github.com/hashicorp/hcl/v2@v2.20.0/json/spec.md (about)

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