OSDN Git Service

Hulk did something
[bytom/vapor.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.Float32, 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 || n.Token.Type == token.NUMBER {
141                         v, err := strconv.ParseFloat(n.Token.Text, 64)
142                         if err != nil {
143                                 return err
144                         }
145
146                         result.Set(reflect.ValueOf(v).Convert(result.Type()))
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         type field struct {
577                 field reflect.StructField
578                 val   reflect.Value
579         }
580         fields := []field{}
581         for len(structs) > 0 {
582                 structVal := structs[0]
583                 structs = structs[1:]
584
585                 structType := structVal.Type()
586                 for i := 0; i < structType.NumField(); i++ {
587                         fieldType := structType.Field(i)
588                         tagParts := strings.Split(fieldType.Tag.Get(tagName), ",")
589
590                         // Ignore fields with tag name "-"
591                         if tagParts[0] == "-" {
592                                 continue
593                         }
594
595                         if fieldType.Anonymous {
596                                 fieldKind := fieldType.Type.Kind()
597                                 if fieldKind != reflect.Struct {
598                                         return &parser.PosError{
599                                                 Pos: node.Pos(),
600                                                 Err: fmt.Errorf("%s: unsupported type to struct: %s",
601                                                         fieldType.Name, fieldKind),
602                                         }
603                                 }
604
605                                 // We have an embedded field. We "squash" the fields down
606                                 // if specified in the tag.
607                                 squash := false
608                                 for _, tag := range tagParts[1:] {
609                                         if tag == "squash" {
610                                                 squash = true
611                                                 break
612                                         }
613                                 }
614
615                                 if squash {
616                                         structs = append(
617                                                 structs, result.FieldByName(fieldType.Name))
618                                         continue
619                                 }
620                         }
621
622                         // Normal struct field, store it away
623                         fields = append(fields, field{fieldType, structVal.Field(i)})
624                 }
625         }
626
627         usedKeys := make(map[string]struct{})
628         decodedFields := make([]string, 0, len(fields))
629         decodedFieldsVal := make([]reflect.Value, 0)
630         unusedKeysVal := make([]reflect.Value, 0)
631         for _, f := range fields {
632                 field, fieldValue := f.field, f.val
633                 if !fieldValue.IsValid() {
634                         // This should never happen
635                         panic("field is not valid")
636                 }
637
638                 // If we can't set the field, then it is unexported or something,
639                 // and we just continue onwards.
640                 if !fieldValue.CanSet() {
641                         continue
642                 }
643
644                 fieldName := field.Name
645
646                 tagValue := field.Tag.Get(tagName)
647                 tagParts := strings.SplitN(tagValue, ",", 2)
648                 if len(tagParts) >= 2 {
649                         switch tagParts[1] {
650                         case "decodedFields":
651                                 decodedFieldsVal = append(decodedFieldsVal, fieldValue)
652                                 continue
653                         case "key":
654                                 if item == nil {
655                                         return &parser.PosError{
656                                                 Pos: node.Pos(),
657                                                 Err: fmt.Errorf("%s: %s asked for 'key', impossible",
658                                                         name, fieldName),
659                                         }
660                                 }
661
662                                 fieldValue.SetString(item.Keys[0].Token.Value().(string))
663                                 continue
664                         case "unusedKeys":
665                                 unusedKeysVal = append(unusedKeysVal, fieldValue)
666                                 continue
667                         }
668                 }
669
670                 if tagParts[0] != "" {
671                         fieldName = tagParts[0]
672                 }
673
674                 // Determine the element we'll use to decode. If it is a single
675                 // match (only object with the field), then we decode it exactly.
676                 // If it is a prefix match, then we decode the matches.
677                 filter := list.Filter(fieldName)
678
679                 prefixMatches := filter.Children()
680                 matches := filter.Elem()
681                 if len(matches.Items) == 0 && len(prefixMatches.Items) == 0 {
682                         continue
683                 }
684
685                 // Track the used key
686                 usedKeys[fieldName] = struct{}{}
687
688                 // Create the field name and decode. We range over the elements
689                 // because we actually want the value.
690                 fieldName = fmt.Sprintf("%s.%s", name, fieldName)
691                 if len(prefixMatches.Items) > 0 {
692                         if err := d.decode(fieldName, prefixMatches, fieldValue); err != nil {
693                                 return err
694                         }
695                 }
696                 for _, match := range matches.Items {
697                         var decodeNode ast.Node = match.Val
698                         if ot, ok := decodeNode.(*ast.ObjectType); ok {
699                                 decodeNode = &ast.ObjectList{Items: ot.List.Items}
700                         }
701
702                         if err := d.decode(fieldName, decodeNode, fieldValue); err != nil {
703                                 return err
704                         }
705                 }
706
707                 decodedFields = append(decodedFields, field.Name)
708         }
709
710         if len(decodedFieldsVal) > 0 {
711                 // Sort it so that it is deterministic
712                 sort.Strings(decodedFields)
713
714                 for _, v := range decodedFieldsVal {
715                         v.Set(reflect.ValueOf(decodedFields))
716                 }
717         }
718
719         return nil
720 }
721
722 // findNodeType returns the type of ast.Node
723 func findNodeType() reflect.Type {
724         var nodeContainer struct {
725                 Node ast.Node
726         }
727         value := reflect.ValueOf(nodeContainer).FieldByName("Node")
728         return value.Type()
729 }