[PR rtl-optimization/115877][2/n] Improve liveness computation for constant initializ...
[official-gcc.git] / libgo / go / encoding / json / encode.go
blob1f5e3e446a9c9c2d92f21edfd5e84f2cea8e88fb
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package json implements encoding and decoding of JSON as defined in
6 // RFC 7159. The mapping between JSON and Go values is described
7 // in the documentation for the Marshal and Unmarshal functions.
8 //
9 // See "JSON and Go" for an introduction to this package:
10 // https://golang.org/doc/articles/json_and_go.html
11 package json
13 import (
14 "bytes"
15 "encoding"
16 "encoding/base64"
17 "fmt"
18 "math"
19 "reflect"
20 "sort"
21 "strconv"
22 "strings"
23 "sync"
24 "unicode"
25 "unicode/utf8"
28 // Marshal returns the JSON encoding of v.
30 // Marshal traverses the value v recursively.
31 // If an encountered value implements the Marshaler interface
32 // and is not a nil pointer, Marshal calls its MarshalJSON method
33 // to produce JSON. If no MarshalJSON method is present but the
34 // value implements encoding.TextMarshaler instead, Marshal calls
35 // its MarshalText method and encodes the result as a JSON string.
36 // The nil pointer exception is not strictly necessary
37 // but mimics a similar, necessary exception in the behavior of
38 // UnmarshalJSON.
40 // Otherwise, Marshal uses the following type-dependent default encodings:
42 // Boolean values encode as JSON booleans.
44 // Floating point, integer, and Number values encode as JSON numbers.
46 // String values encode as JSON strings coerced to valid UTF-8,
47 // replacing invalid bytes with the Unicode replacement rune.
48 // So that the JSON will be safe to embed inside HTML <script> tags,
49 // the string is encoded using HTMLEscape,
50 // which replaces "<", ">", "&", U+2028, and U+2029 are escaped
51 // to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029".
52 // This replacement can be disabled when using an Encoder,
53 // by calling SetEscapeHTML(false).
55 // Array and slice values encode as JSON arrays, except that
56 // []byte encodes as a base64-encoded string, and a nil slice
57 // encodes as the null JSON value.
59 // Struct values encode as JSON objects.
60 // Each exported struct field becomes a member of the object, using the
61 // field name as the object key, unless the field is omitted for one of the
62 // reasons given below.
64 // The encoding of each struct field can be customized by the format string
65 // stored under the "json" key in the struct field's tag.
66 // The format string gives the name of the field, possibly followed by a
67 // comma-separated list of options. The name may be empty in order to
68 // specify options without overriding the default field name.
70 // The "omitempty" option specifies that the field should be omitted
71 // from the encoding if the field has an empty value, defined as
72 // false, 0, a nil pointer, a nil interface value, and any empty array,
73 // slice, map, or string.
75 // As a special case, if the field tag is "-", the field is always omitted.
76 // Note that a field with name "-" can still be generated using the tag "-,".
78 // Examples of struct field tags and their meanings:
80 // // Field appears in JSON as key "myName".
81 // Field int `json:"myName"`
83 // // Field appears in JSON as key "myName" and
84 // // the field is omitted from the object if its value is empty,
85 // // as defined above.
86 // Field int `json:"myName,omitempty"`
88 // // Field appears in JSON as key "Field" (the default), but
89 // // the field is skipped if empty.
90 // // Note the leading comma.
91 // Field int `json:",omitempty"`
93 // // Field is ignored by this package.
94 // Field int `json:"-"`
96 // // Field appears in JSON as key "-".
97 // Field int `json:"-,"`
99 // The "string" option signals that a field is stored as JSON inside a
100 // JSON-encoded string. It applies only to fields of string, floating point,
101 // integer, or boolean types. This extra level of encoding is sometimes used
102 // when communicating with JavaScript programs:
104 // Int64String int64 `json:",string"`
106 // The key name will be used if it's a non-empty string consisting of
107 // only Unicode letters, digits, and ASCII punctuation except quotation
108 // marks, backslash, and comma.
110 // Anonymous struct fields are usually marshaled as if their inner exported fields
111 // were fields in the outer struct, subject to the usual Go visibility rules amended
112 // as described in the next paragraph.
113 // An anonymous struct field with a name given in its JSON tag is treated as
114 // having that name, rather than being anonymous.
115 // An anonymous struct field of interface type is treated the same as having
116 // that type as its name, rather than being anonymous.
118 // The Go visibility rules for struct fields are amended for JSON when
119 // deciding which field to marshal or unmarshal. If there are
120 // multiple fields at the same level, and that level is the least
121 // nested (and would therefore be the nesting level selected by the
122 // usual Go rules), the following extra rules apply:
124 // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
125 // even if there are multiple untagged fields that would otherwise conflict.
127 // 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
129 // 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
131 // Handling of anonymous struct fields is new in Go 1.1.
132 // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
133 // an anonymous struct field in both current and earlier versions, give the field
134 // a JSON tag of "-".
136 // Map values encode as JSON objects. The map's key type must either be a
137 // string, an integer type, or implement encoding.TextMarshaler. The map keys
138 // are sorted and used as JSON object keys by applying the following rules,
139 // subject to the UTF-8 coercion described for string values above:
140 // - keys of any string type are used directly
141 // - encoding.TextMarshalers are marshaled
142 // - integer keys are converted to strings
144 // Pointer values encode as the value pointed to.
145 // A nil pointer encodes as the null JSON value.
147 // Interface values encode as the value contained in the interface.
148 // A nil interface value encodes as the null JSON value.
150 // Channel, complex, and function values cannot be encoded in JSON.
151 // Attempting to encode such a value causes Marshal to return
152 // an UnsupportedTypeError.
154 // JSON cannot represent cyclic data structures and Marshal does not
155 // handle them. Passing cyclic structures to Marshal will result in
156 // an error.
158 func Marshal(v any) ([]byte, error) {
159 e := newEncodeState()
161 err := e.marshal(v, encOpts{escapeHTML: true})
162 if err != nil {
163 return nil, err
165 buf := append([]byte(nil), e.Bytes()...)
167 encodeStatePool.Put(e)
169 return buf, nil
172 // MarshalIndent is like Marshal but applies Indent to format the output.
173 // Each JSON element in the output will begin on a new line beginning with prefix
174 // followed by one or more copies of indent according to the indentation nesting.
175 func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
176 b, err := Marshal(v)
177 if err != nil {
178 return nil, err
180 var buf bytes.Buffer
181 err = Indent(&buf, b, prefix, indent)
182 if err != nil {
183 return nil, err
185 return buf.Bytes(), nil
188 // HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
189 // characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
190 // so that the JSON will be safe to embed inside HTML <script> tags.
191 // For historical reasons, web browsers don't honor standard HTML
192 // escaping within <script> tags, so an alternative JSON encoding must
193 // be used.
194 func HTMLEscape(dst *bytes.Buffer, src []byte) {
195 // The characters can only appear in string literals,
196 // so just scan the string one byte at a time.
197 start := 0
198 for i, c := range src {
199 if c == '<' || c == '>' || c == '&' {
200 if start < i {
201 dst.Write(src[start:i])
203 dst.WriteString(`\u00`)
204 dst.WriteByte(hex[c>>4])
205 dst.WriteByte(hex[c&0xF])
206 start = i + 1
208 // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
209 if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
210 if start < i {
211 dst.Write(src[start:i])
213 dst.WriteString(`\u202`)
214 dst.WriteByte(hex[src[i+2]&0xF])
215 start = i + 3
218 if start < len(src) {
219 dst.Write(src[start:])
223 // Marshaler is the interface implemented by types that
224 // can marshal themselves into valid JSON.
225 type Marshaler interface {
226 MarshalJSON() ([]byte, error)
229 // An UnsupportedTypeError is returned by Marshal when attempting
230 // to encode an unsupported value type.
231 type UnsupportedTypeError struct {
232 Type reflect.Type
235 func (e *UnsupportedTypeError) Error() string {
236 return "json: unsupported type: " + e.Type.String()
239 // An UnsupportedValueError is returned by Marshal when attempting
240 // to encode an unsupported value.
241 type UnsupportedValueError struct {
242 Value reflect.Value
243 Str string
246 func (e *UnsupportedValueError) Error() string {
247 return "json: unsupported value: " + e.Str
250 // Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
251 // attempting to encode a string value with invalid UTF-8 sequences.
252 // As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by
253 // replacing invalid bytes with the Unicode replacement rune U+FFFD.
255 // Deprecated: No longer used; kept for compatibility.
256 type InvalidUTF8Error struct {
257 S string // the whole string value that caused the error
260 func (e *InvalidUTF8Error) Error() string {
261 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
264 // A MarshalerError represents an error from calling a MarshalJSON or MarshalText method.
265 type MarshalerError struct {
266 Type reflect.Type
267 Err error
268 sourceFunc string
271 func (e *MarshalerError) Error() string {
272 srcFunc := e.sourceFunc
273 if srcFunc == "" {
274 srcFunc = "MarshalJSON"
276 return "json: error calling " + srcFunc +
277 " for type " + e.Type.String() +
278 ": " + e.Err.Error()
281 // Unwrap returns the underlying error.
282 func (e *MarshalerError) Unwrap() error { return e.Err }
284 var hex = "0123456789abcdef"
286 // An encodeState encodes JSON into a bytes.Buffer.
287 type encodeState struct {
288 bytes.Buffer // accumulated output
289 scratch [64]byte
291 // Keep track of what pointers we've seen in the current recursive call
292 // path, to avoid cycles that could lead to a stack overflow. Only do
293 // the relatively expensive map operations if ptrLevel is larger than
294 // startDetectingCyclesAfter, so that we skip the work if we're within a
295 // reasonable amount of nested pointers deep.
296 ptrLevel uint
297 ptrSeen map[any]struct{}
300 const startDetectingCyclesAfter = 1000
302 var encodeStatePool sync.Pool
304 func newEncodeState() *encodeState {
305 if v := encodeStatePool.Get(); v != nil {
306 e := v.(*encodeState)
307 e.Reset()
308 if len(e.ptrSeen) > 0 {
309 panic("ptrEncoder.encode should have emptied ptrSeen via defers")
311 e.ptrLevel = 0
312 return e
314 return &encodeState{ptrSeen: make(map[any]struct{})}
317 // jsonError is an error wrapper type for internal use only.
318 // Panics with errors are wrapped in jsonError so that the top-level recover
319 // can distinguish intentional panics from this package.
320 type jsonError struct{ error }
322 func (e *encodeState) marshal(v any, opts encOpts) (err error) {
323 defer func() {
324 if r := recover(); r != nil {
325 if je, ok := r.(jsonError); ok {
326 err = je.error
327 } else {
328 panic(r)
332 e.reflectValue(reflect.ValueOf(v), opts)
333 return nil
336 // error aborts the encoding by panicking with err wrapped in jsonError.
337 func (e *encodeState) error(err error) {
338 panic(jsonError{err})
341 func isEmptyValue(v reflect.Value) bool {
342 switch v.Kind() {
343 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
344 return v.Len() == 0
345 case reflect.Bool:
346 return !v.Bool()
347 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
348 return v.Int() == 0
349 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
350 return v.Uint() == 0
351 case reflect.Float32, reflect.Float64:
352 return v.Float() == 0
353 case reflect.Interface, reflect.Pointer:
354 return v.IsNil()
356 return false
359 func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) {
360 valueEncoder(v)(e, v, opts)
363 type encOpts struct {
364 // quoted causes primitive fields to be encoded inside JSON strings.
365 quoted bool
366 // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings.
367 escapeHTML bool
370 type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
372 var encoderCache sync.Map // map[reflect.Type]encoderFunc
374 func valueEncoder(v reflect.Value) encoderFunc {
375 if !v.IsValid() {
376 return invalidValueEncoder
378 return typeEncoder(v.Type())
381 func typeEncoder(t reflect.Type) encoderFunc {
382 if fi, ok := encoderCache.Load(t); ok {
383 return fi.(encoderFunc)
386 // To deal with recursive types, populate the map with an
387 // indirect func before we build it. This type waits on the
388 // real func (f) to be ready and then calls it. This indirect
389 // func is only used for recursive types.
390 var (
391 wg sync.WaitGroup
392 f encoderFunc
394 wg.Add(1)
395 fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) {
396 wg.Wait()
397 f(e, v, opts)
399 if loaded {
400 return fi.(encoderFunc)
403 // Compute the real encoder and replace the indirect func with it.
404 f = newTypeEncoder(t, true)
405 wg.Done()
406 encoderCache.Store(t, f)
407 return f
410 var (
411 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
412 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
415 // newTypeEncoder constructs an encoderFunc for a type.
416 // The returned encoder only checks CanAddr when allowAddr is true.
417 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
418 // If we have a non-pointer value whose type implements
419 // Marshaler with a value receiver, then we're better off taking
420 // the address of the value - otherwise we end up with an
421 // allocation as we cast the value to an interface.
422 if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) {
423 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
425 if t.Implements(marshalerType) {
426 return marshalerEncoder
428 if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) {
429 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
431 if t.Implements(textMarshalerType) {
432 return textMarshalerEncoder
435 switch t.Kind() {
436 case reflect.Bool:
437 return boolEncoder
438 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
439 return intEncoder
440 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
441 return uintEncoder
442 case reflect.Float32:
443 return float32Encoder
444 case reflect.Float64:
445 return float64Encoder
446 case reflect.String:
447 return stringEncoder
448 case reflect.Interface:
449 return interfaceEncoder
450 case reflect.Struct:
451 return newStructEncoder(t)
452 case reflect.Map:
453 return newMapEncoder(t)
454 case reflect.Slice:
455 return newSliceEncoder(t)
456 case reflect.Array:
457 return newArrayEncoder(t)
458 case reflect.Pointer:
459 return newPtrEncoder(t)
460 default:
461 return unsupportedTypeEncoder
465 func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
466 e.WriteString("null")
469 func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
470 if v.Kind() == reflect.Pointer && v.IsNil() {
471 e.WriteString("null")
472 return
474 m, ok := v.Interface().(Marshaler)
475 if !ok {
476 e.WriteString("null")
477 return
479 b, err := m.MarshalJSON()
480 if err == nil {
481 // copy JSON into buffer, checking validity.
482 err = compact(&e.Buffer, b, opts.escapeHTML)
484 if err != nil {
485 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
489 func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
490 va := v.Addr()
491 if va.IsNil() {
492 e.WriteString("null")
493 return
495 m := va.Interface().(Marshaler)
496 b, err := m.MarshalJSON()
497 if err == nil {
498 // copy JSON into buffer, checking validity.
499 err = compact(&e.Buffer, b, opts.escapeHTML)
501 if err != nil {
502 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
506 func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
507 if v.Kind() == reflect.Pointer && v.IsNil() {
508 e.WriteString("null")
509 return
511 m, ok := v.Interface().(encoding.TextMarshaler)
512 if !ok {
513 e.WriteString("null")
514 return
516 b, err := m.MarshalText()
517 if err != nil {
518 e.error(&MarshalerError{v.Type(), err, "MarshalText"})
520 e.stringBytes(b, opts.escapeHTML)
523 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
524 va := v.Addr()
525 if va.IsNil() {
526 e.WriteString("null")
527 return
529 m := va.Interface().(encoding.TextMarshaler)
530 b, err := m.MarshalText()
531 if err != nil {
532 e.error(&MarshalerError{v.Type(), err, "MarshalText"})
534 e.stringBytes(b, opts.escapeHTML)
537 func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) {
538 if opts.quoted {
539 e.WriteByte('"')
541 if v.Bool() {
542 e.WriteString("true")
543 } else {
544 e.WriteString("false")
546 if opts.quoted {
547 e.WriteByte('"')
551 func intEncoder(e *encodeState, v reflect.Value, opts encOpts) {
552 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
553 if opts.quoted {
554 e.WriteByte('"')
556 e.Write(b)
557 if opts.quoted {
558 e.WriteByte('"')
562 func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) {
563 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
564 if opts.quoted {
565 e.WriteByte('"')
567 e.Write(b)
568 if opts.quoted {
569 e.WriteByte('"')
573 type floatEncoder int // number of bits
575 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
576 f := v.Float()
577 if math.IsInf(f, 0) || math.IsNaN(f) {
578 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
581 // Convert as if by ES6 number to string conversion.
582 // This matches most other JSON generators.
583 // See golang.org/issue/6384 and golang.org/issue/14135.
584 // Like fmt %g, but the exponent cutoffs are different
585 // and exponents themselves are not padded to two digits.
586 b := e.scratch[:0]
587 abs := math.Abs(f)
588 fmt := byte('f')
589 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
590 if abs != 0 {
591 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
592 fmt = 'e'
595 b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
596 if fmt == 'e' {
597 // clean up e-09 to e-9
598 n := len(b)
599 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
600 b[n-2] = b[n-1]
601 b = b[:n-1]
605 if opts.quoted {
606 e.WriteByte('"')
608 e.Write(b)
609 if opts.quoted {
610 e.WriteByte('"')
614 var (
615 float32Encoder = (floatEncoder(32)).encode
616 float64Encoder = (floatEncoder(64)).encode
619 func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
620 if v.Type() == numberType {
621 numStr := v.String()
622 // In Go1.5 the empty string encodes to "0", while this is not a valid number literal
623 // we keep compatibility so check validity after this.
624 if numStr == "" {
625 numStr = "0" // Number's zero-val
627 if !isValidNumber(numStr) {
628 e.error(fmt.Errorf("json: invalid number literal %q", numStr))
630 if opts.quoted {
631 e.WriteByte('"')
633 e.WriteString(numStr)
634 if opts.quoted {
635 e.WriteByte('"')
637 return
639 if opts.quoted {
640 e2 := newEncodeState()
641 // Since we encode the string twice, we only need to escape HTML
642 // the first time.
643 e2.string(v.String(), opts.escapeHTML)
644 e.stringBytes(e2.Bytes(), false)
645 encodeStatePool.Put(e2)
646 } else {
647 e.string(v.String(), opts.escapeHTML)
651 // isValidNumber reports whether s is a valid JSON number literal.
652 func isValidNumber(s string) bool {
653 // This function implements the JSON numbers grammar.
654 // See https://tools.ietf.org/html/rfc7159#section-6
655 // and https://www.json.org/img/number.png
657 if s == "" {
658 return false
661 // Optional -
662 if s[0] == '-' {
663 s = s[1:]
664 if s == "" {
665 return false
669 // Digits
670 switch {
671 default:
672 return false
674 case s[0] == '0':
675 s = s[1:]
677 case '1' <= s[0] && s[0] <= '9':
678 s = s[1:]
679 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
680 s = s[1:]
684 // . followed by 1 or more digits.
685 if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
686 s = s[2:]
687 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
688 s = s[1:]
692 // e or E followed by an optional - or + and
693 // 1 or more digits.
694 if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
695 s = s[1:]
696 if s[0] == '+' || s[0] == '-' {
697 s = s[1:]
698 if s == "" {
699 return false
702 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
703 s = s[1:]
707 // Make sure we are at the end.
708 return s == ""
711 func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {
712 if v.IsNil() {
713 e.WriteString("null")
714 return
716 e.reflectValue(v.Elem(), opts)
719 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) {
720 e.error(&UnsupportedTypeError{v.Type()})
723 type structEncoder struct {
724 fields structFields
727 type structFields struct {
728 list []field
729 nameIndex map[string]int
732 func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
733 next := byte('{')
734 FieldLoop:
735 for i := range se.fields.list {
736 f := &se.fields.list[i]
738 // Find the nested struct field by following f.index.
739 fv := v
740 for _, i := range f.index {
741 if fv.Kind() == reflect.Pointer {
742 if fv.IsNil() {
743 continue FieldLoop
745 fv = fv.Elem()
747 fv = fv.Field(i)
750 if f.omitEmpty && isEmptyValue(fv) {
751 continue
753 e.WriteByte(next)
754 next = ','
755 if opts.escapeHTML {
756 e.WriteString(f.nameEscHTML)
757 } else {
758 e.WriteString(f.nameNonEsc)
760 opts.quoted = f.quoted
761 f.encoder(e, fv, opts)
763 if next == '{' {
764 e.WriteString("{}")
765 } else {
766 e.WriteByte('}')
770 func newStructEncoder(t reflect.Type) encoderFunc {
771 se := structEncoder{fields: cachedTypeFields(t)}
772 return se.encode
775 type mapEncoder struct {
776 elemEnc encoderFunc
779 func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
780 if v.IsNil() {
781 e.WriteString("null")
782 return
784 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
785 // We're a large number of nested ptrEncoder.encode calls deep;
786 // start checking if we've run into a pointer cycle.
787 ptr := v.Pointer()
788 if _, ok := e.ptrSeen[ptr]; ok {
789 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
791 e.ptrSeen[ptr] = struct{}{}
792 defer delete(e.ptrSeen, ptr)
794 e.WriteByte('{')
796 // Extract and sort the keys.
797 sv := make([]reflectWithString, v.Len())
798 mi := v.MapRange()
799 for i := 0; mi.Next(); i++ {
800 sv[i].k = mi.Key()
801 sv[i].v = mi.Value()
802 if err := sv[i].resolve(); err != nil {
803 e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
806 sort.Slice(sv, func(i, j int) bool { return sv[i].ks < sv[j].ks })
808 for i, kv := range sv {
809 if i > 0 {
810 e.WriteByte(',')
812 e.string(kv.ks, opts.escapeHTML)
813 e.WriteByte(':')
814 me.elemEnc(e, kv.v, opts)
816 e.WriteByte('}')
817 e.ptrLevel--
820 func newMapEncoder(t reflect.Type) encoderFunc {
821 switch t.Key().Kind() {
822 case reflect.String,
823 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
824 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
825 default:
826 if !t.Key().Implements(textMarshalerType) {
827 return unsupportedTypeEncoder
830 me := mapEncoder{typeEncoder(t.Elem())}
831 return me.encode
834 func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) {
835 if v.IsNil() {
836 e.WriteString("null")
837 return
839 s := v.Bytes()
840 e.WriteByte('"')
841 encodedLen := base64.StdEncoding.EncodedLen(len(s))
842 if encodedLen <= len(e.scratch) {
843 // If the encoded bytes fit in e.scratch, avoid an extra
844 // allocation and use the cheaper Encoding.Encode.
845 dst := e.scratch[:encodedLen]
846 base64.StdEncoding.Encode(dst, s)
847 e.Write(dst)
848 } else if encodedLen <= 1024 {
849 // The encoded bytes are short enough to allocate for, and
850 // Encoding.Encode is still cheaper.
851 dst := make([]byte, encodedLen)
852 base64.StdEncoding.Encode(dst, s)
853 e.Write(dst)
854 } else {
855 // The encoded bytes are too long to cheaply allocate, and
856 // Encoding.Encode is no longer noticeably cheaper.
857 enc := base64.NewEncoder(base64.StdEncoding, e)
858 enc.Write(s)
859 enc.Close()
861 e.WriteByte('"')
864 // sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil.
865 type sliceEncoder struct {
866 arrayEnc encoderFunc
869 func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
870 if v.IsNil() {
871 e.WriteString("null")
872 return
874 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
875 // We're a large number of nested ptrEncoder.encode calls deep;
876 // start checking if we've run into a pointer cycle.
877 // Here we use a struct to memorize the pointer to the first element of the slice
878 // and its length.
879 ptr := struct {
880 ptr uintptr
881 len int
882 }{v.Pointer(), v.Len()}
883 if _, ok := e.ptrSeen[ptr]; ok {
884 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
886 e.ptrSeen[ptr] = struct{}{}
887 defer delete(e.ptrSeen, ptr)
889 se.arrayEnc(e, v, opts)
890 e.ptrLevel--
893 func newSliceEncoder(t reflect.Type) encoderFunc {
894 // Byte slices get special treatment; arrays don't.
895 if t.Elem().Kind() == reflect.Uint8 {
896 p := reflect.PointerTo(t.Elem())
897 if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
898 return encodeByteSlice
901 enc := sliceEncoder{newArrayEncoder(t)}
902 return enc.encode
905 type arrayEncoder struct {
906 elemEnc encoderFunc
909 func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
910 e.WriteByte('[')
911 n := v.Len()
912 for i := 0; i < n; i++ {
913 if i > 0 {
914 e.WriteByte(',')
916 ae.elemEnc(e, v.Index(i), opts)
918 e.WriteByte(']')
921 func newArrayEncoder(t reflect.Type) encoderFunc {
922 enc := arrayEncoder{typeEncoder(t.Elem())}
923 return enc.encode
926 type ptrEncoder struct {
927 elemEnc encoderFunc
930 func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
931 if v.IsNil() {
932 e.WriteString("null")
933 return
935 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
936 // We're a large number of nested ptrEncoder.encode calls deep;
937 // start checking if we've run into a pointer cycle.
938 ptr := v.Interface()
939 if _, ok := e.ptrSeen[ptr]; ok {
940 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
942 e.ptrSeen[ptr] = struct{}{}
943 defer delete(e.ptrSeen, ptr)
945 pe.elemEnc(e, v.Elem(), opts)
946 e.ptrLevel--
949 func newPtrEncoder(t reflect.Type) encoderFunc {
950 enc := ptrEncoder{typeEncoder(t.Elem())}
951 return enc.encode
954 type condAddrEncoder struct {
955 canAddrEnc, elseEnc encoderFunc
958 func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
959 if v.CanAddr() {
960 ce.canAddrEnc(e, v, opts)
961 } else {
962 ce.elseEnc(e, v, opts)
966 // newCondAddrEncoder returns an encoder that checks whether its value
967 // CanAddr and delegates to canAddrEnc if so, else to elseEnc.
968 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
969 enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
970 return enc.encode
973 func isValidTag(s string) bool {
974 if s == "" {
975 return false
977 for _, c := range s {
978 switch {
979 case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
980 // Backslash and quote chars are reserved, but
981 // otherwise any punctuation chars are allowed
982 // in a tag name.
983 case !unicode.IsLetter(c) && !unicode.IsDigit(c):
984 return false
987 return true
990 func typeByIndex(t reflect.Type, index []int) reflect.Type {
991 for _, i := range index {
992 if t.Kind() == reflect.Pointer {
993 t = t.Elem()
995 t = t.Field(i).Type
997 return t
1000 type reflectWithString struct {
1001 k reflect.Value
1002 v reflect.Value
1003 ks string
1006 func (w *reflectWithString) resolve() error {
1007 if w.k.Kind() == reflect.String {
1008 w.ks = w.k.String()
1009 return nil
1011 if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok {
1012 if w.k.Kind() == reflect.Pointer && w.k.IsNil() {
1013 return nil
1015 buf, err := tm.MarshalText()
1016 w.ks = string(buf)
1017 return err
1019 switch w.k.Kind() {
1020 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1021 w.ks = strconv.FormatInt(w.k.Int(), 10)
1022 return nil
1023 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1024 w.ks = strconv.FormatUint(w.k.Uint(), 10)
1025 return nil
1027 panic("unexpected map key type")
1030 // NOTE: keep in sync with stringBytes below.
1031 func (e *encodeState) string(s string, escapeHTML bool) {
1032 e.WriteByte('"')
1033 start := 0
1034 for i := 0; i < len(s); {
1035 if b := s[i]; b < utf8.RuneSelf {
1036 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
1038 continue
1040 if start < i {
1041 e.WriteString(s[start:i])
1043 e.WriteByte('\\')
1044 switch b {
1045 case '\\', '"':
1046 e.WriteByte(b)
1047 case '\n':
1048 e.WriteByte('n')
1049 case '\r':
1050 e.WriteByte('r')
1051 case '\t':
1052 e.WriteByte('t')
1053 default:
1054 // This encodes bytes < 0x20 except for \t, \n and \r.
1055 // If escapeHTML is set, it also escapes <, >, and &
1056 // because they can lead to security holes when
1057 // user-controlled strings are rendered into JSON
1058 // and served to some browsers.
1059 e.WriteString(`u00`)
1060 e.WriteByte(hex[b>>4])
1061 e.WriteByte(hex[b&0xF])
1064 start = i
1065 continue
1067 c, size := utf8.DecodeRuneInString(s[i:])
1068 if c == utf8.RuneError && size == 1 {
1069 if start < i {
1070 e.WriteString(s[start:i])
1072 e.WriteString(`\ufffd`)
1073 i += size
1074 start = i
1075 continue
1077 // U+2028 is LINE SEPARATOR.
1078 // U+2029 is PARAGRAPH SEPARATOR.
1079 // They are both technically valid characters in JSON strings,
1080 // but don't work in JSONP, which has to be evaluated as JavaScript,
1081 // and can lead to security holes there. It is valid JSON to
1082 // escape them, so we do so unconditionally.
1083 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
1084 if c == '\u2028' || c == '\u2029' {
1085 if start < i {
1086 e.WriteString(s[start:i])
1088 e.WriteString(`\u202`)
1089 e.WriteByte(hex[c&0xF])
1090 i += size
1091 start = i
1092 continue
1094 i += size
1096 if start < len(s) {
1097 e.WriteString(s[start:])
1099 e.WriteByte('"')
1102 // NOTE: keep in sync with string above.
1103 func (e *encodeState) stringBytes(s []byte, escapeHTML bool) {
1104 e.WriteByte('"')
1105 start := 0
1106 for i := 0; i < len(s); {
1107 if b := s[i]; b < utf8.RuneSelf {
1108 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
1110 continue
1112 if start < i {
1113 e.Write(s[start:i])
1115 e.WriteByte('\\')
1116 switch b {
1117 case '\\', '"':
1118 e.WriteByte(b)
1119 case '\n':
1120 e.WriteByte('n')
1121 case '\r':
1122 e.WriteByte('r')
1123 case '\t':
1124 e.WriteByte('t')
1125 default:
1126 // This encodes bytes < 0x20 except for \t, \n and \r.
1127 // If escapeHTML is set, it also escapes <, >, and &
1128 // because they can lead to security holes when
1129 // user-controlled strings are rendered into JSON
1130 // and served to some browsers.
1131 e.WriteString(`u00`)
1132 e.WriteByte(hex[b>>4])
1133 e.WriteByte(hex[b&0xF])
1136 start = i
1137 continue
1139 c, size := utf8.DecodeRune(s[i:])
1140 if c == utf8.RuneError && size == 1 {
1141 if start < i {
1142 e.Write(s[start:i])
1144 e.WriteString(`\ufffd`)
1145 i += size
1146 start = i
1147 continue
1149 // U+2028 is LINE SEPARATOR.
1150 // U+2029 is PARAGRAPH SEPARATOR.
1151 // They are both technically valid characters in JSON strings,
1152 // but don't work in JSONP, which has to be evaluated as JavaScript,
1153 // and can lead to security holes there. It is valid JSON to
1154 // escape them, so we do so unconditionally.
1155 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
1156 if c == '\u2028' || c == '\u2029' {
1157 if start < i {
1158 e.Write(s[start:i])
1160 e.WriteString(`\u202`)
1161 e.WriteByte(hex[c&0xF])
1162 i += size
1163 start = i
1164 continue
1166 i += size
1168 if start < len(s) {
1169 e.Write(s[start:])
1171 e.WriteByte('"')
1174 // A field represents a single field found in a struct.
1175 type field struct {
1176 name string
1177 nameBytes []byte // []byte(name)
1178 equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
1180 nameNonEsc string // `"` + name + `":`
1181 nameEscHTML string // `"` + HTMLEscape(name) + `":`
1183 tag bool
1184 index []int
1185 typ reflect.Type
1186 omitEmpty bool
1187 quoted bool
1189 encoder encoderFunc
1192 // byIndex sorts field by index sequence.
1193 type byIndex []field
1195 func (x byIndex) Len() int { return len(x) }
1197 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
1199 func (x byIndex) Less(i, j int) bool {
1200 for k, xik := range x[i].index {
1201 if k >= len(x[j].index) {
1202 return false
1204 if xik != x[j].index[k] {
1205 return xik < x[j].index[k]
1208 return len(x[i].index) < len(x[j].index)
1211 // typeFields returns a list of fields that JSON should recognize for the given type.
1212 // The algorithm is breadth-first search over the set of structs to include - the top struct
1213 // and then any reachable anonymous structs.
1214 func typeFields(t reflect.Type) structFields {
1215 // Anonymous fields to explore at the current level and the next.
1216 current := []field{}
1217 next := []field{{typ: t}}
1219 // Count of queued names for current level and the next.
1220 var count, nextCount map[reflect.Type]int
1222 // Types already visited at an earlier level.
1223 visited := map[reflect.Type]bool{}
1225 // Fields found.
1226 var fields []field
1228 // Buffer to run HTMLEscape on field names.
1229 var nameEscBuf bytes.Buffer
1231 for len(next) > 0 {
1232 current, next = next, current[:0]
1233 count, nextCount = nextCount, map[reflect.Type]int{}
1235 for _, f := range current {
1236 if visited[f.typ] {
1237 continue
1239 visited[f.typ] = true
1241 // Scan f.typ for fields to include.
1242 for i := 0; i < f.typ.NumField(); i++ {
1243 sf := f.typ.Field(i)
1244 if sf.Anonymous {
1245 t := sf.Type
1246 if t.Kind() == reflect.Pointer {
1247 t = t.Elem()
1249 if !sf.IsExported() && t.Kind() != reflect.Struct {
1250 // Ignore embedded fields of unexported non-struct types.
1251 continue
1253 // Do not ignore embedded fields of unexported struct types
1254 // since they may have exported fields.
1255 } else if !sf.IsExported() {
1256 // Ignore unexported non-embedded fields.
1257 continue
1259 tag := sf.Tag.Get("json")
1260 if tag == "-" {
1261 continue
1263 name, opts := parseTag(tag)
1264 if !isValidTag(name) {
1265 name = ""
1267 index := make([]int, len(f.index)+1)
1268 copy(index, f.index)
1269 index[len(f.index)] = i
1271 ft := sf.Type
1272 if ft.Name() == "" && ft.Kind() == reflect.Pointer {
1273 // Follow pointer.
1274 ft = ft.Elem()
1277 // Only strings, floats, integers, and booleans can be quoted.
1278 quoted := false
1279 if opts.Contains("string") {
1280 switch ft.Kind() {
1281 case reflect.Bool,
1282 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
1283 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
1284 reflect.Float32, reflect.Float64,
1285 reflect.String:
1286 quoted = true
1290 // Record found field and index sequence.
1291 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
1292 tagged := name != ""
1293 if name == "" {
1294 name = sf.Name
1296 field := field{
1297 name: name,
1298 tag: tagged,
1299 index: index,
1300 typ: ft,
1301 omitEmpty: opts.Contains("omitempty"),
1302 quoted: quoted,
1304 field.nameBytes = []byte(field.name)
1305 field.equalFold = foldFunc(field.nameBytes)
1307 // Build nameEscHTML and nameNonEsc ahead of time.
1308 nameEscBuf.Reset()
1309 nameEscBuf.WriteString(`"`)
1310 HTMLEscape(&nameEscBuf, field.nameBytes)
1311 nameEscBuf.WriteString(`":`)
1312 field.nameEscHTML = nameEscBuf.String()
1313 field.nameNonEsc = `"` + field.name + `":`
1315 fields = append(fields, field)
1316 if count[f.typ] > 1 {
1317 // If there were multiple instances, add a second,
1318 // so that the annihilation code will see a duplicate.
1319 // It only cares about the distinction between 1 or 2,
1320 // so don't bother generating any more copies.
1321 fields = append(fields, fields[len(fields)-1])
1323 continue
1326 // Record new anonymous struct to explore in next round.
1327 nextCount[ft]++
1328 if nextCount[ft] == 1 {
1329 next = append(next, field{name: ft.Name(), index: index, typ: ft})
1335 sort.Slice(fields, func(i, j int) bool {
1336 x := fields
1337 // sort field by name, breaking ties with depth, then
1338 // breaking ties with "name came from json tag", then
1339 // breaking ties with index sequence.
1340 if x[i].name != x[j].name {
1341 return x[i].name < x[j].name
1343 if len(x[i].index) != len(x[j].index) {
1344 return len(x[i].index) < len(x[j].index)
1346 if x[i].tag != x[j].tag {
1347 return x[i].tag
1349 return byIndex(x).Less(i, j)
1352 // Delete all fields that are hidden by the Go rules for embedded fields,
1353 // except that fields with JSON tags are promoted.
1355 // The fields are sorted in primary order of name, secondary order
1356 // of field index length. Loop over names; for each name, delete
1357 // hidden fields by choosing the one dominant field that survives.
1358 out := fields[:0]
1359 for advance, i := 0, 0; i < len(fields); i += advance {
1360 // One iteration per name.
1361 // Find the sequence of fields with the name of this first field.
1362 fi := fields[i]
1363 name := fi.name
1364 for advance = 1; i+advance < len(fields); advance++ {
1365 fj := fields[i+advance]
1366 if fj.name != name {
1367 break
1370 if advance == 1 { // Only one field with this name
1371 out = append(out, fi)
1372 continue
1374 dominant, ok := dominantField(fields[i : i+advance])
1375 if ok {
1376 out = append(out, dominant)
1380 fields = out
1381 sort.Sort(byIndex(fields))
1383 for i := range fields {
1384 f := &fields[i]
1385 f.encoder = typeEncoder(typeByIndex(t, f.index))
1387 nameIndex := make(map[string]int, len(fields))
1388 for i, field := range fields {
1389 nameIndex[field.name] = i
1391 return structFields{fields, nameIndex}
1394 // dominantField looks through the fields, all of which are known to
1395 // have the same name, to find the single field that dominates the
1396 // others using Go's embedding rules, modified by the presence of
1397 // JSON tags. If there are multiple top-level fields, the boolean
1398 // will be false: This condition is an error in Go and we skip all
1399 // the fields.
1400 func dominantField(fields []field) (field, bool) {
1401 // The fields are sorted in increasing index-length order, then by presence of tag.
1402 // That means that the first field is the dominant one. We need only check
1403 // for error cases: two fields at top level, either both tagged or neither tagged.
1404 if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
1405 return field{}, false
1407 return fields[0], true
1410 var fieldCache sync.Map // map[reflect.Type]structFields
1412 // cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
1413 func cachedTypeFields(t reflect.Type) structFields {
1414 if f, ok := fieldCache.Load(t); ok {
1415 return f.(structFields)
1417 f, _ := fieldCache.LoadOrStore(t, typeFields(t))
1418 return f.(structFields)