1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package cue
16
17 import (
18 "bytes"
19 "encoding"
20 "encoding/json"
21 "reflect"
22 "sort"
23 "strconv"
24 "strings"
25 "sync"
26 "unicode"
27 "unicode/utf8"
28
29 "cuelang.org/go/cue/errors"
30 "cuelang.org/go/internal/core/adt"
31 )
32
33
34
35
36
37
38
39
40
41 func (v Value) Decode(x interface{}) error {
42 var d decoder
43 w := reflect.ValueOf(x)
44 if w.Kind() != reflect.Pointer || w.IsNil() {
45 d.addErr(errors.Newf(v.Pos(), "cannot decode into unsettable value"))
46 return d.errs
47 }
48 d.decode(w.Elem(), v, false)
49 return d.errs
50 }
51
52 type decoder struct {
53 errs errors.Error
54 }
55
56 func (d *decoder) addErr(err error) {
57 if err != nil {
58 d.errs = errors.Append(d.errs, errors.Promote(err, ""))
59 }
60 }
61
62 func incompleteError(v Value) errors.Error {
63 return &valueError{
64 v: v,
65 err: &adt.Bottom{
66 Code: adt.IncompleteError,
67 Err: errors.Newf(v.Pos(),
68 "cannot convert non-concrete value %v", v)},
69 }
70 }
71
72 func (d *decoder) clear(x reflect.Value) {
73 if x.CanSet() {
74 x.SetZero()
75 }
76 }
77
78 var valueType = reflect.TypeOf(Value{})
79
80 func (d *decoder) decode(x reflect.Value, v Value, isPtr bool) {
81 if !x.IsValid() {
82 d.addErr(errors.Newf(v.Pos(), "cannot decode into invalid value"))
83 return
84 }
85
86 v, _ = v.Default()
87 if v.v == nil {
88 d.clear(x)
89 return
90 }
91
92 if err := v.Err(); err != nil {
93 d.addErr(err)
94 return
95 }
96 if x.Type() == valueType {
97 x.Set(reflect.ValueOf(v))
98 return
99 }
100
101 switch x.Kind() {
102 case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Interface:
103
104 if v.Null() == nil || !v.IsConcrete() {
105 d.clear(x)
106 return
107 }
108
109 default:
110
111 if !v.IsConcrete() {
112 d.addErr(incompleteError(v))
113 return
114 }
115 }
116
117 ij, it, x := indirect(x, v.Null() == nil)
118
119 if ij != nil {
120 b, err := v.marshalJSON()
121 d.addErr(err)
122 d.addErr(ij.UnmarshalJSON(b))
123 return
124 }
125
126 if it != nil {
127 b, err := v.Bytes()
128 if err != nil {
129 err = errors.Wrapf(err, v.Pos(), "Decode")
130 d.addErr(err)
131 return
132 }
133 d.addErr(it.UnmarshalText(b))
134 return
135 }
136
137 kind := x.Kind()
138
139 if kind == reflect.Interface {
140 value := d.interfaceValue(v)
141 x.Set(reflect.ValueOf(value))
142 return
143 }
144
145 switch kind {
146 case reflect.Ptr:
147 d.decode(x.Elem(), v, true)
148
149 case reflect.Bool:
150 b, err := v.Bool()
151 d.addErr(err)
152 x.SetBool(b)
153
154 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
155 i, err := v.Int64()
156 d.addErr(err)
157 if x.OverflowInt(i) {
158 d.addErr(errors.Newf(v.Pos(), "integer %d overflows %s", i, kind))
159 break
160 }
161 x.SetInt(i)
162
163 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
164 i, err := v.Uint64()
165 d.addErr(err)
166 if x.OverflowUint(i) {
167 d.addErr(errors.Newf(v.Pos(), "integer %d overflows %s", i, kind))
168 break
169 }
170 x.SetUint(i)
171
172 case reflect.Float32, reflect.Float64:
173 f, err := v.Float64()
174 d.addErr(err)
175 if x.OverflowFloat(f) {
176 d.addErr(errors.Newf(v.Pos(), "float %g overflows %s", f, kind))
177 break
178 }
179 x.SetFloat(f)
180
181 case reflect.String:
182 s, err := v.String()
183 d.addErr(err)
184 x.SetString(s)
185
186 case reflect.Array:
187 d.clear(x)
188
189 t := x.Type()
190 n := x.Len()
191
192 if t.Elem().Kind() == reflect.Uint8 && v.Kind() == BytesKind {
193 b, err := v.Bytes()
194 d.addErr(err)
195 for i, c := range b {
196 if i >= n {
197 break
198 }
199 x.Index(i).SetUint(uint64(c))
200 }
201 break
202 }
203
204 var a []Value
205 list, err := v.List()
206 d.addErr(err)
207 for list.Next() {
208 a = append(a, list.Value())
209 }
210
211 for i, v := range a {
212 if i >= n {
213 break
214 }
215 d.decode(x.Index(i), v, false)
216 }
217
218 case reflect.Slice:
219 t := x.Type()
220 if t.Elem().Kind() == reflect.Uint8 && v.Kind() == BytesKind {
221 b, err := v.Bytes()
222 d.addErr(err)
223 x.SetBytes(b)
224 break
225 }
226
227 var a []Value
228 list, err := v.List()
229 d.addErr(err)
230 for list.Next() {
231 a = append(a, list.Value())
232 }
233
234 switch cap := x.Cap(); {
235 case cap == 0,
236 cap < len(a):
237 x.Set(reflect.MakeSlice(t, len(a), len(a)))
238
239 default:
240 x.SetLen(len(a))
241 }
242
243 for i, v := range a {
244 d.decode(x.Index(i), v, false)
245 }
246
247 case reflect.Struct:
248 d.convertStruct(x, v)
249
250 case reflect.Map:
251 d.convertMap(x, v)
252
253 default:
254 d.clear(x)
255 }
256 }
257
258 func (d *decoder) interfaceValue(v Value) (x interface{}) {
259 var err error
260 v, _ = v.Default()
261 switch v.Kind() {
262 case NullKind:
263 return nil
264
265 case BoolKind:
266 x, err = v.Bool()
267
268 case IntKind:
269 if i, err := v.Int64(); err == nil {
270 return int(i)
271 }
272 x, err = v.Int(nil)
273
274 case FloatKind:
275 x, err = v.Float64()
276
277 case StringKind:
278 x, err = v.String()
279
280 case BytesKind:
281 x, err = v.Bytes()
282
283 case ListKind:
284 var a []interface{}
285 list, err := v.List()
286 d.addErr(err)
287 for list.Next() {
288 a = append(a, d.interfaceValue(list.Value()))
289 }
290 if a == nil {
291 a = []interface{}{}
292 }
293 x = a
294
295 case StructKind:
296 m := map[string]interface{}{}
297 iter, err := v.Fields()
298 d.addErr(err)
299 for iter.Next() {
300 m[iter.Label()] = d.interfaceValue(iter.Value())
301 }
302 x = m
303
304 default:
305 err = incompleteError(v)
306 }
307
308 d.addErr(err)
309 return x
310 }
311
312 var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
313
314
315
316 func (d *decoder) convertMap(x reflect.Value, v Value) {
317
318 t := x.Type()
319
320
321
322 switch t.Key().Kind() {
323 case reflect.String,
324 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
325 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
326 default:
327 if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) {
328 d.addErr(errors.Newf(v.Pos(), "unsupported key type %v", t.Key()))
329 return
330 }
331 }
332
333 if x.IsNil() {
334 x.Set(reflect.MakeMap(t))
335 }
336
337 var mapElem reflect.Value
338
339 iter, err := v.Fields()
340 d.addErr(err)
341 for iter.Next() {
342 key := iter.Label()
343
344 var kv reflect.Value
345 kt := t.Key()
346 if reflect.PointerTo(kt).Implements(textUnmarshalerType) {
347 kv = reflect.New(kt)
348 err := kv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(key))
349 d.addErr(err)
350 kv = kv.Elem()
351 } else {
352 switch kt.Kind() {
353 case reflect.String:
354 kv = reflect.ValueOf(key).Convert(kt)
355 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
356 n, err := strconv.ParseInt(key, 10, 64)
357 d.addErr(err)
358 if reflect.Zero(kt).OverflowInt(n) {
359 d.addErr(errors.Newf(v.Pos(), "key integer %d overflows %s", n, kt))
360 break
361 }
362 kv = reflect.ValueOf(n).Convert(kt)
363
364 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
365 n, err := strconv.ParseUint(key, 10, 64)
366 d.addErr(err)
367 if reflect.Zero(kt).OverflowUint(n) {
368 d.addErr(errors.Newf(v.Pos(), "key integer %d overflows %s", n, kt))
369 break
370 }
371 kv = reflect.ValueOf(n).Convert(kt)
372
373 default:
374 panic("json: Unexpected key type")
375 }
376 }
377
378 if !mapElem.IsValid() {
379 mapElem = reflect.New(t.Elem()).Elem()
380 } else {
381 mapElem.SetZero()
382 }
383 d.decode(mapElem, iter.Value(), false)
384
385 if kv.IsValid() {
386 x.SetMapIndex(kv, mapElem)
387 }
388 }
389 }
390
391 func (d *decoder) convertStruct(x reflect.Value, v Value) {
392 t := x.Type()
393 fields := cachedTypeFields(t)
394
395 iter, err := v.Fields()
396 d.addErr(err)
397 for iter.Next() {
398
399 var f *goField
400 key := iter.Label()
401 if i, ok := fields.nameIndex[key]; ok {
402
403 f = &fields.list[i]
404 } else {
405
406
407 key := []byte(key)
408 for i := range fields.list {
409 ff := &fields.list[i]
410 if ff.equalFold(ff.nameBytes, key) {
411 f = ff
412 break
413 }
414 }
415 }
416
417 if f == nil {
418 continue
419 }
420
421
422 subv := x
423 for _, i := range f.index {
424 if subv.Kind() == reflect.Ptr {
425 if subv.IsNil() {
426
427
428
429
430
431 if !subv.CanSet() {
432 d.addErr(errors.Newf(v.Pos(),
433 "cannot set embedded pointer to unexported struct: %v",
434 subv.Type().Elem()))
435 subv = reflect.Value{}
436 break
437 }
438 subv.Set(reflect.New(subv.Type().Elem()))
439 }
440 subv = subv.Elem()
441 }
442 subv = subv.Field(i)
443 }
444
445
446
447
448
449
450 d.decode(subv, iter.Value(), false)
451 }
452 }
453
454 type structFields struct {
455 list []goField
456 nameIndex map[string]int
457 }
458
459 func isValidTag(s string) bool {
460 if s == "" {
461 return false
462 }
463 for _, c := range s {
464 switch {
465 case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
466
467
468
469 case !unicode.IsLetter(c) && !unicode.IsDigit(c):
470 return false
471 }
472 }
473 return true
474 }
475
476
477 type goField struct {
478 name string
479 nameBytes []byte
480 equalFold func(s, t []byte) bool
481
482 nameNonEsc string
483 nameEscHTML string
484
485 tag bool
486 index []int
487 typ reflect.Type
488 omitEmpty bool
489 }
490
491
492 type byIndex []goField
493
494 func (x byIndex) Less(i, j int) bool {
495 for k, xik := range x[i].index {
496 if k >= len(x[j].index) {
497 return false
498 }
499 if xik != x[j].index[k] {
500 return xik < x[j].index[k]
501 }
502 }
503 return len(x[i].index) < len(x[j].index)
504 }
505
506
507
508
509 func typeFields(t reflect.Type) structFields {
510
511 current := []goField{}
512 next := []goField{{typ: t}}
513
514
515 var count, nextCount map[reflect.Type]int
516
517
518 visited := map[reflect.Type]bool{}
519
520
521 var fields []goField
522
523
524 var nameEscBuf bytes.Buffer
525
526 for len(next) > 0 {
527 current, next = next, current[:0]
528 count, nextCount = nextCount, map[reflect.Type]int{}
529
530 for _, f := range current {
531 if visited[f.typ] {
532 continue
533 }
534 visited[f.typ] = true
535
536
537 for i := 0; i < f.typ.NumField(); i++ {
538 sf := f.typ.Field(i)
539 isUnexported := sf.PkgPath != ""
540 if sf.Anonymous {
541 t := sf.Type
542 if t.Kind() == reflect.Ptr {
543 t = t.Elem()
544 }
545 if isUnexported && t.Kind() != reflect.Struct {
546
547 continue
548 }
549
550
551 } else if isUnexported {
552
553 continue
554 }
555 tag := sf.Tag.Get("json")
556 if tag == "-" {
557 continue
558 }
559 name, opts := parseTag(tag)
560 if !isValidTag(name) {
561 name = ""
562 }
563 index := make([]int, len(f.index)+1)
564 copy(index, f.index)
565 index[len(f.index)] = i
566
567 ft := sf.Type
568 if ft.Name() == "" && ft.Kind() == reflect.Ptr {
569
570 ft = ft.Elem()
571 }
572
573
574 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
575 tagged := name != ""
576 if name == "" {
577 name = sf.Name
578 }
579 field := goField{
580 name: name,
581 tag: tagged,
582 index: index,
583 typ: ft,
584 omitEmpty: opts.Contains("omitempty"),
585 }
586 field.nameBytes = []byte(field.name)
587 field.equalFold = foldFunc(field.nameBytes)
588
589
590 nameEscBuf.Reset()
591 nameEscBuf.WriteString(`"`)
592 json.HTMLEscape(&nameEscBuf, field.nameBytes)
593 nameEscBuf.WriteString(`":`)
594 field.nameEscHTML = nameEscBuf.String()
595 field.nameNonEsc = `"` + field.name + `":`
596
597 fields = append(fields, field)
598 if count[f.typ] > 1 {
599
600
601
602
603 fields = append(fields, fields[len(fields)-1])
604 }
605 continue
606 }
607
608
609 nextCount[ft]++
610 if nextCount[ft] == 1 {
611 next = append(next, goField{name: ft.Name(), index: index, typ: ft})
612 }
613 }
614 }
615 }
616
617 sort.Slice(fields, func(i, j int) bool {
618 x := fields
619
620
621
622 if x[i].name != x[j].name {
623 return x[i].name < x[j].name
624 }
625 if len(x[i].index) != len(x[j].index) {
626 return len(x[i].index) < len(x[j].index)
627 }
628 if x[i].tag != x[j].tag {
629 return x[i].tag
630 }
631 return byIndex(x).Less(i, j)
632 })
633
634
635
636
637
638
639
640 out := fields[:0]
641 for advance, i := 0, 0; i < len(fields); i += advance {
642
643
644 fi := fields[i]
645 name := fi.name
646 for advance = 1; i+advance < len(fields); advance++ {
647 fj := fields[i+advance]
648 if fj.name != name {
649 break
650 }
651 }
652 if advance == 1 {
653 out = append(out, fi)
654 continue
655 }
656 dominant, ok := dominantField(fields[i : i+advance])
657 if ok {
658 out = append(out, dominant)
659 }
660 }
661
662 fields = out
663 sort.Slice(fields, byIndex(fields).Less)
664
665 nameIndex := make(map[string]int, len(fields))
666 for i, field := range fields {
667 nameIndex[field.name] = i
668 }
669 return structFields{fields, nameIndex}
670 }
671
672
673
674
675
676
677
678 func dominantField(fields []goField) (goField, bool) {
679
680
681
682 if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
683 return goField{}, false
684 }
685 return fields[0], true
686 }
687
688 var fieldCache sync.Map
689
690
691 func cachedTypeFields(t reflect.Type) structFields {
692 if f, ok := fieldCache.Load(t); ok {
693 return f.(structFields)
694 }
695 f, _ := fieldCache.LoadOrStore(t, typeFields(t))
696 return f.(structFields)
697 }
698
699
700
701 type tagOptions string
702
703
704
705 func parseTag(tag string) (string, tagOptions) {
706 if idx := strings.Index(tag, ","); idx != -1 {
707 return tag[:idx], tagOptions(tag[idx+1:])
708 }
709 return tag, tagOptions("")
710 }
711
712
713
714
715 func (o tagOptions) Contains(optionName string) bool {
716 if len(o) == 0 {
717 return false
718 }
719 s := string(o)
720 for s != "" {
721 var next string
722 i := strings.Index(s, ",")
723 if i >= 0 {
724 s, next = s[:i], s[i+1:]
725 }
726 if s == optionName {
727 return true
728 }
729 s = next
730 }
731 return false
732 }
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750 func foldFunc(s []byte) func(s, t []byte) bool {
751 nonLetter := false
752 special := false
753 for _, b := range s {
754 if b >= utf8.RuneSelf {
755 return bytes.EqualFold
756 }
757 upper := b & caseMask
758 if upper < 'A' || upper > 'Z' {
759 nonLetter = true
760 } else if upper == 'K' || upper == 'S' {
761
762 special = true
763 }
764 }
765 if special {
766 return equalFoldRight
767 }
768 if nonLetter {
769 return asciiEqualFold
770 }
771 return simpleLetterEqualFold
772 }
773
774 const (
775 caseMask = ^byte(0x20)
776 kelvin = '\u212a'
777 smallLongEss = '\u017f'
778 )
779
780
781
782
783
784 func equalFoldRight(s, t []byte) bool {
785 for _, sb := range s {
786 if len(t) == 0 {
787 return false
788 }
789 tb := t[0]
790 if tb < utf8.RuneSelf {
791 if sb != tb {
792 sbUpper := sb & caseMask
793 if 'A' <= sbUpper && sbUpper <= 'Z' {
794 if sbUpper != tb&caseMask {
795 return false
796 }
797 } else {
798 return false
799 }
800 }
801 t = t[1:]
802 continue
803 }
804
805
806 tr, size := utf8.DecodeRune(t)
807 switch sb {
808 case 's', 'S':
809 if tr != smallLongEss {
810 return false
811 }
812 case 'k', 'K':
813 if tr != kelvin {
814 return false
815 }
816 default:
817 return false
818 }
819 t = t[size:]
820
821 }
822 return len(t) == 0
823 }
824
825
826
827
828
829 func asciiEqualFold(s, t []byte) bool {
830 if len(s) != len(t) {
831 return false
832 }
833 for i, sb := range s {
834 tb := t[i]
835 if sb == tb {
836 continue
837 }
838 if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
839 if sb&caseMask != tb&caseMask {
840 return false
841 }
842 } else {
843 return false
844 }
845 }
846 return true
847 }
848
849
850
851
852
853 func simpleLetterEqualFold(s, t []byte) bool {
854 if len(s) != len(t) {
855 return false
856 }
857 for i, b := range s {
858 if b&caseMask != t[i]&caseMask {
859 return false
860 }
861 }
862 return true
863 }
864
865
866
867
868
869
870 func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
871
872
873
874
875
876
877
878
879
880
881
882 v0 := v
883 haveAddr := false
884
885
886
887
888 if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
889 haveAddr = true
890 v = v.Addr()
891 }
892 for {
893
894
895 if v.Kind() == reflect.Interface && !v.IsNil() {
896 e := v.Elem()
897 if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
898 haveAddr = false
899 v = e
900 continue
901 }
902 }
903
904 if v.Kind() != reflect.Ptr {
905 break
906 }
907
908 if decodingNull && v.CanSet() {
909 break
910 }
911
912
913
914
915 if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v {
916 v = v.Elem()
917 break
918 }
919 if v.IsNil() {
920 v.Set(reflect.New(v.Type().Elem()))
921 }
922 if v.Type().NumMethod() > 0 && v.CanInterface() {
923 if u, ok := v.Interface().(json.Unmarshaler); ok {
924 return u, nil, reflect.Value{}
925 }
926 if !decodingNull {
927 if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
928 return nil, u, reflect.Value{}
929 }
930 }
931 }
932
933 if haveAddr {
934 v = v0
935 haveAddr = false
936 } else {
937 v = v.Elem()
938 }
939 }
940 return nil, nil, v
941 }
942
View as plain text