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