github.com/hashicorp/hcl/v2@v2.20.0/structure.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package hcl 5 6 import ( 7 "github.com/zclconf/go-cty/cty" 8 ) 9 10 // File is the top-level node that results from parsing a HCL file. 11 type File struct { 12 Body Body 13 Bytes []byte 14 15 // Nav is used to integrate with the "hcled" editor integration package, 16 // and with diagnostic information formatters. It is not for direct use 17 // by a calling application. 18 Nav interface{} 19 } 20 21 // Block represents a nested block within a Body. 22 type Block struct { 23 Type string 24 Labels []string 25 Body Body 26 27 DefRange Range // Range that can be considered the "definition" for seeking in an editor 28 TypeRange Range // Range for the block type declaration specifically. 29 LabelRanges []Range // Ranges for the label values specifically. 30 } 31 32 // Blocks is a sequence of Block. 33 type Blocks []*Block 34 35 // Attributes is a set of attributes keyed by their names. 36 type Attributes map[string]*Attribute 37 38 // Body is a container for attributes and blocks. It serves as the primary 39 // unit of hierarchical structure within configuration. 40 // 41 // The content of a body cannot be meaningfully interpreted without a schema, 42 // so Body represents the raw body content and has methods that allow the 43 // content to be extracted in terms of a given schema. 44 type Body interface { 45 // Content verifies that the entire body content conforms to the given 46 // schema and then returns it, and/or returns diagnostics. The returned 47 // body content is valid if non-nil, regardless of whether Diagnostics 48 // are provided, but diagnostics should still be eventually shown to 49 // the user. 50 Content(schema *BodySchema) (*BodyContent, Diagnostics) 51 52 // PartialContent is like Content except that it permits the configuration 53 // to contain additional blocks or attributes not specified in the 54 // schema. If any are present, the returned Body is non-nil and contains 55 // the remaining items from the body that were not selected by the schema. 56 PartialContent(schema *BodySchema) (*BodyContent, Body, Diagnostics) 57 58 // JustAttributes attempts to interpret all of the contents of the body 59 // as attributes, allowing for the contents to be accessed without a priori 60 // knowledge of the structure. 61 // 62 // The behavior of this method depends on the body's source language. 63 // Some languages, like JSON, can't distinguish between attributes and 64 // blocks without schema hints, but for languages that _can_ error 65 // diagnostics will be generated if any blocks are present in the body. 66 // 67 // Diagnostics may be produced for other reasons too, such as duplicate 68 // declarations of the same attribute. 69 JustAttributes() (Attributes, Diagnostics) 70 71 // MissingItemRange returns a range that represents where a missing item 72 // might hypothetically be inserted. This is used when producing 73 // diagnostics about missing required attributes or blocks. Not all bodies 74 // will have an obvious single insertion point, so the result here may 75 // be rather arbitrary. 76 MissingItemRange() Range 77 } 78 79 // BodyContent is the result of applying a BodySchema to a Body. 80 type BodyContent struct { 81 Attributes Attributes 82 Blocks Blocks 83 84 MissingItemRange Range 85 } 86 87 // Attribute represents an attribute from within a body. 88 type Attribute struct { 89 Name string 90 Expr Expression 91 92 Range Range 93 NameRange Range 94 } 95 96 // Expression is a literal value or an expression provided in the 97 // configuration, which can be evaluated within a scope to produce a value. 98 type Expression interface { 99 // Value returns the value resulting from evaluating the expression 100 // in the given evaluation context. 101 // 102 // The context may be nil, in which case the expression may contain 103 // only constants and diagnostics will be produced for any non-constant 104 // sub-expressions. (The exact definition of this depends on the source 105 // language.) 106 // 107 // The context may instead be set but have either its Variables or 108 // Functions maps set to nil, in which case only use of these features 109 // will return diagnostics. 110 // 111 // Different diagnostics are provided depending on whether the given 112 // context maps are nil or empty. In the former case, the message 113 // tells the user that variables/functions are not permitted at all, 114 // while in the latter case usage will produce a "not found" error for 115 // the specific symbol in question. 116 Value(ctx *EvalContext) (cty.Value, Diagnostics) 117 118 // Variables returns a list of variables referenced in the receiving 119 // expression. These are expressed as absolute Traversals, so may include 120 // additional information about how the variable is used, such as 121 // attribute lookups, which the calling application can potentially use 122 // to only selectively populate the scope. 123 Variables() []Traversal 124 125 Range() Range 126 StartRange() Range 127 } 128 129 // OfType filters the receiving block sequence by block type name, 130 // returning a new block sequence including only the blocks of the 131 // requested type. 132 func (els Blocks) OfType(typeName string) Blocks { 133 ret := make(Blocks, 0) 134 for _, el := range els { 135 if el.Type == typeName { 136 ret = append(ret, el) 137 } 138 } 139 return ret 140 } 141 142 // ByType transforms the receiving block sequence into a map from type 143 // name to block sequences of only that type. 144 func (els Blocks) ByType() map[string]Blocks { 145 ret := make(map[string]Blocks) 146 for _, el := range els { 147 ty := el.Type 148 if ret[ty] == nil { 149 ret[ty] = make(Blocks, 0, 1) 150 } 151 ret[ty] = append(ret[ty], el) 152 } 153 return ret 154 }