]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/hcl/decoder.go
Initial transfer of provider code
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / hcl / decoder.go
1 package hcl
2
3 import (
4 "errors"
5 "fmt"
6 "reflect"
7 "sort"
8 "strconv"
9 "strings"
10
11 "github.com/hashicorp/hcl/hcl/ast"
12 "github.com/hashicorp/hcl/hcl/parser"
13 "github.com/hashicorp/hcl/hcl/token"
14 )
15
16 // This is the tag to use with structures to have settings for HCL
17 const tagName = "hcl"
18
19 var (
20 // nodeType holds a reference to the type of ast.Node
21 nodeType reflect.Type = findNodeType()
22 )
23
24 // Unmarshal accepts a byte slice as input and writes the
25 // data to the value pointed to by v.
26 func Unmarshal(bs []byte, v interface{}) error {
27 root, err := parse(bs)
28 if err != nil {
29 return err
30 }
31
32 return DecodeObject(v, root)
33 }
34
35 // Decode reads the given input and decodes it into the structure
36 // given by `out`.
37 func Decode(out interface{}, in string) error {
38 obj, err := Parse(in)
39 if err != nil {
40 return err
41 }
42
43 return DecodeObject(out, obj)
44 }
45
46 // DecodeObject is a lower-level version of Decode. It decodes a
47 // raw Object into the given output.
48 func DecodeObject(out interface{}, n ast.Node) error {
49 val := reflect.ValueOf(out)
50 if val.Kind() != reflect.Ptr {
51 return errors.New("result must be a pointer")
52 }
53
54 // If we have the file, we really decode the root node
55 if f, ok := n.(*ast.File); ok {
56 n = f.Node
57 }
58
59 var d decoder
60 return d.decode("root", n, val.Elem())
61 }
62
63 type decoder struct {
64 stack []reflect.Kind
65 }
66
67 func (d *decoder) decode(name string, node ast.Node, result reflect.Value) error {
68 k := result
69
70 // If we have an interface with a valid value, we use that
71 // for the check.
72 if result.Kind() == reflect.Interface {
73 elem := result.Elem()
74 if elem.IsValid() {
75 k = elem
76 }
77 }
78
79 // Push current onto stack unless it is an interface.
80 if k.Kind() != reflect.Interface {
81 d.stack = append(d.stack, k.Kind())
82
83 // Schedule a pop
84 defer func() {
85 d.stack = d.stack[:len(d.stack)-1]
86 }()
87 }
88
89 switch k.Kind() {
90 case reflect.Bool:
91 return d.decodeBool(name, node, result)
92 case reflect.Float64:
93 return d.decodeFloat(name, node, result)
94 case reflect.Int, reflect.Int32, reflect.Int64:
95 return d.decodeInt(name, node, result)
96 case reflect.Interface:
97 // When we see an interface, we make our own thing
98 return d.decodeInterface(name, node, result)
99 case reflect.Map:
100 return d.decodeMap(name, node, result)
101 case reflect.Ptr:
102 return d.decodePtr(name, node, result)
103 case reflect.Slice:
104 return d.decodeSlice(name, node, result)
105 case reflect.String:
106 return d.decodeString(name, node, result)
107 case reflect.Struct:
108 return d.decodeStruct(name, node, result)
109 default:
110 return &parser.PosError{
111 Pos: node.Pos(),
112 Err: fmt.Errorf("%s: unknown kind to decode into: %s", name, k.Kind()),
113 }
114 }
115 }
116
117 func (d *decoder) decodeBool(name string, node ast.Node, result reflect.Value) error {
118 switch n := node.(type) {
119 case *ast.LiteralType:
120 if n.Token.Type == token.BOOL {
121 v, err := strconv.ParseBool(n.Token.Text)
122 if err != nil {
123 return err
124 }
125
126 result.Set(reflect.ValueOf(v))
127 return nil
128 }
129 }
130
131 return &parser.PosError{
132 Pos: node.Pos(),
133 Err: fmt.Errorf("%s: unknown type %T", name, node),
134 }
135 }
136
137 func (d *decoder) decodeFloat(name string, node ast.Node, result reflect.Value) error {
138 switch n := node.(type) {
139 case *ast.LiteralType:
140 if n.Token.Type == token.FLOAT {
141 v, err := strconv.ParseFloat(n.Token.Text, 64)
142 if err != nil {
143 return err
144 }
145
146 result.Set(reflect.ValueOf(v))
147 return nil
148 }
149 }
150
151 return &parser.PosError{
152 Pos: node.Pos(),
153 Err: fmt.Errorf("%s: unknown type %T", name, node),
154 }
155 }
156
157 func (d *decoder) decodeInt(name string, node ast.Node, result reflect.Value) error {
158 switch n := node.(type) {
159 case *ast.LiteralType:
160 switch n.Token.Type {
161 case token.NUMBER:
162 v, err := strconv.ParseInt(n.Token.Text, 0, 0)
163 if err != nil {
164 return err
165 }
166
167 if result.Kind() == reflect.Interface {
168 result.Set(reflect.ValueOf(int(v)))
169 } else {
170 result.SetInt(v)
171 }
172 return nil
173 case token.STRING:
174 v, err := strconv.ParseInt(n.Token.Value().(string), 0, 0)
175 if err != nil {
176 return err
177 }
178
179 if result.Kind() == reflect.Interface {
180 result.Set(reflect.ValueOf(int(v)))
181 } else {
182 result.SetInt(v)
183 }
184 return nil
185 }
186 }
187
188 return &parser.PosError{
189 Pos: node.Pos(),
190 Err: fmt.Errorf("%s: unknown type %T", name, node),
191 }
192 }
193
194 func (d *decoder) decodeInterface(name string, node ast.Node, result reflect.Value) error {
195 // When we see an ast.Node, we retain the value to enable deferred decoding.
196 // Very useful in situations where we want to preserve ast.Node information
197 // like Pos
198 if result.Type() == nodeType && result.CanSet() {
199 result.Set(reflect.ValueOf(node))
200 return nil
201 }
202
203 var set reflect.Value
204 redecode := true
205
206 // For testing types, ObjectType should just be treated as a list. We
207 // set this to a temporary var because we want to pass in the real node.
208 testNode := node
209 if ot, ok := node.(*ast.ObjectType); ok {
210 testNode = ot.List
211 }
212
213 switch n := testNode.(type) {
214 case *ast.ObjectList:
215 // If we're at the root or we're directly within a slice, then we
216 // decode objects into map[string]interface{}, otherwise we decode
217 // them into lists.
218 if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice {
219 var temp map[string]interface{}
220 tempVal := reflect.ValueOf(temp)
221 result := reflect.MakeMap(
222 reflect.MapOf(
223 reflect.TypeOf(""),
224 tempVal.Type().Elem()))
225
226 set = result
227 } else {
228 var temp []map[string]interface{}
229 tempVal := reflect.ValueOf(temp)
230 result := reflect.MakeSlice(
231 reflect.SliceOf(tempVal.Type().Elem()), 0, len(n.Items))
232 set = result
233 }
234 case *ast.ObjectType:
235 // If we're at the root or we're directly within a slice, then we
236 // decode objects into map[string]interface{}, otherwise we decode
237 // them into lists.
238 if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice {
239 var temp map[string]interface{}
240 tempVal := reflect.ValueOf(temp)
241 result := reflect.MakeMap(
242 reflect.MapOf(
243 reflect.TypeOf(""),
244 tempVal.Type().Elem()))
245
246 set = result
247 } else {
248 var temp []map[string]interface{}
249 tempVal := reflect.ValueOf(temp)
250 result := reflect.MakeSlice(
251 reflect.SliceOf(tempVal.Type().Elem()), 0, 1)
252 set = result
253 }
254 case *ast.ListType:
255 var temp []interface{}
256 tempVal := reflect.ValueOf(temp)
257 result := reflect.MakeSlice(
258 reflect.SliceOf(tempVal.Type().Elem()), 0, 0)
259 set = result
260 case *ast.LiteralType:
261 switch n.Token.Type {
262 case token.BOOL:
263 var result bool
264 set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
265 case token.FLOAT:
266 var result float64
267 set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
268 case token.NUMBER:
269 var result int
270 set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
271 case token.STRING, token.HEREDOC:
272 set = reflect.Indirect(reflect.New(reflect.TypeOf("")))
273 default:
274 return &parser.PosError{
275 Pos: node.Pos(),
276 Err: fmt.Errorf("%s: cannot decode into interface: %T", name, node),
277 }
278 }
279 default:
280 return fmt.Errorf(
281 "%s: cannot decode into interface: %T",
282 name, node)
283 }
284
285 // Set the result to what its supposed to be, then reset
286 // result so we don't reflect into this method anymore.
287 result.Set(set)
288
289 if redecode {
290 // Revisit the node so that we can use the newly instantiated
291 // thing and populate it.
292 if err := d.decode(name, node, result); err != nil {
293 return err
294 }
295 }
296
297 return nil
298 }
299
300 func (d *decoder) decodeMap(name string, node ast.Node, result reflect.Value) error {
301 if item, ok := node.(*ast.ObjectItem); ok {
302 node = &ast.ObjectList{Items: []*ast.ObjectItem{item}}
303 }
304
305 if ot, ok := node.(*ast.ObjectType); ok {
306 node = ot.List
307 }
308
309 n, ok := node.(*ast.ObjectList)
310 if !ok {
311 return &parser.PosError{
312 Pos: node.Pos(),
313 Err: fmt.Errorf("%s: not an object type for map (%T)", name, node),
314 }
315 }
316
317 // If we have an interface, then we can address the interface,
318 // but not the slice itself, so get the element but set the interface
319 set := result
320 if result.Kind() == reflect.Interface {
321 result = result.Elem()
322 }
323
324 resultType := result.Type()
325 resultElemType := resultType.Elem()
326 resultKeyType := resultType.Key()
327 if resultKeyType.Kind() != reflect.String {
328 return &parser.PosError{
329 Pos: node.Pos(),
330 Err: fmt.Errorf("%s: map must have string keys", name),
331 }
332 }
333
334 // Make a map if it is nil
335 resultMap := result
336 if result.IsNil() {
337 resultMap = reflect.MakeMap(
338 reflect.MapOf(resultKeyType, resultElemType))
339 }
340
341 // Go through each element and decode it.
342 done := make(map[string]struct{})
343 for _, item := range n.Items {
344 if item.Val == nil {
345 continue
346 }
347
348 // github.com/hashicorp/terraform/issue/5740
349 if len(item.Keys) == 0 {
350 return &parser.PosError{
351 Pos: node.Pos(),
352 Err: fmt.Errorf("%s: map must have string keys", name),
353 }
354 }
355
356 // Get the key we're dealing with, which is the first item
357 keyStr := item.Keys[0].Token.Value().(string)
358
359 // If we've already processed this key, then ignore it
360 if _, ok := done[keyStr]; ok {
361 continue
362 }
363
364 // Determine the value. If we have more than one key, then we
365 // get the objectlist of only these keys.
366 itemVal := item.Val
367 if len(item.Keys) > 1 {
368 itemVal = n.Filter(keyStr)
369 done[keyStr] = struct{}{}
370 }
371
372 // Make the field name
373 fieldName := fmt.Sprintf("%s.%s", name, keyStr)
374
375 // Get the key/value as reflection values
376 key := reflect.ValueOf(keyStr)
377 val := reflect.Indirect(reflect.New(resultElemType))
378
379 // If we have a pre-existing value in the map, use that
380 oldVal := resultMap.MapIndex(key)
381 if oldVal.IsValid() {
382 val.Set(oldVal)
383 }
384
385 // Decode!
386 if err := d.decode(fieldName, itemVal, val); err != nil {
387 return err
388 }
389
390 // Set the value on the map
391 resultMap.SetMapIndex(key, val)
392 }
393
394 // Set the final map if we can
395 set.Set(resultMap)
396 return nil
397 }
398
399 func (d *decoder) decodePtr(name string, node ast.Node, result reflect.Value) error {
400 // Create an element of the concrete (non pointer) type and decode
401 // into that. Then set the value of the pointer to this type.
402 resultType := result.Type()
403 resultElemType := resultType.Elem()
404 val := reflect.New(resultElemType)
405 if err := d.decode(name, node, reflect.Indirect(val)); err != nil {
406 return err
407 }
408
409 result.Set(val)
410 return nil
411 }
412
413 func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value) error {
414 // If we have an interface, then we can address the interface,
415 // but not the slice itself, so get the element but set the interface
416 set := result
417 if result.Kind() == reflect.Interface {
418 result = result.Elem()
419 }
420 // Create the slice if it isn't nil
421 resultType := result.Type()
422 resultElemType := resultType.Elem()
423 if result.IsNil() {
424 resultSliceType := reflect.SliceOf(resultElemType)
425 result = reflect.MakeSlice(
426 resultSliceType, 0, 0)
427 }
428
429 // Figure out the items we'll be copying into the slice
430 var items []ast.Node
431 switch n := node.(type) {
432 case *ast.ObjectList:
433 items = make([]ast.Node, len(n.Items))
434 for i, item := range n.Items {
435 items[i] = item
436 }
437 case *ast.ObjectType:
438 items = []ast.Node{n}
439 case *ast.ListType:
440 items = n.List
441 default:
442 return &parser.PosError{
443 Pos: node.Pos(),
444 Err: fmt.Errorf("unknown slice type: %T", node),
445 }
446 }
447
448 for i, item := range items {
449 fieldName := fmt.Sprintf("%s[%d]", name, i)
450
451 // Decode
452 val := reflect.Indirect(reflect.New(resultElemType))
453
454 // if item is an object that was decoded from ambiguous JSON and
455 // flattened, make sure it's expanded if it needs to decode into a
456 // defined structure.
457 item := expandObject(item, val)
458
459 if err := d.decode(fieldName, item, val); err != nil {
460 return err
461 }
462
463 // Append it onto the slice
464 result = reflect.Append(result, val)
465 }
466
467 set.Set(result)
468 return nil
469 }
470
471 // expandObject detects if an ambiguous JSON object was flattened to a List which
472 // should be decoded into a struct, and expands the ast to properly deocode.
473 func expandObject(node ast.Node, result reflect.Value) ast.Node {
474 item, ok := node.(*ast.ObjectItem)
475 if !ok {
476 return node
477 }
478
479 elemType := result.Type()
480
481 // our target type must be a struct
482 switch elemType.Kind() {
483 case reflect.Ptr:
484 switch elemType.Elem().Kind() {
485 case reflect.Struct:
486 //OK
487 default:
488 return node
489 }
490 case reflect.Struct:
491 //OK
492 default:
493 return node
494 }
495
496 // A list value will have a key and field name. If it had more fields,
497 // it wouldn't have been flattened.
498 if len(item.Keys) != 2 {
499 return node
500 }
501
502 keyToken := item.Keys[0].Token
503 item.Keys = item.Keys[1:]
504
505 // we need to un-flatten the ast enough to decode
506 newNode := &ast.ObjectItem{
507 Keys: []*ast.ObjectKey{
508 &ast.ObjectKey{
509 Token: keyToken,
510 },
511 },
512 Val: &ast.ObjectType{
513 List: &ast.ObjectList{
514 Items: []*ast.ObjectItem{item},
515 },
516 },
517 }
518
519 return newNode
520 }
521
522 func (d *decoder) decodeString(name string, node ast.Node, result reflect.Value) error {
523 switch n := node.(type) {
524 case *ast.LiteralType:
525 switch n.Token.Type {
526 case token.NUMBER:
527 result.Set(reflect.ValueOf(n.Token.Text).Convert(result.Type()))
528 return nil
529 case token.STRING, token.HEREDOC:
530 result.Set(reflect.ValueOf(n.Token.Value()).Convert(result.Type()))
531 return nil
532 }
533 }
534
535 return &parser.PosError{
536 Pos: node.Pos(),
537 Err: fmt.Errorf("%s: unknown type for string %T", name, node),
538 }
539 }
540
541 func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) error {
542 var item *ast.ObjectItem
543 if it, ok := node.(*ast.ObjectItem); ok {
544 item = it
545 node = it.Val
546 }
547
548 if ot, ok := node.(*ast.ObjectType); ok {
549 node = ot.List
550 }
551
552 // Handle the special case where the object itself is a literal. Previously
553 // the yacc parser would always ensure top-level elements were arrays. The new
554 // parser does not make the same guarantees, thus we need to convert any
555 // top-level literal elements into a list.
556 if _, ok := node.(*ast.LiteralType); ok && item != nil {
557 node = &ast.ObjectList{Items: []*ast.ObjectItem{item}}
558 }
559
560 list, ok := node.(*ast.ObjectList)
561 if !ok {
562 return &parser.PosError{
563 Pos: node.Pos(),
564 Err: fmt.Errorf("%s: not an object type for struct (%T)", name, node),
565 }
566 }
567
568 // This slice will keep track of all the structs we'll be decoding.
569 // There can be more than one struct if there are embedded structs
570 // that are squashed.
571 structs := make([]reflect.Value, 1, 5)
572 structs[0] = result
573
574 // Compile the list of all the fields that we're going to be decoding
575 // from all the structs.
576 fields := make(map[*reflect.StructField]reflect.Value)
577 for len(structs) > 0 {
578 structVal := structs[0]
579 structs = structs[1:]
580
581 structType := structVal.Type()
582 for i := 0; i < structType.NumField(); i++ {
583 fieldType := structType.Field(i)
584 tagParts := strings.Split(fieldType.Tag.Get(tagName), ",")
585
586 // Ignore fields with tag name "-"
587 if tagParts[0] == "-" {
588 continue
589 }
590
591 if fieldType.Anonymous {
592 fieldKind := fieldType.Type.Kind()
593 if fieldKind != reflect.Struct {
594 return &parser.PosError{
595 Pos: node.Pos(),
596 Err: fmt.Errorf("%s: unsupported type to struct: %s",
597 fieldType.Name, fieldKind),
598 }
599 }
600
601 // We have an embedded field. We "squash" the fields down
602 // if specified in the tag.
603 squash := false
604 for _, tag := range tagParts[1:] {
605 if tag == "squash" {
606 squash = true
607 break
608 }
609 }
610
611 if squash {
612 structs = append(
613 structs, result.FieldByName(fieldType.Name))
614 continue
615 }
616 }
617
618 // Normal struct field, store it away
619 fields[&fieldType] = structVal.Field(i)
620 }
621 }
622
623 usedKeys := make(map[string]struct{})
624 decodedFields := make([]string, 0, len(fields))
625 decodedFieldsVal := make([]reflect.Value, 0)
626 unusedKeysVal := make([]reflect.Value, 0)
627 for fieldType, field := range fields {
628 if !field.IsValid() {
629 // This should never happen
630 panic("field is not valid")
631 }
632
633 // If we can't set the field, then it is unexported or something,
634 // and we just continue onwards.
635 if !field.CanSet() {
636 continue
637 }
638
639 fieldName := fieldType.Name
640
641 tagValue := fieldType.Tag.Get(tagName)
642 tagParts := strings.SplitN(tagValue, ",", 2)
643 if len(tagParts) >= 2 {
644 switch tagParts[1] {
645 case "decodedFields":
646 decodedFieldsVal = append(decodedFieldsVal, field)
647 continue
648 case "key":
649 if item == nil {
650 return &parser.PosError{
651 Pos: node.Pos(),
652 Err: fmt.Errorf("%s: %s asked for 'key', impossible",
653 name, fieldName),
654 }
655 }
656
657 field.SetString(item.Keys[0].Token.Value().(string))
658 continue
659 case "unusedKeys":
660 unusedKeysVal = append(unusedKeysVal, field)
661 continue
662 }
663 }
664
665 if tagParts[0] != "" {
666 fieldName = tagParts[0]
667 }
668
669 // Determine the element we'll use to decode. If it is a single
670 // match (only object with the field), then we decode it exactly.
671 // If it is a prefix match, then we decode the matches.
672 filter := list.Filter(fieldName)
673
674 prefixMatches := filter.Children()
675 matches := filter.Elem()
676 if len(matches.Items) == 0 && len(prefixMatches.Items) == 0 {
677 continue
678 }
679
680 // Track the used key
681 usedKeys[fieldName] = struct{}{}
682
683 // Create the field name and decode. We range over the elements
684 // because we actually want the value.
685 fieldName = fmt.Sprintf("%s.%s", name, fieldName)
686 if len(prefixMatches.Items) > 0 {
687 if err := d.decode(fieldName, prefixMatches, field); err != nil {
688 return err
689 }
690 }
691 for _, match := range matches.Items {
692 var decodeNode ast.Node = match.Val
693 if ot, ok := decodeNode.(*ast.ObjectType); ok {
694 decodeNode = &ast.ObjectList{Items: ot.List.Items}
695 }
696
697 if err := d.decode(fieldName, decodeNode, field); err != nil {
698 return err
699 }
700 }
701
702 decodedFields = append(decodedFields, fieldType.Name)
703 }
704
705 if len(decodedFieldsVal) > 0 {
706 // Sort it so that it is deterministic
707 sort.Strings(decodedFields)
708
709 for _, v := range decodedFieldsVal {
710 v.Set(reflect.ValueOf(decodedFields))
711 }
712 }
713
714 return nil
715 }
716
717 // findNodeType returns the type of ast.Node
718 func findNodeType() reflect.Type {
719 var nodeContainer struct {
720 Node ast.Node
721 }
722 value := reflect.ValueOf(nodeContainer).FieldByName("Node")
723 return value.Type()
724 }