diff options
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/gohcl')
-rw-r--r-- | vendor/github.com/hashicorp/hcl2/gohcl/decode.go | 304 | ||||
-rw-r--r-- | vendor/github.com/hashicorp/hcl2/gohcl/doc.go | 49 | ||||
-rw-r--r-- | vendor/github.com/hashicorp/hcl2/gohcl/schema.go | 174 | ||||
-rw-r--r-- | vendor/github.com/hashicorp/hcl2/gohcl/types.go | 16 |
4 files changed, 543 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/gohcl/decode.go b/vendor/github.com/hashicorp/hcl2/gohcl/decode.go new file mode 100644 index 0000000..3a149a8 --- /dev/null +++ b/vendor/github.com/hashicorp/hcl2/gohcl/decode.go | |||
@@ -0,0 +1,304 @@ | |||
1 | package gohcl | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "reflect" | ||
6 | |||
7 | "github.com/zclconf/go-cty/cty" | ||
8 | |||
9 | "github.com/hashicorp/hcl2/hcl" | ||
10 | "github.com/zclconf/go-cty/cty/convert" | ||
11 | "github.com/zclconf/go-cty/cty/gocty" | ||
12 | ) | ||
13 | |||
14 | // DecodeBody extracts the configuration within the given body into the given | ||
15 | // value. This value must be a non-nil pointer to either a struct or | ||
16 | // a map, where in the former case the configuration will be decoded using | ||
17 | // struct tags and in the latter case only attributes are allowed and their | ||
18 | // values are decoded into the map. | ||
19 | // | ||
20 | // The given EvalContext is used to resolve any variables or functions in | ||
21 | // expressions encountered while decoding. This may be nil to require only | ||
22 | // constant values, for simple applications that do not support variables or | ||
23 | // functions. | ||
24 | // | ||
25 | // The returned diagnostics should be inspected with its HasErrors method to | ||
26 | // determine if the populated value is valid and complete. If error diagnostics | ||
27 | // are returned then the given value may have been partially-populated but | ||
28 | // may still be accessed by a careful caller for static analysis and editor | ||
29 | // integration use-cases. | ||
30 | func DecodeBody(body hcl.Body, ctx *hcl.EvalContext, val interface{}) hcl.Diagnostics { | ||
31 | rv := reflect.ValueOf(val) | ||
32 | if rv.Kind() != reflect.Ptr { | ||
33 | panic(fmt.Sprintf("target value must be a pointer, not %s", rv.Type().String())) | ||
34 | } | ||
35 | |||
36 | return decodeBodyToValue(body, ctx, rv.Elem()) | ||
37 | } | ||
38 | |||
39 | func decodeBodyToValue(body hcl.Body, ctx *hcl.EvalContext, val reflect.Value) hcl.Diagnostics { | ||
40 | et := val.Type() | ||
41 | switch et.Kind() { | ||
42 | case reflect.Struct: | ||
43 | return decodeBodyToStruct(body, ctx, val) | ||
44 | case reflect.Map: | ||
45 | return decodeBodyToMap(body, ctx, val) | ||
46 | default: | ||
47 | panic(fmt.Sprintf("target value must be pointer to struct or map, not %s", et.String())) | ||
48 | } | ||
49 | } | ||
50 | |||
51 | func decodeBodyToStruct(body hcl.Body, ctx *hcl.EvalContext, val reflect.Value) hcl.Diagnostics { | ||
52 | schema, partial := ImpliedBodySchema(val.Interface()) | ||
53 | |||
54 | var content *hcl.BodyContent | ||
55 | var leftovers hcl.Body | ||
56 | var diags hcl.Diagnostics | ||
57 | if partial { | ||
58 | content, leftovers, diags = body.PartialContent(schema) | ||
59 | } else { | ||
60 | content, diags = body.Content(schema) | ||
61 | } | ||
62 | if content == nil { | ||
63 | return diags | ||
64 | } | ||
65 | |||
66 | tags := getFieldTags(val.Type()) | ||
67 | |||
68 | if tags.Remain != nil { | ||
69 | fieldIdx := *tags.Remain | ||
70 | field := val.Type().Field(fieldIdx) | ||
71 | fieldV := val.Field(fieldIdx) | ||
72 | switch { | ||
73 | case bodyType.AssignableTo(field.Type): | ||
74 | fieldV.Set(reflect.ValueOf(leftovers)) | ||
75 | case attrsType.AssignableTo(field.Type): | ||
76 | attrs, attrsDiags := leftovers.JustAttributes() | ||
77 | if len(attrsDiags) > 0 { | ||
78 | diags = append(diags, attrsDiags...) | ||
79 | } | ||
80 | fieldV.Set(reflect.ValueOf(attrs)) | ||
81 | default: | ||
82 | diags = append(diags, decodeBodyToValue(leftovers, ctx, fieldV)...) | ||
83 | } | ||
84 | } | ||
85 | |||
86 | for name, fieldIdx := range tags.Attributes { | ||
87 | attr := content.Attributes[name] | ||
88 | field := val.Type().Field(fieldIdx) | ||
89 | fieldV := val.Field(fieldIdx) | ||
90 | |||
91 | if attr == nil { | ||
92 | if !exprType.AssignableTo(field.Type) { | ||
93 | continue | ||
94 | } | ||
95 | |||
96 | // As a special case, if the target is of type hcl.Expression then | ||
97 | // we'll assign an actual expression that evalues to a cty null, | ||
98 | // so the caller can deal with it within the cty realm rather | ||
99 | // than within the Go realm. | ||
100 | synthExpr := hcl.StaticExpr(cty.NullVal(cty.DynamicPseudoType), body.MissingItemRange()) | ||
101 | fieldV.Set(reflect.ValueOf(synthExpr)) | ||
102 | continue | ||
103 | } | ||
104 | |||
105 | switch { | ||
106 | case attrType.AssignableTo(field.Type): | ||
107 | fieldV.Set(reflect.ValueOf(attr)) | ||
108 | case exprType.AssignableTo(field.Type): | ||
109 | fieldV.Set(reflect.ValueOf(attr.Expr)) | ||
110 | default: | ||
111 | diags = append(diags, DecodeExpression( | ||
112 | attr.Expr, ctx, fieldV.Addr().Interface(), | ||
113 | )...) | ||
114 | } | ||
115 | } | ||
116 | |||
117 | blocksByType := content.Blocks.ByType() | ||
118 | |||
119 | for typeName, fieldIdx := range tags.Blocks { | ||
120 | blocks := blocksByType[typeName] | ||
121 | field := val.Type().Field(fieldIdx) | ||
122 | |||
123 | ty := field.Type | ||
124 | isSlice := false | ||
125 | isPtr := false | ||
126 | if ty.Kind() == reflect.Slice { | ||
127 | isSlice = true | ||
128 | ty = ty.Elem() | ||
129 | } | ||
130 | if ty.Kind() == reflect.Ptr { | ||
131 | isPtr = true | ||
132 | ty = ty.Elem() | ||
133 | } | ||
134 | |||
135 | if len(blocks) > 1 && !isSlice { | ||
136 | diags = append(diags, &hcl.Diagnostic{ | ||
137 | Severity: hcl.DiagError, | ||
138 | Summary: fmt.Sprintf("Duplicate %s block", typeName), | ||
139 | Detail: fmt.Sprintf( | ||
140 | "Only one %s block is allowed. Another was defined at %s.", | ||
141 | typeName, blocks[0].DefRange.String(), | ||
142 | ), | ||
143 | Subject: &blocks[1].DefRange, | ||
144 | }) | ||
145 | continue | ||
146 | } | ||
147 | |||
148 | if len(blocks) == 0 { | ||
149 | if isSlice || isPtr { | ||
150 | val.Field(fieldIdx).Set(reflect.Zero(field.Type)) | ||
151 | } else { | ||
152 | diags = append(diags, &hcl.Diagnostic{ | ||
153 | Severity: hcl.DiagError, | ||
154 | Summary: fmt.Sprintf("Missing %s block", typeName), | ||
155 | Detail: fmt.Sprintf("A %s block is required.", typeName), | ||
156 | Subject: body.MissingItemRange().Ptr(), | ||
157 | }) | ||
158 | } | ||
159 | continue | ||
160 | } | ||
161 | |||
162 | switch { | ||
163 | |||
164 | case isSlice: | ||
165 | elemType := ty | ||
166 | if isPtr { | ||
167 | elemType = reflect.PtrTo(ty) | ||
168 | } | ||
169 | sli := reflect.MakeSlice(reflect.SliceOf(elemType), len(blocks), len(blocks)) | ||
170 | |||
171 | for i, block := range blocks { | ||
172 | if isPtr { | ||
173 | v := reflect.New(ty) | ||
174 | diags = append(diags, decodeBlockToValue(block, ctx, v.Elem())...) | ||
175 | sli.Index(i).Set(v) | ||
176 | } else { | ||
177 | diags = append(diags, decodeBlockToValue(block, ctx, sli.Index(i))...) | ||
178 | } | ||
179 | } | ||
180 | |||
181 | val.Field(fieldIdx).Set(sli) | ||
182 | |||
183 | default: | ||
184 | block := blocks[0] | ||
185 | if isPtr { | ||
186 | v := reflect.New(ty) | ||
187 | diags = append(diags, decodeBlockToValue(block, ctx, v.Elem())...) | ||
188 | val.Field(fieldIdx).Set(v) | ||
189 | } else { | ||
190 | diags = append(diags, decodeBlockToValue(block, ctx, val.Field(fieldIdx))...) | ||
191 | } | ||
192 | |||
193 | } | ||
194 | |||
195 | } | ||
196 | |||
197 | return diags | ||
198 | } | ||
199 | |||
200 | func decodeBodyToMap(body hcl.Body, ctx *hcl.EvalContext, v reflect.Value) hcl.Diagnostics { | ||
201 | attrs, diags := body.JustAttributes() | ||
202 | if attrs == nil { | ||
203 | return diags | ||
204 | } | ||
205 | |||
206 | mv := reflect.MakeMap(v.Type()) | ||
207 | |||
208 | for k, attr := range attrs { | ||
209 | switch { | ||
210 | case attrType.AssignableTo(v.Type().Elem()): | ||
211 | mv.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(attr)) | ||
212 | case exprType.AssignableTo(v.Type().Elem()): | ||
213 | mv.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(attr.Expr)) | ||
214 | default: | ||
215 | ev := reflect.New(v.Type().Elem()) | ||
216 | diags = append(diags, DecodeExpression(attr.Expr, ctx, ev.Interface())...) | ||
217 | mv.SetMapIndex(reflect.ValueOf(k), ev.Elem()) | ||
218 | } | ||
219 | } | ||
220 | |||
221 | v.Set(mv) | ||
222 | |||
223 | return diags | ||
224 | } | ||
225 | |||
226 | func decodeBlockToValue(block *hcl.Block, ctx *hcl.EvalContext, v reflect.Value) hcl.Diagnostics { | ||
227 | var diags hcl.Diagnostics | ||
228 | |||
229 | ty := v.Type() | ||
230 | |||
231 | switch { | ||
232 | case blockType.AssignableTo(ty): | ||
233 | v.Elem().Set(reflect.ValueOf(block)) | ||
234 | case bodyType.AssignableTo(ty): | ||
235 | v.Elem().Set(reflect.ValueOf(block.Body)) | ||
236 | case attrsType.AssignableTo(ty): | ||
237 | attrs, attrsDiags := block.Body.JustAttributes() | ||
238 | if len(attrsDiags) > 0 { | ||
239 | diags = append(diags, attrsDiags...) | ||
240 | } | ||
241 | v.Elem().Set(reflect.ValueOf(attrs)) | ||
242 | default: | ||
243 | diags = append(diags, decodeBodyToValue(block.Body, ctx, v)...) | ||
244 | |||
245 | if len(block.Labels) > 0 { | ||
246 | blockTags := getFieldTags(ty) | ||
247 | for li, lv := range block.Labels { | ||
248 | lfieldIdx := blockTags.Labels[li].FieldIndex | ||
249 | v.Field(lfieldIdx).Set(reflect.ValueOf(lv)) | ||
250 | } | ||
251 | } | ||
252 | |||
253 | } | ||
254 | |||
255 | return diags | ||
256 | } | ||
257 | |||
258 | // DecodeExpression extracts the value of the given expression into the given | ||
259 | // value. This value must be something that gocty is able to decode into, | ||
260 | // since the final decoding is delegated to that package. | ||
261 | // | ||
262 | // The given EvalContext is used to resolve any variables or functions in | ||
263 | // expressions encountered while decoding. This may be nil to require only | ||
264 | // constant values, for simple applications that do not support variables or | ||
265 | // functions. | ||
266 | // | ||
267 | // The returned diagnostics should be inspected with its HasErrors method to | ||
268 | // determine if the populated value is valid and complete. If error diagnostics | ||
269 | // are returned then the given value may have been partially-populated but | ||
270 | // may still be accessed by a careful caller for static analysis and editor | ||
271 | // integration use-cases. | ||
272 | func DecodeExpression(expr hcl.Expression, ctx *hcl.EvalContext, val interface{}) hcl.Diagnostics { | ||
273 | srcVal, diags := expr.Value(ctx) | ||
274 | |||
275 | convTy, err := gocty.ImpliedType(val) | ||
276 | if err != nil { | ||
277 | panic(fmt.Sprintf("unsuitable DecodeExpression target: %s", err)) | ||
278 | } | ||
279 | |||
280 | srcVal, err = convert.Convert(srcVal, convTy) | ||
281 | if err != nil { | ||
282 | diags = append(diags, &hcl.Diagnostic{ | ||
283 | Severity: hcl.DiagError, | ||
284 | Summary: "Unsuitable value type", | ||
285 | Detail: fmt.Sprintf("Unsuitable value: %s", err.Error()), | ||
286 | Subject: expr.StartRange().Ptr(), | ||
287 | Context: expr.Range().Ptr(), | ||
288 | }) | ||
289 | return diags | ||
290 | } | ||
291 | |||
292 | err = gocty.FromCtyValue(srcVal, val) | ||
293 | if err != nil { | ||
294 | diags = append(diags, &hcl.Diagnostic{ | ||
295 | Severity: hcl.DiagError, | ||
296 | Summary: "Unsuitable value type", | ||
297 | Detail: fmt.Sprintf("Unsuitable value: %s", err.Error()), | ||
298 | Subject: expr.StartRange().Ptr(), | ||
299 | Context: expr.Range().Ptr(), | ||
300 | }) | ||
301 | } | ||
302 | |||
303 | return diags | ||
304 | } | ||
diff --git a/vendor/github.com/hashicorp/hcl2/gohcl/doc.go b/vendor/github.com/hashicorp/hcl2/gohcl/doc.go new file mode 100644 index 0000000..8500214 --- /dev/null +++ b/vendor/github.com/hashicorp/hcl2/gohcl/doc.go | |||
@@ -0,0 +1,49 @@ | |||
1 | // Package gohcl allows decoding HCL configurations into Go data structures. | ||
2 | // | ||
3 | // It provides a convenient and concise way of describing the schema for | ||
4 | // configuration and then accessing the resulting data via native Go | ||
5 | // types. | ||
6 | // | ||
7 | // A struct field tag scheme is used, similar to other decoding and | ||
8 | // unmarshalling libraries. The tags are formatted as in the following example: | ||
9 | // | ||
10 | // ThingType string `hcl:"thing_type,attr"` | ||
11 | // | ||
12 | // Within each tag there are two comma-separated tokens. The first is the | ||
13 | // name of the corresponding construct in configuration, while the second | ||
14 | // is a keyword giving the kind of construct expected. The following | ||
15 | // kind keywords are supported: | ||
16 | // | ||
17 | // attr (the default) indicates that the value is to be populated from an attribute | ||
18 | // block indicates that the value is to populated from a block | ||
19 | // label indicates that the value is to populated from a block label | ||
20 | // remain indicates that the value is to be populated from the remaining body after populating other fields | ||
21 | // | ||
22 | // "attr" fields may either be of type *hcl.Expression, in which case the raw | ||
23 | // expression is assigned, or of any type accepted by gocty, in which case | ||
24 | // gocty will be used to assign the value to a native Go type. | ||
25 | // | ||
26 | // "block" fields may be of type *hcl.Block or hcl.Body, in which case the | ||
27 | // corresponding raw value is assigned, or may be a struct that recursively | ||
28 | // uses the same tags. Block fields may also be slices of any of these types, | ||
29 | // in which case multiple blocks of the corresponding type are decoded into | ||
30 | // the slice. | ||
31 | // | ||
32 | // "label" fields are considered only in a struct used as the type of a field | ||
33 | // marked as "block", and are used sequentially to capture the labels of | ||
34 | // the blocks being decoded. In this case, the name token is used only as | ||
35 | // an identifier for the label in diagnostic messages. | ||
36 | // | ||
37 | // "remain" can be placed on a single field that may be either of type | ||
38 | // hcl.Body or hcl.Attributes, in which case any remaining body content is | ||
39 | // placed into this field for delayed processing. If no "remain" field is | ||
40 | // present then any attributes or blocks not matched by another valid tag | ||
41 | // will cause an error diagnostic. | ||
42 | // | ||
43 | // Broadly-speaking this package deals with two types of error. The first is | ||
44 | // errors in the configuration itself, which are returned as diagnostics | ||
45 | // written with the configuration author as the target audience. The second | ||
46 | // is bugs in the calling program, such as invalid struct tags, which are | ||
47 | // surfaced via panics since there can be no useful runtime handling of such | ||
48 | // errors and they should certainly not be returned to the user as diagnostics. | ||
49 | package gohcl | ||
diff --git a/vendor/github.com/hashicorp/hcl2/gohcl/schema.go b/vendor/github.com/hashicorp/hcl2/gohcl/schema.go new file mode 100644 index 0000000..88164cb --- /dev/null +++ b/vendor/github.com/hashicorp/hcl2/gohcl/schema.go | |||
@@ -0,0 +1,174 @@ | |||
1 | package gohcl | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "reflect" | ||
6 | "sort" | ||
7 | "strings" | ||
8 | |||
9 | "github.com/hashicorp/hcl2/hcl" | ||
10 | ) | ||
11 | |||
12 | // ImpliedBodySchema produces a hcl.BodySchema derived from the type of the | ||
13 | // given value, which must be a struct value or a pointer to one. If an | ||
14 | // inappropriate value is passed, this function will panic. | ||
15 | // | ||
16 | // The second return argument indicates whether the given struct includes | ||
17 | // a "remain" field, and thus the returned schema is non-exhaustive. | ||
18 | // | ||
19 | // This uses the tags on the fields of the struct to discover how each | ||
20 | // field's value should be expressed within configuration. If an invalid | ||
21 | // mapping is attempted, this function will panic. | ||
22 | func ImpliedBodySchema(val interface{}) (schema *hcl.BodySchema, partial bool) { | ||
23 | ty := reflect.TypeOf(val) | ||
24 | |||
25 | if ty.Kind() == reflect.Ptr { | ||
26 | ty = ty.Elem() | ||
27 | } | ||
28 | |||
29 | if ty.Kind() != reflect.Struct { | ||
30 | panic(fmt.Sprintf("given value must be struct, not %T", val)) | ||
31 | } | ||
32 | |||
33 | var attrSchemas []hcl.AttributeSchema | ||
34 | var blockSchemas []hcl.BlockHeaderSchema | ||
35 | |||
36 | tags := getFieldTags(ty) | ||
37 | |||
38 | attrNames := make([]string, 0, len(tags.Attributes)) | ||
39 | for n := range tags.Attributes { | ||
40 | attrNames = append(attrNames, n) | ||
41 | } | ||
42 | sort.Strings(attrNames) | ||
43 | for _, n := range attrNames { | ||
44 | idx := tags.Attributes[n] | ||
45 | optional := tags.Optional[n] | ||
46 | field := ty.Field(idx) | ||
47 | |||
48 | var required bool | ||
49 | |||
50 | switch { | ||
51 | case field.Type.AssignableTo(exprType): | ||
52 | // If we're decoding to hcl.Expression then absense can be | ||
53 | // indicated via a null value, so we don't specify that | ||
54 | // the field is required during decoding. | ||
55 | required = false | ||
56 | case field.Type.Kind() != reflect.Ptr && !optional: | ||
57 | required = true | ||
58 | default: | ||
59 | required = false | ||
60 | } | ||
61 | |||
62 | attrSchemas = append(attrSchemas, hcl.AttributeSchema{ | ||
63 | Name: n, | ||
64 | Required: required, | ||
65 | }) | ||
66 | } | ||
67 | |||
68 | blockNames := make([]string, 0, len(tags.Blocks)) | ||
69 | for n := range tags.Blocks { | ||
70 | blockNames = append(blockNames, n) | ||
71 | } | ||
72 | sort.Strings(blockNames) | ||
73 | for _, n := range blockNames { | ||
74 | idx := tags.Blocks[n] | ||
75 | field := ty.Field(idx) | ||
76 | fty := field.Type | ||
77 | if fty.Kind() == reflect.Slice { | ||
78 | fty = fty.Elem() | ||
79 | } | ||
80 | if fty.Kind() == reflect.Ptr { | ||
81 | fty = fty.Elem() | ||
82 | } | ||
83 | if fty.Kind() != reflect.Struct { | ||
84 | panic(fmt.Sprintf( | ||
85 | "hcl 'block' tag kind cannot be applied to %s field %s: struct required", field.Type.String(), field.Name, | ||
86 | )) | ||
87 | } | ||
88 | ftags := getFieldTags(fty) | ||
89 | var labelNames []string | ||
90 | if len(ftags.Labels) > 0 { | ||
91 | labelNames = make([]string, len(ftags.Labels)) | ||
92 | for i, l := range ftags.Labels { | ||
93 | labelNames[i] = l.Name | ||
94 | } | ||
95 | } | ||
96 | |||
97 | blockSchemas = append(blockSchemas, hcl.BlockHeaderSchema{ | ||
98 | Type: n, | ||
99 | LabelNames: labelNames, | ||
100 | }) | ||
101 | } | ||
102 | |||
103 | partial = tags.Remain != nil | ||
104 | schema = &hcl.BodySchema{ | ||
105 | Attributes: attrSchemas, | ||
106 | Blocks: blockSchemas, | ||
107 | } | ||
108 | return schema, partial | ||
109 | } | ||
110 | |||
111 | type fieldTags struct { | ||
112 | Attributes map[string]int | ||
113 | Blocks map[string]int | ||
114 | Labels []labelField | ||
115 | Remain *int | ||
116 | Optional map[string]bool | ||
117 | } | ||
118 | |||
119 | type labelField struct { | ||
120 | FieldIndex int | ||
121 | Name string | ||
122 | } | ||
123 | |||
124 | func getFieldTags(ty reflect.Type) *fieldTags { | ||
125 | ret := &fieldTags{ | ||
126 | Attributes: map[string]int{}, | ||
127 | Blocks: map[string]int{}, | ||
128 | Optional: map[string]bool{}, | ||
129 | } | ||
130 | |||
131 | ct := ty.NumField() | ||
132 | for i := 0; i < ct; i++ { | ||
133 | field := ty.Field(i) | ||
134 | tag := field.Tag.Get("hcl") | ||
135 | if tag == "" { | ||
136 | continue | ||
137 | } | ||
138 | |||
139 | comma := strings.Index(tag, ",") | ||
140 | var name, kind string | ||
141 | if comma != -1 { | ||
142 | name = tag[:comma] | ||
143 | kind = tag[comma+1:] | ||
144 | } else { | ||
145 | name = tag | ||
146 | kind = "attr" | ||
147 | } | ||
148 | |||
149 | switch kind { | ||
150 | case "attr": | ||
151 | ret.Attributes[name] = i | ||
152 | case "block": | ||
153 | ret.Blocks[name] = i | ||
154 | case "label": | ||
155 | ret.Labels = append(ret.Labels, labelField{ | ||
156 | FieldIndex: i, | ||
157 | Name: name, | ||
158 | }) | ||
159 | case "remain": | ||
160 | if ret.Remain != nil { | ||
161 | panic("only one 'remain' tag is permitted") | ||
162 | } | ||
163 | idx := i // copy, because this loop will continue assigning to i | ||
164 | ret.Remain = &idx | ||
165 | case "optional": | ||
166 | ret.Attributes[name] = i | ||
167 | ret.Optional[name] = true | ||
168 | default: | ||
169 | panic(fmt.Sprintf("invalid hcl field tag kind %q on %s %q", kind, field.Type.String(), field.Name)) | ||
170 | } | ||
171 | } | ||
172 | |||
173 | return ret | ||
174 | } | ||
diff --git a/vendor/github.com/hashicorp/hcl2/gohcl/types.go b/vendor/github.com/hashicorp/hcl2/gohcl/types.go new file mode 100644 index 0000000..a94f275 --- /dev/null +++ b/vendor/github.com/hashicorp/hcl2/gohcl/types.go | |||
@@ -0,0 +1,16 @@ | |||
1 | package gohcl | ||
2 | |||
3 | import ( | ||
4 | "reflect" | ||
5 | |||
6 | "github.com/hashicorp/hcl2/hcl" | ||
7 | ) | ||
8 | |||
9 | var victimExpr hcl.Expression | ||
10 | var victimBody hcl.Body | ||
11 | |||
12 | var exprType = reflect.TypeOf(&victimExpr).Elem() | ||
13 | var bodyType = reflect.TypeOf(&victimBody).Elem() | ||
14 | var blockType = reflect.TypeOf((*hcl.Block)(nil)) | ||
15 | var attrType = reflect.TypeOf((*hcl.Attribute)(nil)) | ||
16 | var attrsType = reflect.TypeOf(hcl.Attributes(nil)) | ||