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