1
2
3
4
5
6
7
8
9
10
11 package json
12
13 import (
14 "bytes"
15 "encoding"
16 "encoding/base64"
17 "fmt"
18 "math"
19 "reflect"
20 "runtime"
21 "sort"
22 "strconv"
23 "strings"
24 "sync"
25 "unicode"
26 "unicode/utf8"
27 )
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 func Marshal(v interface{}) ([]byte, error) {
138 e := &encodeState{}
139 err := e.marshal(v)
140 if err != nil {
141 return nil, err
142 }
143 return e.Bytes(), nil
144 }
145
146
147 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
148 b, err := Marshal(v)
149 if err != nil {
150 return nil, err
151 }
152 var buf bytes.Buffer
153 err = Indent(&buf, b, prefix, indent)
154 if err != nil {
155 return nil, err
156 }
157 return buf.Bytes(), nil
158 }
159
160
161
162
163
164
165
166 func HTMLEscape(dst *bytes.Buffer, src []byte) {
167
168
169 start := 0
170 for i, c := range src {
171 if c == '<' || c == '>' || c == '&' {
172 if start < i {
173 dst.Write(src[start:i])
174 }
175 dst.WriteString(`\u00`)
176 dst.WriteByte(hex[c>>4])
177 dst.WriteByte(hex[c&0xF])
178 start = i + 1
179 }
180
181 if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
182 if start < i {
183 dst.Write(src[start:i])
184 }
185 dst.WriteString(`\u202`)
186 dst.WriteByte(hex[src[i+2]&0xF])
187 start = i + 3
188 }
189 }
190 if start < len(src) {
191 dst.Write(src[start:])
192 }
193 }
194
195
196
197 type Marshaler interface {
198 MarshalJSON() ([]byte, error)
199 }
200
201
202
203 type UnsupportedTypeError struct {
204 Type reflect.Type
205 }
206
207 func (e *UnsupportedTypeError) Error() string {
208 return "json: unsupported type: " + e.Type.String()
209 }
210
211 type UnsupportedValueError struct {
212 Value reflect.Value
213 Str string
214 }
215
216 func (e *UnsupportedValueError) Error() string {
217 return "json: unsupported value: " + e.Str
218 }
219
220
221
222
223
224
225
226 type InvalidUTF8Error struct {
227 S string
228 }
229
230 func (e *InvalidUTF8Error) Error() string {
231 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
232 }
233
234 type MarshalerError struct {
235 Type reflect.Type
236 Err error
237 }
238
239 func (e *MarshalerError) Error() string {
240 return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
241 }
242
243 var hex = "0123456789abcdef"
244
245
246 type encodeState struct {
247 bytes.Buffer
248 scratch [64]byte
249 }
250
251 var encodeStatePool sync.Pool
252
253 func newEncodeState() *encodeState {
254 if v := encodeStatePool.Get(); v != nil {
255 e := v.(*encodeState)
256 e.Reset()
257 return e
258 }
259 return new(encodeState)
260 }
261
262 func (e *encodeState) marshal(v interface{}) (err error) {
263 defer func() {
264 if r := recover(); r != nil {
265 if _, ok := r.(runtime.Error); ok {
266 panic(r)
267 }
268 if s, ok := r.(string); ok {
269 panic(s)
270 }
271 err = r.(error)
272 }
273 }()
274 e.reflectValue(reflect.ValueOf(v))
275 return nil
276 }
277
278 func (e *encodeState) error(err error) {
279 panic(err)
280 }
281
282 func isEmptyValue(v reflect.Value) bool {
283 switch v.Kind() {
284 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
285 return v.Len() == 0
286 case reflect.Bool:
287 return !v.Bool()
288 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
289 return v.Int() == 0
290 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
291 return v.Uint() == 0
292 case reflect.Float32, reflect.Float64:
293 return v.Float() == 0
294 case reflect.Interface, reflect.Ptr:
295 return v.IsNil()
296 }
297 return false
298 }
299
300 func (e *encodeState) reflectValue(v reflect.Value) {
301 valueEncoder(v)(e, v, false)
302 }
303
304 type encoderFunc func(e *encodeState, v reflect.Value, quoted bool)
305
306 var encoderCache struct {
307 sync.RWMutex
308 m map[reflect.Type]encoderFunc
309 }
310
311 func valueEncoder(v reflect.Value) encoderFunc {
312 if !v.IsValid() {
313 return invalidValueEncoder
314 }
315 return typeEncoder(v.Type())
316 }
317
318 func typeEncoder(t reflect.Type) encoderFunc {
319 encoderCache.RLock()
320 f := encoderCache.m[t]
321 encoderCache.RUnlock()
322 if f != nil {
323 return f
324 }
325
326
327
328
329
330 encoderCache.Lock()
331 if encoderCache.m == nil {
332 encoderCache.m = make(map[reflect.Type]encoderFunc)
333 }
334 var wg sync.WaitGroup
335 wg.Add(1)
336 encoderCache.m[t] = func(e *encodeState, v reflect.Value, quoted bool) {
337 wg.Wait()
338 f(e, v, quoted)
339 }
340 encoderCache.Unlock()
341
342
343
344 f = newTypeEncoder(t, true)
345 wg.Done()
346 encoderCache.Lock()
347 encoderCache.m[t] = f
348 encoderCache.Unlock()
349 return f
350 }
351
352 var (
353 marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
354 textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()
355 )
356
357
358
359 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
360 if t.Implements(marshalerType) {
361 return marshalerEncoder
362 }
363 if t.Kind() != reflect.Ptr && allowAddr {
364 if reflect.PtrTo(t).Implements(marshalerType) {
365 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
366 }
367 }
368
369 if t.Implements(textMarshalerType) {
370 return textMarshalerEncoder
371 }
372 if t.Kind() != reflect.Ptr && allowAddr {
373 if reflect.PtrTo(t).Implements(textMarshalerType) {
374 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
375 }
376 }
377
378 switch t.Kind() {
379 case reflect.Bool:
380 return boolEncoder
381 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
382 return intEncoder
383 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
384 return uintEncoder
385 case reflect.Float32:
386 return float32Encoder
387 case reflect.Float64:
388 return float64Encoder
389 case reflect.String:
390 return stringEncoder
391 case reflect.Interface:
392 return interfaceEncoder
393 case reflect.Struct:
394 return newStructEncoder(t)
395 case reflect.Map:
396 return newMapEncoder(t)
397 case reflect.Slice:
398 return newSliceEncoder(t)
399 case reflect.Array:
400 return newArrayEncoder(t)
401 case reflect.Ptr:
402 return newPtrEncoder(t)
403 default:
404 return unsupportedTypeEncoder
405 }
406 }
407
408 func invalidValueEncoder(e *encodeState, v reflect.Value, quoted bool) {
409 e.WriteString("null")
410 }
411
412 func marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
413 if v.Kind() == reflect.Ptr && v.IsNil() {
414 e.WriteString("null")
415 return
416 }
417 m := v.Interface().(Marshaler)
418 b, err := m.MarshalJSON()
419 if err == nil {
420
421 err = compact(&e.Buffer, b, true)
422 }
423 if err != nil {
424 e.error(&MarshalerError{v.Type(), err})
425 }
426 }
427
428 func addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
429 va := v.Addr()
430 if va.IsNil() {
431 e.WriteString("null")
432 return
433 }
434 m := va.Interface().(Marshaler)
435 b, err := m.MarshalJSON()
436 if err == nil {
437
438 err = compact(&e.Buffer, b, true)
439 }
440 if err != nil {
441 e.error(&MarshalerError{v.Type(), err})
442 }
443 }
444
445 func textMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
446 if v.Kind() == reflect.Ptr && v.IsNil() {
447 e.WriteString("null")
448 return
449 }
450 m := v.Interface().(encoding.TextMarshaler)
451 b, err := m.MarshalText()
452 if err != nil {
453 e.error(&MarshalerError{v.Type(), err})
454 }
455 e.stringBytes(b)
456 }
457
458 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
459 va := v.Addr()
460 if va.IsNil() {
461 e.WriteString("null")
462 return
463 }
464 m := va.Interface().(encoding.TextMarshaler)
465 b, err := m.MarshalText()
466 if err != nil {
467 e.error(&MarshalerError{v.Type(), err})
468 }
469 e.stringBytes(b)
470 }
471
472 func boolEncoder(e *encodeState, v reflect.Value, quoted bool) {
473 if quoted {
474 e.WriteByte('"')
475 }
476 if v.Bool() {
477 e.WriteString("true")
478 } else {
479 e.WriteString("false")
480 }
481 if quoted {
482 e.WriteByte('"')
483 }
484 }
485
486 func intEncoder(e *encodeState, v reflect.Value, quoted bool) {
487 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
488 if quoted {
489 e.WriteByte('"')
490 }
491 e.Write(b)
492 if quoted {
493 e.WriteByte('"')
494 }
495 }
496
497 func uintEncoder(e *encodeState, v reflect.Value, quoted bool) {
498 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
499 if quoted {
500 e.WriteByte('"')
501 }
502 e.Write(b)
503 if quoted {
504 e.WriteByte('"')
505 }
506 }
507
508 type floatEncoder int
509
510 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
511 f := v.Float()
512 if math.IsInf(f, 0) || math.IsNaN(f) {
513 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
514 }
515 b := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, int(bits))
516 if quoted {
517 e.WriteByte('"')
518 }
519 e.Write(b)
520 if quoted {
521 e.WriteByte('"')
522 }
523 }
524
525 var (
526 float32Encoder = (floatEncoder(32)).encode
527 float64Encoder = (floatEncoder(64)).encode
528 )
529
530 func stringEncoder(e *encodeState, v reflect.Value, quoted bool) {
531 if v.Type() == numberType {
532 numStr := v.String()
533
534
535 if numStr == "" {
536 numStr = "0"
537 }
538 if !isValidNumber(numStr) {
539 e.error(fmt.Errorf("json: invalid number literal %q", numStr))
540 }
541 e.WriteString(numStr)
542 return
543 }
544 if quoted {
545 sb, err := Marshal(v.String())
546 if err != nil {
547 e.error(err)
548 }
549 e.string(string(sb))
550 } else {
551 e.string(v.String())
552 }
553 }
554
555 func interfaceEncoder(e *encodeState, v reflect.Value, quoted bool) {
556 if v.IsNil() {
557 e.WriteString("null")
558 return
559 }
560 e.reflectValue(v.Elem())
561 }
562
563 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, quoted bool) {
564 e.error(&UnsupportedTypeError{v.Type()})
565 }
566
567 type structEncoder struct {
568 fields []field
569 fieldEncs []encoderFunc
570 }
571
572 func (se *structEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
573 e.WriteByte('{')
574 first := true
575 for i, f := range se.fields {
576 fv := fieldByIndex(v, f.index)
577 if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) {
578 continue
579 }
580 if first {
581 first = false
582 } else {
583 e.WriteByte(',')
584 }
585 e.string(f.name)
586 e.WriteByte(':')
587 se.fieldEncs[i](e, fv, f.quoted)
588 }
589 e.WriteByte('}')
590 }
591
592 func newStructEncoder(t reflect.Type) encoderFunc {
593 fields := cachedTypeFields(t)
594 se := &structEncoder{
595 fields: fields,
596 fieldEncs: make([]encoderFunc, len(fields)),
597 }
598 for i, f := range fields {
599 se.fieldEncs[i] = typeEncoder(typeByIndex(t, f.index))
600 }
601 return se.encode
602 }
603
604 type mapEncoder struct {
605 elemEnc encoderFunc
606 }
607
608 func (me *mapEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
609 if v.IsNil() {
610 e.WriteString("null")
611 return
612 }
613 e.WriteByte('{')
614 var sv stringValues = v.MapKeys()
615 sort.Sort(sv)
616 for i, k := range sv {
617 if i > 0 {
618 e.WriteByte(',')
619 }
620 e.string(k.String())
621 e.WriteByte(':')
622 me.elemEnc(e, v.MapIndex(k), false)
623 }
624 e.WriteByte('}')
625 }
626
627 func newMapEncoder(t reflect.Type) encoderFunc {
628 if t.Key().Kind() != reflect.String {
629 return unsupportedTypeEncoder
630 }
631 me := &mapEncoder{typeEncoder(t.Elem())}
632 return me.encode
633 }
634
635 func encodeByteSlice(e *encodeState, v reflect.Value, _ bool) {
636 if v.IsNil() {
637 e.WriteString("null")
638 return
639 }
640 s := v.Bytes()
641 e.WriteByte('"')
642 if len(s) < 1024 {
643
644 dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
645 base64.StdEncoding.Encode(dst, s)
646 e.Write(dst)
647 } else {
648
649
650 enc := base64.NewEncoder(base64.StdEncoding, e)
651 enc.Write(s)
652 enc.Close()
653 }
654 e.WriteByte('"')
655 }
656
657
658 type sliceEncoder struct {
659 arrayEnc encoderFunc
660 }
661
662 func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
663 if v.IsNil() {
664 e.WriteString("null")
665 return
666 }
667 se.arrayEnc(e, v, false)
668 }
669
670 func newSliceEncoder(t reflect.Type) encoderFunc {
671
672 if t.Elem().Kind() == reflect.Uint8 {
673 return encodeByteSlice
674 }
675 enc := &sliceEncoder{newArrayEncoder(t)}
676 return enc.encode
677 }
678
679 type arrayEncoder struct {
680 elemEnc encoderFunc
681 }
682
683 func (ae *arrayEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
684 e.WriteByte('[')
685 n := v.Len()
686 for i := 0; i < n; i++ {
687 if i > 0 {
688 e.WriteByte(',')
689 }
690 ae.elemEnc(e, v.Index(i), false)
691 }
692 e.WriteByte(']')
693 }
694
695 func newArrayEncoder(t reflect.Type) encoderFunc {
696 enc := &arrayEncoder{typeEncoder(t.Elem())}
697 return enc.encode
698 }
699
700 type ptrEncoder struct {
701 elemEnc encoderFunc
702 }
703
704 func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
705 if v.IsNil() {
706 e.WriteString("null")
707 return
708 }
709 pe.elemEnc(e, v.Elem(), quoted)
710 }
711
712 func newPtrEncoder(t reflect.Type) encoderFunc {
713 enc := &ptrEncoder{typeEncoder(t.Elem())}
714 return enc.encode
715 }
716
717 type condAddrEncoder struct {
718 canAddrEnc, elseEnc encoderFunc
719 }
720
721 func (ce *condAddrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
722 if v.CanAddr() {
723 ce.canAddrEnc(e, v, quoted)
724 } else {
725 ce.elseEnc(e, v, quoted)
726 }
727 }
728
729
730
731 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
732 enc := &condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
733 return enc.encode
734 }
735
736 func isValidTag(s string) bool {
737 if s == "" {
738 return false
739 }
740 for _, c := range s {
741 switch {
742 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
743
744
745
746 default:
747 if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
748 return false
749 }
750 }
751 }
752 return true
753 }
754
755 func fieldByIndex(v reflect.Value, index []int) reflect.Value {
756 for _, i := range index {
757 if v.Kind() == reflect.Ptr {
758 if v.IsNil() {
759 return reflect.Value{}
760 }
761 v = v.Elem()
762 }
763 v = v.Field(i)
764 }
765 return v
766 }
767
768 func typeByIndex(t reflect.Type, index []int) reflect.Type {
769 for _, i := range index {
770 if t.Kind() == reflect.Ptr {
771 t = t.Elem()
772 }
773 t = t.Field(i).Type
774 }
775 return t
776 }
777
778
779
780 type stringValues []reflect.Value
781
782 func (sv stringValues) Len() int { return len(sv) }
783 func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
784 func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
785 func (sv stringValues) get(i int) string { return sv[i].String() }
786
787
788 func (e *encodeState) string(s string) int {
789 len0 := e.Len()
790 e.WriteByte('"')
791 start := 0
792 for i := 0; i < len(s); {
793 if b := s[i]; b < utf8.RuneSelf {
794 if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
795 i++
796 continue
797 }
798 if start < i {
799 e.WriteString(s[start:i])
800 }
801 switch b {
802 case '\\', '"':
803 e.WriteByte('\\')
804 e.WriteByte(b)
805 case '\n':
806 e.WriteByte('\\')
807 e.WriteByte('n')
808 case '\r':
809 e.WriteByte('\\')
810 e.WriteByte('r')
811 case '\t':
812 e.WriteByte('\\')
813 e.WriteByte('t')
814 default:
815
816
817
818
819 e.WriteString(`\u00`)
820 e.WriteByte(hex[b>>4])
821 e.WriteByte(hex[b&0xF])
822 }
823 i++
824 start = i
825 continue
826 }
827 c, size := utf8.DecodeRuneInString(s[i:])
828 if c == utf8.RuneError && size == 1 {
829 if start < i {
830 e.WriteString(s[start:i])
831 }
832 e.WriteString(`\ufffd`)
833 i += size
834 start = i
835 continue
836 }
837
838
839
840
841
842
843
844 if c == '\u2028' || c == '\u2029' {
845 if start < i {
846 e.WriteString(s[start:i])
847 }
848 e.WriteString(`\u202`)
849 e.WriteByte(hex[c&0xF])
850 i += size
851 start = i
852 continue
853 }
854 i += size
855 }
856 if start < len(s) {
857 e.WriteString(s[start:])
858 }
859 e.WriteByte('"')
860 return e.Len() - len0
861 }
862
863
864 func (e *encodeState) stringBytes(s []byte) int {
865 len0 := e.Len()
866 e.WriteByte('"')
867 start := 0
868 for i := 0; i < len(s); {
869 if b := s[i]; b < utf8.RuneSelf {
870 if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
871 i++
872 continue
873 }
874 if start < i {
875 e.Write(s[start:i])
876 }
877 switch b {
878 case '\\', '"':
879 e.WriteByte('\\')
880 e.WriteByte(b)
881 case '\n':
882 e.WriteByte('\\')
883 e.WriteByte('n')
884 case '\r':
885 e.WriteByte('\\')
886 e.WriteByte('r')
887 case '\t':
888 e.WriteByte('\\')
889 e.WriteByte('t')
890 default:
891
892
893
894
895 e.WriteString(`\u00`)
896 e.WriteByte(hex[b>>4])
897 e.WriteByte(hex[b&0xF])
898 }
899 i++
900 start = i
901 continue
902 }
903 c, size := utf8.DecodeRune(s[i:])
904 if c == utf8.RuneError && size == 1 {
905 if start < i {
906 e.Write(s[start:i])
907 }
908 e.WriteString(`\ufffd`)
909 i += size
910 start = i
911 continue
912 }
913
914
915
916
917
918
919
920 if c == '\u2028' || c == '\u2029' {
921 if start < i {
922 e.Write(s[start:i])
923 }
924 e.WriteString(`\u202`)
925 e.WriteByte(hex[c&0xF])
926 i += size
927 start = i
928 continue
929 }
930 i += size
931 }
932 if start < len(s) {
933 e.Write(s[start:])
934 }
935 e.WriteByte('"')
936 return e.Len() - len0
937 }
938
939
940 type field struct {
941 name string
942 nameBytes []byte
943
944 tag bool
945 index []int
946 typ reflect.Type
947 omitEmpty bool
948 quoted bool
949 }
950
951 func fillField(f field) field {
952 f.nameBytes = []byte(f.name)
953 return f
954 }
955
956
957
958
959 type byName []field
960
961 func (x byName) Len() int { return len(x) }
962
963 func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
964
965 func (x byName) Less(i, j int) bool {
966 if x[i].name != x[j].name {
967 return x[i].name < x[j].name
968 }
969 if len(x[i].index) != len(x[j].index) {
970 return len(x[i].index) < len(x[j].index)
971 }
972 if x[i].tag != x[j].tag {
973 return x[i].tag
974 }
975 return byIndex(x).Less(i, j)
976 }
977
978
979 type byIndex []field
980
981 func (x byIndex) Len() int { return len(x) }
982
983 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
984
985 func (x byIndex) Less(i, j int) bool {
986 for k, xik := range x[i].index {
987 if k >= len(x[j].index) {
988 return false
989 }
990 if xik != x[j].index[k] {
991 return xik < x[j].index[k]
992 }
993 }
994 return len(x[i].index) < len(x[j].index)
995 }
996
997
998
999
1000 func typeFields(t reflect.Type) []field {
1001
1002 current := []field{}
1003 next := []field{{typ: t}}
1004
1005
1006 count := map[reflect.Type]int{}
1007 nextCount := map[reflect.Type]int{}
1008
1009
1010 visited := map[reflect.Type]bool{}
1011
1012
1013 var fields []field
1014
1015 for len(next) > 0 {
1016 current, next = next, current[:0]
1017 count, nextCount = nextCount, map[reflect.Type]int{}
1018
1019 for _, f := range current {
1020 if visited[f.typ] {
1021 continue
1022 }
1023 visited[f.typ] = true
1024
1025
1026 for i := 0; i < f.typ.NumField(); i++ {
1027 sf := f.typ.Field(i)
1028 if sf.PkgPath != "" && !sf.Anonymous {
1029 continue
1030 }
1031 tag := sf.Tag.Get("json")
1032 if tag == "-" {
1033 continue
1034 }
1035 name, opts := parseTag(tag)
1036 if !isValidTag(name) {
1037 name = ""
1038 }
1039 index := make([]int, len(f.index)+1)
1040 copy(index, f.index)
1041 index[len(f.index)] = i
1042
1043 ft := sf.Type
1044 if ft.Name() == "" && ft.Kind() == reflect.Ptr {
1045
1046 ft = ft.Elem()
1047 }
1048
1049
1050 quoted := false
1051 if opts.Contains("string") {
1052 switch ft.Kind() {
1053 case reflect.Bool,
1054 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
1055 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
1056 reflect.Float32, reflect.Float64,
1057 reflect.String:
1058 quoted = true
1059 }
1060 }
1061
1062
1063 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
1064 tagged := name != ""
1065 if name == "" {
1066 name = sf.Name
1067 }
1068 fields = append(fields, fillField(field{
1069 name: name,
1070 tag: tagged,
1071 index: index,
1072 typ: ft,
1073 omitEmpty: opts.Contains("omitempty"),
1074 quoted: quoted,
1075 }))
1076 if count[f.typ] > 1 {
1077
1078
1079
1080
1081 fields = append(fields, fields[len(fields)-1])
1082 }
1083 continue
1084 }
1085
1086
1087 nextCount[ft]++
1088 if nextCount[ft] == 1 {
1089 next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))
1090 }
1091 }
1092 }
1093 }
1094
1095 sort.Sort(byName(fields))
1096
1097
1098
1099
1100
1101
1102
1103 out := fields[:0]
1104 for advance, i := 0, 0; i < len(fields); i += advance {
1105
1106
1107 fi := fields[i]
1108 name := fi.name
1109 for advance = 1; i+advance < len(fields); advance++ {
1110 fj := fields[i+advance]
1111 if fj.name != name {
1112 break
1113 }
1114 }
1115 if advance == 1 {
1116 out = append(out, fi)
1117 continue
1118 }
1119 dominant, ok := dominantField(fields[i : i+advance])
1120 if ok {
1121 out = append(out, dominant)
1122 }
1123 }
1124
1125 fields = out
1126 sort.Sort(byIndex(fields))
1127
1128 return fields
1129 }
1130
1131
1132
1133
1134
1135
1136
1137 func dominantField(fields []field) (field, bool) {
1138
1139
1140
1141 length := len(fields[0].index)
1142 tagged := -1
1143 for i, f := range fields {
1144 if len(f.index) > length {
1145 fields = fields[:i]
1146 break
1147 }
1148 if f.tag {
1149 if tagged >= 0 {
1150
1151
1152 return field{}, false
1153 }
1154 tagged = i
1155 }
1156 }
1157 if tagged >= 0 {
1158 return fields[tagged], true
1159 }
1160
1161
1162
1163 if len(fields) > 1 {
1164 return field{}, false
1165 }
1166 return fields[0], true
1167 }
1168
1169 var fieldCache struct {
1170 sync.RWMutex
1171 m map[reflect.Type][]field
1172 }
1173
1174
1175 func cachedTypeFields(t reflect.Type) []field {
1176 fieldCache.RLock()
1177 f := fieldCache.m[t]
1178 fieldCache.RUnlock()
1179 if f != nil {
1180 return f
1181 }
1182
1183
1184
1185 f = typeFields(t)
1186 if f == nil {
1187 f = []field{}
1188 }
1189
1190 fieldCache.Lock()
1191 if fieldCache.m == nil {
1192 fieldCache.m = map[reflect.Type][]field{}
1193 }
1194 fieldCache.m[t] = f
1195 fieldCache.Unlock()
1196 return f
1197 }
1198
View as plain text