aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/hcl2/hcl/json/spec.md
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/hcl/json/spec.md')
-rw-r--r--vendor/github.com/hashicorp/hcl2/hcl/json/spec.md405
1 files changed, 405 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/hcl/json/spec.md b/vendor/github.com/hashicorp/hcl2/hcl/json/spec.md
new file mode 100644
index 0000000..9b33c7f
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl2/hcl/json/spec.md
@@ -0,0 +1,405 @@
1# HCL JSON Syntax Specification
2
3This is the specification for the JSON serialization for hcl. HCL is a system
4for defining configuration languages for applications. The HCL information
5model is designed to support multiple concrete syntaxes for configuration,
6and this JSON-based format complements [the native syntax](../hclsyntax/spec.md)
7by being easy to machine-generate, whereas the native syntax is oriented
8towards human authoring and maintenence.
9
10This syntax is defined in terms of JSON as defined in
11[RFC7159](https://tools.ietf.org/html/rfc7159). As such it inherits the JSON
12grammar as-is, and merely defines a specific methodology for interpreting
13JSON constructs into HCL structural elements and expressions.
14
15This mapping is defined such that valid JSON-serialized HCL input can be
16_produced_ using standard JSON implementations in various programming languages.
17_Parsing_ such JSON has some additional constraints not beyond what is normally
18supported by JSON parsers, so a specialized parser may be required that
19is able to:
20
21* Preserve the relative ordering of properties defined in an object.
22* Preserve multiple definitions of the same property name.
23* Preserve numeric values to the precision required by the number type
24 in [the HCL syntax-agnostic information model](../spec.md).
25* Retain source location information for parsed tokens/constructs in order
26 to produce good error messages.
27
28## Structural Elements
29
30[The HCL syntax-agnostic information model](../spec.md) defines a _body_ as an
31abstract container for attribute definitions and child blocks. A body is
32represented in JSON as either a single JSON object or a JSON array of objects.
33
34Body processing is in terms of JSON object properties, visited in the order
35they appear in the input. Where a body is represented by a single JSON object,
36the properties of that object are visited in order. Where a body is
37represented by a JSON array, each of its elements are visited in order and
38each element has its properties visited in order. If any element of the array
39is not a JSON object then the input is erroneous.
40
41When a body is being processed in the _dynamic attributes_ mode, the allowance
42of a JSON array in the previous paragraph does not apply and instead a single
43JSON object is always required.
44
45As defined in the language-agnostic model, body processing is in terms
46of a schema which provides context for interpreting the body's content. For
47JSON bodies, the schema is crucial to allow differentiation of attribute
48definitions and block definitions, both of which are represented via object
49properties.
50
51The special property name `"//"`, when used in an object representing a HCL
52body, is parsed and ignored. A property with this name can be used to
53include human-readable comments. (This special property name is _not_
54processed in this way for any _other_ HCL constructs that are represented as
55JSON objects.)
56
57### Attributes
58
59Where the given schema describes an attribute with a given name, the object
60property with the matching name — if present — serves as the attribute's
61definition.
62
63When a body is being processed in the _dynamic attributes_ mode, each object
64property serves as an attribute definition for the attribute whose name
65matches the property name.
66
67The value of an attribute definition property is interpreted as an _expression_,
68as described in a later section.
69
70Given a schema that calls for an attribute named "foo", a JSON object like
71the following provides a definition for that attribute:
72
73```json
74{
75 "foo": "bar baz"
76}
77```
78
79### Blocks
80
81Where the given schema describes a block with a given type name, each object
82property with the matching name serves as a definition of zero or more blocks
83of that type.
84
85Processing of child blocks is in terms of nested JSON objects and arrays.
86If the schema defines one or more _labels_ for the block type, a nested JSON
87object or JSON array of objects is required for each labelling level. These
88are flattened to a single ordered sequence of object properties using the
89same algorithm as for body content as defined above. Each object property
90serves as a label value at the corresponding level.
91
92After any labelling levels, the next nested value is either a JSON object
93representing a single block body, or a JSON array of JSON objects that each
94represent a single block body. Use of an array accommodates the definition
95of multiple blocks that have identical type and labels.
96
97Given a schema that calls for a block type named "foo" with no labels, the
98following JSON objects are all valid definitions of zero or more blocks of this
99type:
100
101```json
102{
103 "foo": {
104 "child_attr": "baz"
105 }
106}
107```
108
109```json
110{
111 "foo": [
112 {
113 "child_attr": "baz"
114 },
115 {
116 "child_attr": "boz"
117 }
118 ]
119}
120```
121```json
122{
123 "foo": []
124}
125```
126
127The first of these defines a single child block of type "foo". The second
128defines _two_ such blocks. The final example shows a degenerate definition
129of zero blocks, though generators should prefer to omit the property entirely
130in this scenario.
131
132Given a schema that calls for a block type named "foo" with _two_ labels, the
133extra label levels must be represented as objects or arrays of objects as in
134the following examples:
135
136```json
137{
138 "foo": {
139 "bar": {
140 "baz": {
141 "child_attr": "baz"
142 },
143 "boz": {
144 "child_attr": "baz"
145 }
146 },
147 "boz": {
148 "baz": {
149 "child_attr": "baz"
150 },
151 }
152 }
153}
154```
155
156```json
157{
158 "foo": {
159 "bar": {
160 "baz": {
161 "child_attr": "baz"
162 },
163 "boz": {
164 "child_attr": "baz"
165 }
166 },
167 "boz": {
168 "baz": [
169 {
170 "child_attr": "baz"
171 },
172 {
173 "child_attr": "boz"
174 }
175 ]
176 }
177 }
178}
179```
180
181```json
182{
183 "foo": [
184 {
185 "bar": {
186 "baz": {
187 "child_attr": "baz"
188 },
189 "boz": {
190 "child_attr": "baz"
191 }
192 },
193 },
194 {
195 "bar": {
196 "baz": [
197 {
198 "child_attr": "baz"
199 },
200 {
201 "child_attr": "boz"
202 }
203 ]
204 }
205 }
206 ]
207}
208```
209
210```json
211{
212 "foo": {
213 "bar": {
214 "baz": {
215 "child_attr": "baz"
216 },
217 "boz": {
218 "child_attr": "baz"
219 }
220 },
221 "bar": {
222 "baz": [
223 {
224 "child_attr": "baz"
225 },
226 {
227 "child_attr": "boz"
228 }
229 ]
230 }
231 }
232}
233```
234
235Arrays can be introduced at either the label definition or block body
236definition levels to define multiple definitions of the same block type
237or labels while preserving order.
238
239A JSON HCL parser _must_ support duplicate definitions of the same property
240name within a single object, preserving all of them and the relative ordering
241between them. The array-based forms are also required so that JSON HCL
242configurations can be produced with JSON producing libraries that are not
243able to preserve property definition order and multiple definitions of
244the same property.
245
246## Expressions
247
248JSON lacks a native expression syntax, so the HCL JSON syntax instead defines
249a mapping for each of the JSON value types, including a special mapping for
250strings that allows optional use of arbitrary expressions.
251
252### Objects
253
254When interpreted as an expression, a JSON object represents a value of a HCL
255object type.
256
257Each property of the JSON object represents an attribute of the HCL object type.
258The property name string given in the JSON input is interpreted as a string
259expression as described below, and its result is converted to string as defined
260by the syntax-agnostic information model. If such a conversion is not possible,
261an error is produced and evaluation fails.
262
263An instance of the constructed object type is then created, whose values
264are interpreted by again recursively applying the mapping rules defined in
265this section to each of the property values.
266
267If any evaluated property name strings produce null values, an error is
268produced and evaluation fails. If any produce _unknown_ values, the _entire
269object's_ result is an unknown value of the dynamic pseudo-type, signalling
270that the type of the object cannot be determined.
271
272It is an error to define the same property name multiple times within a single
273JSON object interpreted as an expression. In full expression mode, this
274constraint applies to the name expression results after conversion to string,
275rather than the raw string that may contain interpolation expressions.
276
277### Arrays
278
279When interpreted as an expression, a JSON array represents a value of a HCL
280tuple type.
281
282Each element of the JSON array represents an element of the HCL tuple type.
283The tuple type is constructed by enumerationg the JSON array elements, creating
284for each an element whose type is the result of recursively applying the
285expression mapping rules. Correspondance is preserved between the array element
286indices and the tuple element indices.
287
288An instance of the constructed tuple type is then created, whose values are
289interpreted by again recursively applying the mapping rules defined in this
290section.
291
292### Numbers
293
294When interpreted as an expression, a JSON number represents a HCL number value.
295
296HCL numbers are arbitrary-precision decimal values, so a JSON HCL parser must
297be able to translate exactly the value given to a number of corresponding
298precision, within the constraints set by the HCL syntax-agnostic information
299model.
300
301In practice, off-the-shelf JSON serializers often do not support customizing the
302processing of numbers, and instead force processing as 32-bit or 64-bit
303floating point values.
304
305A _producer_ of JSON HCL that uses such a serializer can provide numeric values
306as JSON strings where they have precision too great for representation in the
307serializer's chosen numeric type in situations where the result will be
308converted to number (using the standard conversion rules) by a calling
309application.
310
311Alternatively, for expressions that are evaluated in full expression mode an
312embedded template interpolation can be used to faithfully represent a number,
313such as `"${1e150}"`, which will then be evaluated by the underlying HCL native
314syntax expression evaluator.
315
316### Boolean Values
317
318The JSON boolean values `true` and `false`, when interpreted as expressions,
319represent the corresponding HCL boolean values.
320
321### The Null Value
322
323The JSON value `null`, when interpreted as an expression, represents a
324HCL null value of the dynamic pseudo-type.
325
326### Strings
327
328When intepreted as an expression, a JSON string may be interpreted in one of
329two ways depending on the evaluation mode.
330
331If evaluating in literal-only mode (as defined by the syntax-agnostic
332information model) the literal string is intepreted directly as a HCL string
333value, by directly using the exact sequence of unicode characters represented.
334Template interpolations and directives MUST NOT be processed in this mode,
335allowing any characters that appear as introduction sequences to pass through
336literally:
337
338```json
339"Hello world! Template sequences like ${ are not intepreted here."
340```
341
342When evaluating in full expression mode (again, as defined by the syntax-
343agnostic information model) the literal string is instead interpreted as a
344_standalone template_ in the HCL Native Syntax. The expression evaluation
345result is then the direct result of evaluating that template with the current
346variable scope and function table.
347
348```json
349"Hello, ${name}! Template sequences are interpreted in full expression mode."
350```
351
352In particular the _Template Interpolation Unwrapping_ requirement from the
353HCL native syntax specification must be implemented, allowing the use of
354single-interpolation templates to represent expressions that would not
355otherwise be representable in JSON, such as the following example where
356the result must be a number, rather than a string representation of a number:
357
358```json
359"${ a + b }"
360```
361
362## Static Analysis
363
364The HCL static analysis operations are implemented for JSON values that
365represent expressions, as described in the following sections.
366
367Due to the limited expressive power of the JSON syntax alone, use of these
368static analyses functions rather than normal expression evaluation is used
369as additional context for how a JSON value is to be interpreted, which means
370that static analyses can result in a different interpretation of a given
371expression than normal evaluation.
372
373### Static List
374
375An expression interpreted as a static list must be a JSON array. Each of the
376values in the array is interpreted as an expression and returned.
377
378### Static Map
379
380An expression interpreted as a static map must be a JSON object. Each of the
381key/value pairs in the object is presented as a pair of expressions. Since
382object property names are always strings, evaluating the key expression with
383a non-`nil` evaluation context will evaluate any template sequences given
384in the property name.
385
386### Static Call
387
388An expression interpreted as a static call must be a string. The content of
389the string is interpreted as a native syntax expression (not a _template_,
390unlike normal evaluation) and then the static call analysis is delegated to
391that expression.
392
393If the original expression is not a string or its contents cannot be parsed
394as a native syntax expression then static call analysis is not supported.
395
396### Static Traversal
397
398An expression interpreted as a static traversal must be a string. The content
399of the string is interpreted as a native syntax expression (not a _template_,
400unlike normal evaluation) and then static traversal analysis is delegated
401to that expression.
402
403If the original expression is not a string or its contents cannot be parsed
404as a native syntax expression then static call analysis is not supported.
405