github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/encoding/json/encode.go (about) 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. 4 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 12 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" 26 ) 27 28 // Marshal returns the JSON encoding of v. 29 // 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. 39 // 40 // Otherwise, Marshal uses the following type-dependent default encodings: 41 // 42 // Boolean values encode as JSON booleans. 43 // 44 // Floating point, integer, and Number values encode as JSON numbers. 45 // 46 // String values encode as JSON strings coerced to valid UTF-8, 47 // replacing invalid bytes with the Unicode replacement rune. 48 // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" 49 // to keep some browsers from misinterpreting JSON output as HTML. 50 // Ampersand "&" is also escaped to "\u0026" for the same reason. 51 // This escaping can be disabled using an Encoder that had SetEscapeHTML(false) 52 // called on it. 53 // 54 // Array and slice values encode as JSON arrays, except that 55 // []byte encodes as a base64-encoded string, and a nil slice 56 // encodes as the null JSON value. 57 // 58 // Struct values encode as JSON objects. 59 // Each exported struct field becomes a member of the object, using the 60 // field name as the object key, unless the field is omitted for one of the 61 // reasons given below. 62 // 63 // The encoding of each struct field can be customized by the format string 64 // stored under the "json" key in the struct field's tag. 65 // The format string gives the name of the field, possibly followed by a 66 // comma-separated list of options. The name may be empty in order to 67 // specify options without overriding the default field name. 68 // 69 // The "omitempty" option specifies that the field should be omitted 70 // from the encoding if the field has an empty value, defined as 71 // false, 0, a nil pointer, a nil interface value, and any empty array, 72 // slice, map, or string. 73 // 74 // As a special case, if the field tag is "-", the field is always omitted. 75 // Note that a field with name "-" can still be generated using the tag "-,". 76 // 77 // Examples of struct field tags and their meanings: 78 // 79 // // Field appears in JSON as key "myName". 80 // Field int `json:"myName"` 81 // 82 // // Field appears in JSON as key "myName" and 83 // // the field is omitted from the object if its value is empty, 84 // // as defined above. 85 // Field int `json:"myName,omitempty"` 86 // 87 // // Field appears in JSON as key "Field" (the default), but 88 // // the field is skipped if empty. 89 // // Note the leading comma. 90 // Field int `json:",omitempty"` 91 // 92 // // Field is ignored by this package. 93 // Field int `json:"-"` 94 // 95 // // Field appears in JSON as key "-". 96 // Field int `json:"-,"` 97 // 98 // The "string" option signals that a field is stored as JSON inside a 99 // JSON-encoded string. It applies only to fields of string, floating point, 100 // integer, or boolean types. This extra level of encoding is sometimes used 101 // when communicating with JavaScript programs: 102 // 103 // Int64String int64 `json:",string"` 104 // 105 // The key name will be used if it's a non-empty string consisting of 106 // only Unicode letters, digits, and ASCII punctuation except quotation 107 // marks, backslash, and comma. 108 // 109 // Anonymous struct fields are usually marshaled as if their inner exported fields 110 // were fields in the outer struct, subject to the usual Go visibility rules amended 111 // as described in the next paragraph. 112 // An anonymous struct field with a name given in its JSON tag is treated as 113 // having that name, rather than being anonymous. 114 // An anonymous struct field of interface type is treated the same as having 115 // that type as its name, rather than being anonymous. 116 // 117 // The Go visibility rules for struct fields are amended for JSON when 118 // deciding which field to marshal or unmarshal. If there are 119 // multiple fields at the same level, and that level is the least 120 // nested (and would therefore be the nesting level selected by the 121 // usual Go rules), the following extra rules apply: 122 // 123 // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, 124 // even if there are multiple untagged fields that would otherwise conflict. 125 // 126 // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 127 // 128 // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. 129 // 130 // Handling of anonymous struct fields is new in Go 1.1. 131 // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of 132 // an anonymous struct field in both current and earlier versions, give the field 133 // a JSON tag of "-". 134 // 135 // Map values encode as JSON objects. The map's key type must either be a 136 // string, an integer type, or implement encoding.TextMarshaler. The map keys 137 // are sorted and used as JSON object keys by applying the following rules, 138 // subject to the UTF-8 coercion described for string values above: 139 // - string keys are used directly 140 // - encoding.TextMarshalers are marshaled 141 // - integer keys are converted to strings 142 // 143 // Pointer values encode as the value pointed to. 144 // A nil pointer encodes as the null JSON value. 145 // 146 // Interface values encode as the value contained in the interface. 147 // A nil interface value encodes as the null JSON value. 148 // 149 // Channel, complex, and function values cannot be encoded in JSON. 150 // Attempting to encode such a value causes Marshal to return 151 // an UnsupportedTypeError. 152 // 153 // JSON cannot represent cyclic data structures and Marshal does not 154 // handle them. Passing cyclic structures to Marshal will result in 155 // an infinite recursion. 156 // 157 func Marshal(v interface{}) ([]byte, error) { 158 e := newEncodeState() 159 160 err := e.marshal(v, encOpts{escapeHTML: true}) 161 if err != nil { 162 return nil, err 163 } 164 buf := append([]byte(nil), e.Bytes()...) 165 166 e.Reset() 167 encodeStatePool.Put(e) 168 169 return buf, nil 170 } 171 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 interface{}, prefix, indent string) ([]byte, error) { 176 b, err := Marshal(v) 177 if err != nil { 178 return nil, err 179 } 180 var buf bytes.Buffer 181 err = Indent(&buf, b, prefix, indent) 182 if err != nil { 183 return nil, err 184 } 185 return buf.Bytes(), nil 186 } 187 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]) 202 } 203 dst.WriteString(`\u00`) 204 dst.WriteByte(hex[c>>4]) 205 dst.WriteByte(hex[c&0xF]) 206 start = i + 1 207 } 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]) 212 } 213 dst.WriteString(`\u202`) 214 dst.WriteByte(hex[src[i+2]&0xF]) 215 start = i + 3 216 } 217 } 218 if start < len(src) { 219 dst.Write(src[start:]) 220 } 221 } 222 223 // Marshaler is the interface implemented by types that 224 // can marshal themselves into valid JSON. 225 type Marshaler interface { 226 MarshalJSON() ([]byte, error) 227 } 228 229 // An UnsupportedTypeError is returned by Marshal when attempting 230 // to encode an unsupported value type. 231 type UnsupportedTypeError struct { 232 Type reflect.Type 233 } 234 235 func (e *UnsupportedTypeError) Error() string { 236 return "json: unsupported type: " + e.Type.String() 237 } 238 239 type UnsupportedValueError struct { 240 Value reflect.Value 241 Str string 242 } 243 244 func (e *UnsupportedValueError) Error() string { 245 return "json: unsupported value: " + e.Str 246 } 247 248 // Before Go 1.2, an InvalidUTF8Error was returned by Marshal when 249 // attempting to encode a string value with invalid UTF-8 sequences. 250 // As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by 251 // replacing invalid bytes with the Unicode replacement rune U+FFFD. 252 // 253 // Deprecated: No longer used; kept for compatibility. 254 type InvalidUTF8Error struct { 255 S string // the whole string value that caused the error 256 } 257 258 func (e *InvalidUTF8Error) Error() string { 259 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S) 260 } 261 262 type MarshalerError struct { 263 Type reflect.Type 264 Err error 265 } 266 267 func (e *MarshalerError) Error() string { 268 return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error() 269 } 270 271 var hex = "0123456789abcdef" 272 273 // An encodeState encodes JSON into a bytes.Buffer. 274 type encodeState struct { 275 bytes.Buffer // accumulated output 276 scratch [64]byte 277 } 278 279 var encodeStatePool sync.Pool 280 281 func newEncodeState() *encodeState { 282 if v := encodeStatePool.Get(); v != nil { 283 e := v.(*encodeState) 284 e.Reset() 285 return e 286 } 287 return new(encodeState) 288 } 289 290 // jsonError is an error wrapper type for internal use only. 291 // Panics with errors are wrapped in jsonError so that the top-level recover 292 // can distinguish intentional panics from this package. 293 type jsonError struct{ error } 294 295 func (e *encodeState) marshal(v interface{}, opts encOpts) (err error) { 296 defer func() { 297 if r := recover(); r != nil { 298 if je, ok := r.(jsonError); ok { 299 err = je.error 300 } else { 301 panic(r) 302 } 303 } 304 }() 305 e.reflectValue(reflect.ValueOf(v), opts) 306 return nil 307 } 308 309 // error aborts the encoding by panicking with err wrapped in jsonError. 310 func (e *encodeState) error(err error) { 311 panic(jsonError{err}) 312 } 313 314 func isEmptyValue(v reflect.Value) bool { 315 switch v.Kind() { 316 case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 317 return v.Len() == 0 318 case reflect.Bool: 319 return !v.Bool() 320 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 321 return v.Int() == 0 322 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 323 return v.Uint() == 0 324 case reflect.Float32, reflect.Float64: 325 return v.Float() == 0 326 case reflect.Interface, reflect.Ptr: 327 return v.IsNil() 328 } 329 return false 330 } 331 332 func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) { 333 valueEncoder(v)(e, v, opts) 334 } 335 336 type encOpts struct { 337 // quoted causes primitive fields to be encoded inside JSON strings. 338 quoted bool 339 // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings. 340 escapeHTML bool 341 } 342 343 type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts) 344 345 var encoderCache sync.Map // map[reflect.Type]encoderFunc 346 347 func valueEncoder(v reflect.Value) encoderFunc { 348 if !v.IsValid() { 349 return invalidValueEncoder 350 } 351 return typeEncoder(v.Type()) 352 } 353 354 func typeEncoder(t reflect.Type) encoderFunc { 355 if fi, ok := encoderCache.Load(t); ok { 356 return fi.(encoderFunc) 357 } 358 359 // To deal with recursive types, populate the map with an 360 // indirect func before we build it. This type waits on the 361 // real func (f) to be ready and then calls it. This indirect 362 // func is only used for recursive types. 363 var ( 364 wg sync.WaitGroup 365 f encoderFunc 366 ) 367 wg.Add(1) 368 fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) { 369 wg.Wait() 370 f(e, v, opts) 371 })) 372 if loaded { 373 return fi.(encoderFunc) 374 } 375 376 // Compute the real encoder and replace the indirect func with it. 377 f = newTypeEncoder(t, true) 378 wg.Done() 379 encoderCache.Store(t, f) 380 return f 381 } 382 383 var ( 384 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() 385 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 386 ) 387 388 // newTypeEncoder constructs an encoderFunc for a type. 389 // The returned encoder only checks CanAddr when allowAddr is true. 390 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { 391 if t.Implements(marshalerType) { 392 return marshalerEncoder 393 } 394 if t.Kind() != reflect.Ptr && allowAddr { 395 if reflect.PtrTo(t).Implements(marshalerType) { 396 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false)) 397 } 398 } 399 400 if t.Implements(textMarshalerType) { 401 return textMarshalerEncoder 402 } 403 if t.Kind() != reflect.Ptr && allowAddr { 404 if reflect.PtrTo(t).Implements(textMarshalerType) { 405 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false)) 406 } 407 } 408 409 switch t.Kind() { 410 case reflect.Bool: 411 return boolEncoder 412 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 413 return intEncoder 414 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 415 return uintEncoder 416 case reflect.Float32: 417 return float32Encoder 418 case reflect.Float64: 419 return float64Encoder 420 case reflect.String: 421 return stringEncoder 422 case reflect.Interface: 423 return interfaceEncoder 424 case reflect.Struct: 425 return newStructEncoder(t) 426 case reflect.Map: 427 return newMapEncoder(t) 428 case reflect.Slice: 429 return newSliceEncoder(t) 430 case reflect.Array: 431 return newArrayEncoder(t) 432 case reflect.Ptr: 433 return newPtrEncoder(t) 434 default: 435 return unsupportedTypeEncoder 436 } 437 } 438 439 func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) { 440 e.WriteString("null") 441 } 442 443 func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 444 if v.Kind() == reflect.Ptr && v.IsNil() { 445 e.WriteString("null") 446 return 447 } 448 m, ok := v.Interface().(Marshaler) 449 if !ok { 450 e.WriteString("null") 451 return 452 } 453 b, err := m.MarshalJSON() 454 if err == nil { 455 // copy JSON into buffer, checking validity. 456 err = compact(&e.Buffer, b, opts.escapeHTML) 457 } 458 if err != nil { 459 e.error(&MarshalerError{v.Type(), err}) 460 } 461 } 462 463 func addrMarshalerEncoder(e *encodeState, v reflect.Value, _ encOpts) { 464 va := v.Addr() 465 if va.IsNil() { 466 e.WriteString("null") 467 return 468 } 469 m := va.Interface().(Marshaler) 470 b, err := m.MarshalJSON() 471 if err == nil { 472 // copy JSON into buffer, checking validity. 473 err = compact(&e.Buffer, b, true) 474 } 475 if err != nil { 476 e.error(&MarshalerError{v.Type(), err}) 477 } 478 } 479 480 func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 481 if v.Kind() == reflect.Ptr && v.IsNil() { 482 e.WriteString("null") 483 return 484 } 485 m := v.Interface().(encoding.TextMarshaler) 486 b, err := m.MarshalText() 487 if err != nil { 488 e.error(&MarshalerError{v.Type(), err}) 489 } 490 e.stringBytes(b, opts.escapeHTML) 491 } 492 493 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 494 va := v.Addr() 495 if va.IsNil() { 496 e.WriteString("null") 497 return 498 } 499 m := va.Interface().(encoding.TextMarshaler) 500 b, err := m.MarshalText() 501 if err != nil { 502 e.error(&MarshalerError{v.Type(), err}) 503 } 504 e.stringBytes(b, opts.escapeHTML) 505 } 506 507 func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) { 508 if opts.quoted { 509 e.WriteByte('"') 510 } 511 if v.Bool() { 512 e.WriteString("true") 513 } else { 514 e.WriteString("false") 515 } 516 if opts.quoted { 517 e.WriteByte('"') 518 } 519 } 520 521 func intEncoder(e *encodeState, v reflect.Value, opts encOpts) { 522 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10) 523 if opts.quoted { 524 e.WriteByte('"') 525 } 526 e.Write(b) 527 if opts.quoted { 528 e.WriteByte('"') 529 } 530 } 531 532 func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) { 533 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10) 534 if opts.quoted { 535 e.WriteByte('"') 536 } 537 e.Write(b) 538 if opts.quoted { 539 e.WriteByte('"') 540 } 541 } 542 543 type floatEncoder int // number of bits 544 545 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 546 f := v.Float() 547 if math.IsInf(f, 0) || math.IsNaN(f) { 548 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))}) 549 } 550 551 // Convert as if by ES6 number to string conversion. 552 // This matches most other JSON generators. 553 // See golang.org/issue/6384 and golang.org/issue/14135. 554 // Like fmt %g, but the exponent cutoffs are different 555 // and exponents themselves are not padded to two digits. 556 b := e.scratch[:0] 557 abs := math.Abs(f) 558 fmt := byte('f') 559 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. 560 if abs != 0 { 561 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { 562 fmt = 'e' 563 } 564 } 565 b = strconv.AppendFloat(b, f, fmt, -1, int(bits)) 566 if fmt == 'e' { 567 // clean up e-09 to e-9 568 n := len(b) 569 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' { 570 b[n-2] = b[n-1] 571 b = b[:n-1] 572 } 573 } 574 575 if opts.quoted { 576 e.WriteByte('"') 577 } 578 e.Write(b) 579 if opts.quoted { 580 e.WriteByte('"') 581 } 582 } 583 584 var ( 585 float32Encoder = (floatEncoder(32)).encode 586 float64Encoder = (floatEncoder(64)).encode 587 ) 588 589 func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { 590 if v.Type() == numberType { 591 numStr := v.String() 592 // In Go1.5 the empty string encodes to "0", while this is not a valid number literal 593 // we keep compatibility so check validity after this. 594 if numStr == "" { 595 numStr = "0" // Number's zero-val 596 } 597 if !isValidNumber(numStr) { 598 e.error(fmt.Errorf("json: invalid number literal %q", numStr)) 599 } 600 e.WriteString(numStr) 601 return 602 } 603 if opts.quoted { 604 sb, err := Marshal(v.String()) 605 if err != nil { 606 e.error(err) 607 } 608 e.string(string(sb), opts.escapeHTML) 609 } else { 610 e.string(v.String(), opts.escapeHTML) 611 } 612 } 613 614 func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) { 615 if v.IsNil() { 616 e.WriteString("null") 617 return 618 } 619 e.reflectValue(v.Elem(), opts) 620 } 621 622 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) { 623 e.error(&UnsupportedTypeError{v.Type()}) 624 } 625 626 type structEncoder struct { 627 fields []field 628 } 629 630 func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 631 next := byte('{') 632 FieldLoop: 633 for i := range se.fields { 634 f := &se.fields[i] 635 636 // Find the nested struct field by following f.index. 637 fv := v 638 for _, i := range f.index { 639 if fv.Kind() == reflect.Ptr { 640 if fv.IsNil() { 641 continue FieldLoop 642 } 643 fv = fv.Elem() 644 } 645 fv = fv.Field(i) 646 } 647 648 if f.omitEmpty && isEmptyValue(fv) { 649 continue 650 } 651 e.WriteByte(next) 652 next = ',' 653 if opts.escapeHTML { 654 e.WriteString(f.nameEscHTML) 655 } else { 656 e.WriteString(f.nameNonEsc) 657 } 658 opts.quoted = f.quoted 659 f.encoder(e, fv, opts) 660 } 661 if next == '{' { 662 e.WriteString("{}") 663 } else { 664 e.WriteByte('}') 665 } 666 } 667 668 func newStructEncoder(t reflect.Type) encoderFunc { 669 se := structEncoder{fields: cachedTypeFields(t)} 670 return se.encode 671 } 672 673 type mapEncoder struct { 674 elemEnc encoderFunc 675 } 676 677 func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 678 if v.IsNil() { 679 e.WriteString("null") 680 return 681 } 682 e.WriteByte('{') 683 684 // Extract and sort the keys. 685 keys := v.MapKeys() 686 sv := make([]reflectWithString, len(keys)) 687 for i, v := range keys { 688 sv[i].v = v 689 if err := sv[i].resolve(); err != nil { 690 e.error(&MarshalerError{v.Type(), err}) 691 } 692 } 693 sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s }) 694 695 for i, kv := range sv { 696 if i > 0 { 697 e.WriteByte(',') 698 } 699 e.string(kv.s, opts.escapeHTML) 700 e.WriteByte(':') 701 me.elemEnc(e, v.MapIndex(kv.v), opts) 702 } 703 e.WriteByte('}') 704 } 705 706 func newMapEncoder(t reflect.Type) encoderFunc { 707 switch t.Key().Kind() { 708 case reflect.String, 709 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 710 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 711 default: 712 if !t.Key().Implements(textMarshalerType) { 713 return unsupportedTypeEncoder 714 } 715 } 716 me := mapEncoder{typeEncoder(t.Elem())} 717 return me.encode 718 } 719 720 func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) { 721 if v.IsNil() { 722 e.WriteString("null") 723 return 724 } 725 s := v.Bytes() 726 e.WriteByte('"') 727 encodedLen := base64.StdEncoding.EncodedLen(len(s)) 728 if encodedLen <= len(e.scratch) { 729 // If the encoded bytes fit in e.scratch, avoid an extra 730 // allocation and use the cheaper Encoding.Encode. 731 dst := e.scratch[:encodedLen] 732 base64.StdEncoding.Encode(dst, s) 733 e.Write(dst) 734 } else if encodedLen <= 1024 { 735 // The encoded bytes are short enough to allocate for, and 736 // Encoding.Encode is still cheaper. 737 dst := make([]byte, encodedLen) 738 base64.StdEncoding.Encode(dst, s) 739 e.Write(dst) 740 } else { 741 // The encoded bytes are too long to cheaply allocate, and 742 // Encoding.Encode is no longer noticeably cheaper. 743 enc := base64.NewEncoder(base64.StdEncoding, e) 744 enc.Write(s) 745 enc.Close() 746 } 747 e.WriteByte('"') 748 } 749 750 // sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil. 751 type sliceEncoder struct { 752 arrayEnc encoderFunc 753 } 754 755 func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 756 if v.IsNil() { 757 e.WriteString("null") 758 return 759 } 760 se.arrayEnc(e, v, opts) 761 } 762 763 func newSliceEncoder(t reflect.Type) encoderFunc { 764 // Byte slices get special treatment; arrays don't. 765 if t.Elem().Kind() == reflect.Uint8 { 766 p := reflect.PtrTo(t.Elem()) 767 if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) { 768 return encodeByteSlice 769 } 770 } 771 enc := sliceEncoder{newArrayEncoder(t)} 772 return enc.encode 773 } 774 775 type arrayEncoder struct { 776 elemEnc encoderFunc 777 } 778 779 func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 780 e.WriteByte('[') 781 n := v.Len() 782 for i := 0; i < n; i++ { 783 if i > 0 { 784 e.WriteByte(',') 785 } 786 ae.elemEnc(e, v.Index(i), opts) 787 } 788 e.WriteByte(']') 789 } 790 791 func newArrayEncoder(t reflect.Type) encoderFunc { 792 enc := arrayEncoder{typeEncoder(t.Elem())} 793 return enc.encode 794 } 795 796 type ptrEncoder struct { 797 elemEnc encoderFunc 798 } 799 800 func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 801 if v.IsNil() { 802 e.WriteString("null") 803 return 804 } 805 pe.elemEnc(e, v.Elem(), opts) 806 } 807 808 func newPtrEncoder(t reflect.Type) encoderFunc { 809 enc := ptrEncoder{typeEncoder(t.Elem())} 810 return enc.encode 811 } 812 813 type condAddrEncoder struct { 814 canAddrEnc, elseEnc encoderFunc 815 } 816 817 func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 818 if v.CanAddr() { 819 ce.canAddrEnc(e, v, opts) 820 } else { 821 ce.elseEnc(e, v, opts) 822 } 823 } 824 825 // newCondAddrEncoder returns an encoder that checks whether its value 826 // CanAddr and delegates to canAddrEnc if so, else to elseEnc. 827 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc { 828 enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc} 829 return enc.encode 830 } 831 832 func isValidTag(s string) bool { 833 if s == "" { 834 return false 835 } 836 for _, c := range s { 837 switch { 838 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): 839 // Backslash and quote chars are reserved, but 840 // otherwise any punctuation chars are allowed 841 // in a tag name. 842 case !unicode.IsLetter(c) && !unicode.IsDigit(c): 843 return false 844 } 845 } 846 return true 847 } 848 849 func typeByIndex(t reflect.Type, index []int) reflect.Type { 850 for _, i := range index { 851 if t.Kind() == reflect.Ptr { 852 t = t.Elem() 853 } 854 t = t.Field(i).Type 855 } 856 return t 857 } 858 859 type reflectWithString struct { 860 v reflect.Value 861 s string 862 } 863 864 func (w *reflectWithString) resolve() error { 865 if w.v.Kind() == reflect.String { 866 w.s = w.v.String() 867 return nil 868 } 869 if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok { 870 buf, err := tm.MarshalText() 871 w.s = string(buf) 872 return err 873 } 874 switch w.v.Kind() { 875 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 876 w.s = strconv.FormatInt(w.v.Int(), 10) 877 return nil 878 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 879 w.s = strconv.FormatUint(w.v.Uint(), 10) 880 return nil 881 } 882 panic("unexpected map key type") 883 } 884 885 // NOTE: keep in sync with stringBytes below. 886 func (e *encodeState) string(s string, escapeHTML bool) { 887 e.WriteByte('"') 888 start := 0 889 for i := 0; i < len(s); { 890 if b := s[i]; b < utf8.RuneSelf { 891 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 892 i++ 893 continue 894 } 895 if start < i { 896 e.WriteString(s[start:i]) 897 } 898 e.WriteByte('\\') 899 switch b { 900 case '\\', '"': 901 e.WriteByte(b) 902 case '\n': 903 e.WriteByte('n') 904 case '\r': 905 e.WriteByte('r') 906 case '\t': 907 e.WriteByte('t') 908 default: 909 // This encodes bytes < 0x20 except for \t, \n and \r. 910 // If escapeHTML is set, it also escapes <, >, and & 911 // because they can lead to security holes when 912 // user-controlled strings are rendered into JSON 913 // and served to some browsers. 914 e.WriteString(`u00`) 915 e.WriteByte(hex[b>>4]) 916 e.WriteByte(hex[b&0xF]) 917 } 918 i++ 919 start = i 920 continue 921 } 922 c, size := utf8.DecodeRuneInString(s[i:]) 923 if c == utf8.RuneError && size == 1 { 924 if start < i { 925 e.WriteString(s[start:i]) 926 } 927 e.WriteString(`\ufffd`) 928 i += size 929 start = i 930 continue 931 } 932 // U+2028 is LINE SEPARATOR. 933 // U+2029 is PARAGRAPH SEPARATOR. 934 // They are both technically valid characters in JSON strings, 935 // but don't work in JSONP, which has to be evaluated as JavaScript, 936 // and can lead to security holes there. It is valid JSON to 937 // escape them, so we do so unconditionally. 938 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 939 if c == '\u2028' || c == '\u2029' { 940 if start < i { 941 e.WriteString(s[start:i]) 942 } 943 e.WriteString(`\u202`) 944 e.WriteByte(hex[c&0xF]) 945 i += size 946 start = i 947 continue 948 } 949 i += size 950 } 951 if start < len(s) { 952 e.WriteString(s[start:]) 953 } 954 e.WriteByte('"') 955 } 956 957 // NOTE: keep in sync with string above. 958 func (e *encodeState) stringBytes(s []byte, escapeHTML bool) { 959 e.WriteByte('"') 960 start := 0 961 for i := 0; i < len(s); { 962 if b := s[i]; b < utf8.RuneSelf { 963 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 964 i++ 965 continue 966 } 967 if start < i { 968 e.Write(s[start:i]) 969 } 970 e.WriteByte('\\') 971 switch b { 972 case '\\', '"': 973 e.WriteByte(b) 974 case '\n': 975 e.WriteByte('n') 976 case '\r': 977 e.WriteByte('r') 978 case '\t': 979 e.WriteByte('t') 980 default: 981 // This encodes bytes < 0x20 except for \t, \n and \r. 982 // If escapeHTML is set, it also escapes <, >, and & 983 // because they can lead to security holes when 984 // user-controlled strings are rendered into JSON 985 // and served to some browsers. 986 e.WriteString(`u00`) 987 e.WriteByte(hex[b>>4]) 988 e.WriteByte(hex[b&0xF]) 989 } 990 i++ 991 start = i 992 continue 993 } 994 c, size := utf8.DecodeRune(s[i:]) 995 if c == utf8.RuneError && size == 1 { 996 if start < i { 997 e.Write(s[start:i]) 998 } 999 e.WriteString(`\ufffd`) 1000 i += size 1001 start = i 1002 continue 1003 } 1004 // U+2028 is LINE SEPARATOR. 1005 // U+2029 is PARAGRAPH SEPARATOR. 1006 // They are both technically valid characters in JSON strings, 1007 // but don't work in JSONP, which has to be evaluated as JavaScript, 1008 // and can lead to security holes there. It is valid JSON to 1009 // escape them, so we do so unconditionally. 1010 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 1011 if c == '\u2028' || c == '\u2029' { 1012 if start < i { 1013 e.Write(s[start:i]) 1014 } 1015 e.WriteString(`\u202`) 1016 e.WriteByte(hex[c&0xF]) 1017 i += size 1018 start = i 1019 continue 1020 } 1021 i += size 1022 } 1023 if start < len(s) { 1024 e.Write(s[start:]) 1025 } 1026 e.WriteByte('"') 1027 } 1028 1029 // A field represents a single field found in a struct. 1030 type field struct { 1031 name string 1032 nameBytes []byte // []byte(name) 1033 equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent 1034 1035 nameNonEsc string // `"` + name + `":` 1036 nameEscHTML string // `"` + HTMLEscape(name) + `":` 1037 1038 tag bool 1039 index []int 1040 typ reflect.Type 1041 omitEmpty bool 1042 quoted bool 1043 1044 encoder encoderFunc 1045 } 1046 1047 // byIndex sorts field by index sequence. 1048 type byIndex []field 1049 1050 func (x byIndex) Len() int { return len(x) } 1051 1052 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 1053 1054 func (x byIndex) Less(i, j int) bool { 1055 for k, xik := range x[i].index { 1056 if k >= len(x[j].index) { 1057 return false 1058 } 1059 if xik != x[j].index[k] { 1060 return xik < x[j].index[k] 1061 } 1062 } 1063 return len(x[i].index) < len(x[j].index) 1064 } 1065 1066 // typeFields returns a list of fields that JSON should recognize for the given type. 1067 // The algorithm is breadth-first search over the set of structs to include - the top struct 1068 // and then any reachable anonymous structs. 1069 func typeFields(t reflect.Type) []field { 1070 // Anonymous fields to explore at the current level and the next. 1071 current := []field{} 1072 next := []field{{typ: t}} 1073 1074 // Count of queued names for current level and the next. 1075 count := map[reflect.Type]int{} 1076 nextCount := map[reflect.Type]int{} 1077 1078 // Types already visited at an earlier level. 1079 visited := map[reflect.Type]bool{} 1080 1081 // Fields found. 1082 var fields []field 1083 1084 // Buffer to run HTMLEscape on field names. 1085 var nameEscBuf bytes.Buffer 1086 1087 for len(next) > 0 { 1088 current, next = next, current[:0] 1089 count, nextCount = nextCount, map[reflect.Type]int{} 1090 1091 for _, f := range current { 1092 if visited[f.typ] { 1093 continue 1094 } 1095 visited[f.typ] = true 1096 1097 // Scan f.typ for fields to include. 1098 for i := 0; i < f.typ.NumField(); i++ { 1099 sf := f.typ.Field(i) 1100 isUnexported := sf.PkgPath != "" 1101 if sf.Anonymous { 1102 t := sf.Type 1103 if t.Kind() == reflect.Ptr { 1104 t = t.Elem() 1105 } 1106 if isUnexported && t.Kind() != reflect.Struct { 1107 // Ignore embedded fields of unexported non-struct types. 1108 continue 1109 } 1110 // Do not ignore embedded fields of unexported struct types 1111 // since they may have exported fields. 1112 } else if isUnexported { 1113 // Ignore unexported non-embedded fields. 1114 continue 1115 } 1116 tag := sf.Tag.Get("json") 1117 if tag == "-" { 1118 continue 1119 } 1120 name, opts := parseTag(tag) 1121 if !isValidTag(name) { 1122 name = "" 1123 } 1124 index := make([]int, len(f.index)+1) 1125 copy(index, f.index) 1126 index[len(f.index)] = i 1127 1128 ft := sf.Type 1129 if ft.Name() == "" && ft.Kind() == reflect.Ptr { 1130 // Follow pointer. 1131 ft = ft.Elem() 1132 } 1133 1134 // Only strings, floats, integers, and booleans can be quoted. 1135 quoted := false 1136 if opts.Contains("string") { 1137 switch ft.Kind() { 1138 case reflect.Bool, 1139 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 1140 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 1141 reflect.Float32, reflect.Float64, 1142 reflect.String: 1143 quoted = true 1144 } 1145 } 1146 1147 // Record found field and index sequence. 1148 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { 1149 tagged := name != "" 1150 if name == "" { 1151 name = sf.Name 1152 } 1153 field := field{ 1154 name: name, 1155 tag: tagged, 1156 index: index, 1157 typ: ft, 1158 omitEmpty: opts.Contains("omitempty"), 1159 quoted: quoted, 1160 } 1161 field.nameBytes = []byte(field.name) 1162 field.equalFold = foldFunc(field.nameBytes) 1163 1164 // Build nameEscHTML and nameNonEsc ahead of time. 1165 nameEscBuf.Reset() 1166 nameEscBuf.WriteString(`"`) 1167 HTMLEscape(&nameEscBuf, field.nameBytes) 1168 nameEscBuf.WriteString(`":`) 1169 field.nameEscHTML = nameEscBuf.String() 1170 field.nameNonEsc = `"` + field.name + `":` 1171 1172 fields = append(fields, field) 1173 if count[f.typ] > 1 { 1174 // If there were multiple instances, add a second, 1175 // so that the annihilation code will see a duplicate. 1176 // It only cares about the distinction between 1 or 2, 1177 // so don't bother generating any more copies. 1178 fields = append(fields, fields[len(fields)-1]) 1179 } 1180 continue 1181 } 1182 1183 // Record new anonymous struct to explore in next round. 1184 nextCount[ft]++ 1185 if nextCount[ft] == 1 { 1186 next = append(next, field{name: ft.Name(), index: index, typ: ft}) 1187 } 1188 } 1189 } 1190 } 1191 1192 sort.Slice(fields, func(i, j int) bool { 1193 x := fields 1194 // sort field by name, breaking ties with depth, then 1195 // breaking ties with "name came from json tag", then 1196 // breaking ties with index sequence. 1197 if x[i].name != x[j].name { 1198 return x[i].name < x[j].name 1199 } 1200 if len(x[i].index) != len(x[j].index) { 1201 return len(x[i].index) < len(x[j].index) 1202 } 1203 if x[i].tag != x[j].tag { 1204 return x[i].tag 1205 } 1206 return byIndex(x).Less(i, j) 1207 }) 1208 1209 // Delete all fields that are hidden by the Go rules for embedded fields, 1210 // except that fields with JSON tags are promoted. 1211 1212 // The fields are sorted in primary order of name, secondary order 1213 // of field index length. Loop over names; for each name, delete 1214 // hidden fields by choosing the one dominant field that survives. 1215 out := fields[:0] 1216 for advance, i := 0, 0; i < len(fields); i += advance { 1217 // One iteration per name. 1218 // Find the sequence of fields with the name of this first field. 1219 fi := fields[i] 1220 name := fi.name 1221 for advance = 1; i+advance < len(fields); advance++ { 1222 fj := fields[i+advance] 1223 if fj.name != name { 1224 break 1225 } 1226 } 1227 if advance == 1 { // Only one field with this name 1228 out = append(out, fi) 1229 continue 1230 } 1231 dominant, ok := dominantField(fields[i : i+advance]) 1232 if ok { 1233 out = append(out, dominant) 1234 } 1235 } 1236 1237 fields = out 1238 sort.Sort(byIndex(fields)) 1239 1240 for i := range fields { 1241 f := &fields[i] 1242 f.encoder = typeEncoder(typeByIndex(t, f.index)) 1243 } 1244 return fields 1245 } 1246 1247 // dominantField looks through the fields, all of which are known to 1248 // have the same name, to find the single field that dominates the 1249 // others using Go's embedding rules, modified by the presence of 1250 // JSON tags. If there are multiple top-level fields, the boolean 1251 // will be false: This condition is an error in Go and we skip all 1252 // the fields. 1253 func dominantField(fields []field) (field, bool) { 1254 // The fields are sorted in increasing index-length order, then by presence of tag. 1255 // That means that the first field is the dominant one. We need only check 1256 // for error cases: two fields at top level, either both tagged or neither tagged. 1257 if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag { 1258 return field{}, false 1259 } 1260 return fields[0], true 1261 } 1262 1263 var fieldCache sync.Map // map[reflect.Type][]field 1264 1265 // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. 1266 func cachedTypeFields(t reflect.Type) []field { 1267 if f, ok := fieldCache.Load(t); ok { 1268 return f.([]field) 1269 } 1270 f, _ := fieldCache.LoadOrStore(t, typeFields(t)) 1271 return f.([]field) 1272 }