github.com/vmware/govmomi@v0.37.1/vim25/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 // 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). 54 // 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. 58 // 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. 63 // 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. 69 // 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. 74 // 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 "-,". 77 // 78 // Examples of struct field tags and their meanings: 79 // 80 // // Field appears in JSON as key "myName". 81 // Field int `json:"myName"` 82 // 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"` 87 // 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"` 92 // 93 // // Field is ignored by this package. 94 // Field int `json:"-"` 95 // 96 // // Field appears in JSON as key "-". 97 // Field int `json:"-,"` 98 // 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: 103 // 104 // Int64String int64 `json:",string"` 105 // 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. 109 // 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. 117 // 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: 123 // 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. 126 // 127 // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 128 // 129 // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. 130 // 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 "-". 135 // 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 143 // 144 // Pointer values encode as the value pointed to. 145 // A nil pointer encodes as the null JSON value. 146 // 147 // Interface values encode as the value contained in the interface. 148 // A nil interface value encodes as the null JSON value. 149 // 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. 153 // 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. 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 encodeStatePool.Put(e) 167 168 return buf, nil 169 } 170 171 // MarshalIndent is like Marshal but applies Indent to format the output. 172 // Each JSON element in the output will begin on a new line beginning with prefix 173 // followed by one or more copies of indent according to the indentation nesting. 174 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { 175 b, err := Marshal(v) 176 if err != nil { 177 return nil, err 178 } 179 var buf bytes.Buffer 180 err = Indent(&buf, b, prefix, indent) 181 if err != nil { 182 return nil, err 183 } 184 return buf.Bytes(), nil 185 } 186 187 // HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 188 // characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 189 // so that the JSON will be safe to embed inside HTML <script> tags. 190 // For historical reasons, web browsers don't honor standard HTML 191 // escaping within <script> tags, so an alternative JSON encoding must 192 // be used. 193 func HTMLEscape(dst *bytes.Buffer, src []byte) { 194 // The characters can only appear in string literals, 195 // so just scan the string one byte at a time. 196 start := 0 197 for i, c := range src { 198 if c == '<' || c == '>' || c == '&' { 199 if start < i { 200 dst.Write(src[start:i]) 201 } 202 dst.WriteString(`\u00`) 203 dst.WriteByte(hex[c>>4]) 204 dst.WriteByte(hex[c&0xF]) 205 start = i + 1 206 } 207 // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9). 208 if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 { 209 if start < i { 210 dst.Write(src[start:i]) 211 } 212 dst.WriteString(`\u202`) 213 dst.WriteByte(hex[src[i+2]&0xF]) 214 start = i + 3 215 } 216 } 217 if start < len(src) { 218 dst.Write(src[start:]) 219 } 220 } 221 222 // Marshaler is the interface implemented by types that 223 // can marshal themselves into valid JSON. 224 type Marshaler interface { 225 MarshalJSON() ([]byte, error) 226 } 227 228 // An UnsupportedTypeError is returned by Marshal when attempting 229 // to encode an unsupported value type. 230 type UnsupportedTypeError struct { 231 Type reflect.Type 232 } 233 234 func (e *UnsupportedTypeError) Error() string { 235 return "json: unsupported type: " + e.Type.String() 236 } 237 238 // An UnsupportedValueError is returned by Marshal when attempting 239 // to encode an unsupported value. 240 type UnsupportedValueError struct { 241 Value reflect.Value 242 Str string 243 } 244 245 func (e *UnsupportedValueError) Error() string { 246 return "json: unsupported value: " + e.Str 247 } 248 249 // Before Go 1.2, an InvalidUTF8Error was returned by Marshal when 250 // attempting to encode a string value with invalid UTF-8 sequences. 251 // As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by 252 // replacing invalid bytes with the Unicode replacement rune U+FFFD. 253 // 254 // Deprecated: No longer used; kept for compatibility. 255 type InvalidUTF8Error struct { 256 S string // the whole string value that caused the error 257 } 258 259 func (e *InvalidUTF8Error) Error() string { 260 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S) 261 } 262 263 // A MarshalerError represents an error from calling a MarshalJSON or MarshalText method. 264 type MarshalerError struct { 265 Type reflect.Type 266 Err error 267 sourceFunc string 268 } 269 270 func (e *MarshalerError) Error() string { 271 srcFunc := e.sourceFunc 272 if srcFunc == "" { 273 srcFunc = "MarshalJSON" 274 } 275 return "json: error calling " + srcFunc + 276 " for type " + e.Type.String() + 277 ": " + e.Err.Error() 278 } 279 280 // Unwrap returns the underlying error. 281 func (e *MarshalerError) Unwrap() error { return e.Err } 282 283 var hex = "0123456789abcdef" 284 285 // An encodeState encodes JSON into a bytes.Buffer. 286 type encodeState struct { 287 bytes.Buffer // accumulated output 288 scratch [64]byte 289 290 // Keep track of what pointers we've seen in the current recursive call 291 // path, to avoid cycles that could lead to a stack overflow. Only do 292 // the relatively expensive map operations if ptrLevel is larger than 293 // startDetectingCyclesAfter, so that we skip the work if we're within a 294 // reasonable amount of nested pointers deep. 295 ptrLevel uint 296 ptrSeen map[interface{}]struct{} 297 298 // discriminatorEncodeTypeName is set to true when the type name should 299 // be encoded along with a map or struct value. The flag is flipped back 300 // to false as soon as the type name is encoded to prevent impacting 301 // subsequent values. 302 discriminatorEncodeTypeName bool 303 } 304 305 const startDetectingCyclesAfter = 1000 306 307 var encodeStatePool sync.Pool 308 309 func newEncodeState() *encodeState { 310 if v := encodeStatePool.Get(); v != nil { 311 e := v.(*encodeState) 312 e.Reset() 313 if len(e.ptrSeen) > 0 { 314 panic("ptrEncoder.encode should have emptied ptrSeen via defers") 315 } 316 e.ptrLevel = 0 317 e.discriminatorEncodeTypeName = false 318 return e 319 } 320 return &encodeState{ptrSeen: make(map[interface{}]struct{})} 321 } 322 323 // jsonError is an error wrapper type for internal use only. 324 // Panics with errors are wrapped in jsonError so that the top-level recover 325 // can distinguish intentional panics from this package. 326 type jsonError struct{ error } 327 328 var interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() 329 330 func (e *encodeState) marshal(v interface{}, opts encOpts) (err error) { 331 defer func() { 332 if r := recover(); r != nil { 333 if je, ok := r.(jsonError); ok { 334 err = je.error 335 } else { 336 panic(r) 337 } 338 } 339 }() 340 341 val := reflect.ValueOf(v) 342 if val.IsValid() && opts.isDiscriminatorSet() && opts.discriminatorEncodeMode.root() { 343 val = val.Convert(interfaceType) 344 } 345 e.reflectValue(val, opts) 346 347 return nil 348 } 349 350 // error aborts the encoding by panicking with err wrapped in jsonError. 351 func (e *encodeState) error(err error) { 352 panic(jsonError{err}) 353 } 354 355 func isEmptyValue(v reflect.Value) bool { 356 switch v.Kind() { 357 case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 358 return v.Len() == 0 359 case reflect.Bool: 360 return !v.Bool() 361 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 362 return v.Int() == 0 363 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 364 return v.Uint() == 0 365 case reflect.Float32, reflect.Float64: 366 return v.Float() == 0 367 case reflect.Interface, reflect.Ptr: 368 return v.IsNil() 369 } 370 return false 371 } 372 373 func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) { 374 valueEncoder(v)(e, v, opts) 375 } 376 377 type encOpts struct { 378 // quoted causes primitive fields to be encoded inside JSON strings. 379 quoted bool 380 // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings. 381 escapeHTML bool 382 // see Encoder.SetDiscriminator 383 discriminatorTypeFieldName string 384 // see Encoder.SetDiscriminator 385 discriminatorValueFieldName string 386 // see Encoder.SetDiscriminator 387 discriminatorValueFn TypeToDiscriminatorFunc 388 // see Encoder.SetDiscriminator 389 discriminatorEncodeMode DiscriminatorEncodeMode 390 } 391 392 type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts) 393 394 var encoderCache sync.Map // map[reflect.Type]encoderFunc 395 396 func valueEncoder(v reflect.Value) encoderFunc { 397 if !v.IsValid() { 398 return invalidValueEncoder 399 } 400 return typeEncoder(v.Type()) 401 } 402 403 func typeEncoder(t reflect.Type) encoderFunc { 404 if fi, ok := encoderCache.Load(t); ok { 405 return fi.(encoderFunc) 406 } 407 408 // To deal with recursive types, populate the map with an 409 // indirect func before we build it. This type waits on the 410 // real func (f) to be ready and then calls it. This indirect 411 // func is only used for recursive types. 412 var ( 413 wg sync.WaitGroup 414 f encoderFunc 415 ) 416 wg.Add(1) 417 fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) { 418 wg.Wait() 419 f(e, v, opts) 420 })) 421 if loaded { 422 return fi.(encoderFunc) 423 } 424 425 // Compute the real encoder and replace the indirect func with it. 426 f = newTypeEncoder(t, true) 427 wg.Done() 428 encoderCache.Store(t, f) 429 return f 430 } 431 432 var ( 433 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() 434 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 435 ) 436 437 // newTypeEncoder constructs an encoderFunc for a type. 438 // The returned encoder only checks CanAddr when allowAddr is true. 439 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { 440 // If we have a non-pointer value whose type implements 441 // Marshaler with a value receiver, then we're better off taking 442 // the address of the value - otherwise we end up with an 443 // allocation as we cast the value to an interface. 444 if t.Kind() != reflect.Ptr && allowAddr && reflect.PtrTo(t).Implements(marshalerType) { 445 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false)) 446 } 447 if t.Implements(marshalerType) { 448 return marshalerEncoder 449 } 450 if t.Kind() != reflect.Ptr && allowAddr && reflect.PtrTo(t).Implements(textMarshalerType) { 451 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false)) 452 } 453 if t.Implements(textMarshalerType) { 454 return textMarshalerEncoder 455 } 456 457 switch t.Kind() { 458 case reflect.Bool: 459 return boolEncoder 460 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 461 return intEncoder 462 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 463 return uintEncoder 464 case reflect.Float32: 465 return float32Encoder 466 case reflect.Float64: 467 return float64Encoder 468 case reflect.String: 469 return stringEncoder 470 case reflect.Interface: 471 return interfaceEncoder 472 case reflect.Struct: 473 return newStructEncoder(t) 474 case reflect.Map: 475 return newMapEncoder(t) 476 case reflect.Slice: 477 return newSliceEncoder(t) 478 case reflect.Array: 479 return newArrayEncoder(t) 480 case reflect.Ptr: 481 return newPtrEncoder(t) 482 default: 483 return unsupportedTypeEncoder 484 } 485 } 486 487 func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) { 488 e.WriteString("null") 489 } 490 491 func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 492 if v.Kind() == reflect.Ptr && v.IsNil() { 493 e.WriteString("null") 494 return 495 } 496 m, ok := v.Interface().(Marshaler) 497 if !ok { 498 e.WriteString("null") 499 return 500 } 501 b, err := m.MarshalJSON() 502 if err == nil { 503 // copy JSON into buffer, checking validity. 504 err = compact(&e.Buffer, b, opts.escapeHTML) 505 } 506 if err != nil { 507 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"}) 508 } 509 } 510 511 func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 512 va := v.Addr() 513 if va.IsNil() { 514 e.WriteString("null") 515 return 516 } 517 m := va.Interface().(Marshaler) 518 b, err := m.MarshalJSON() 519 if err == nil { 520 // copy JSON into buffer, checking validity. 521 err = compact(&e.Buffer, b, opts.escapeHTML) 522 } 523 if err != nil { 524 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"}) 525 } 526 } 527 528 func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 529 if v.Kind() == reflect.Ptr && v.IsNil() { 530 e.WriteString("null") 531 return 532 } 533 m, ok := v.Interface().(encoding.TextMarshaler) 534 if !ok { 535 e.WriteString("null") 536 return 537 } 538 b, err := m.MarshalText() 539 if err != nil { 540 e.error(&MarshalerError{v.Type(), err, "MarshalText"}) 541 } 542 e.stringBytes(b, opts.escapeHTML) 543 } 544 545 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 546 va := v.Addr() 547 if va.IsNil() { 548 e.WriteString("null") 549 return 550 } 551 m := va.Interface().(encoding.TextMarshaler) 552 b, err := m.MarshalText() 553 if err != nil { 554 e.error(&MarshalerError{v.Type(), err, "MarshalText"}) 555 } 556 e.stringBytes(b, opts.escapeHTML) 557 } 558 559 func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) { 560 if opts.quoted { 561 e.WriteByte('"') 562 } 563 if v.Bool() { 564 e.WriteString("true") 565 } else { 566 e.WriteString("false") 567 } 568 if opts.quoted { 569 e.WriteByte('"') 570 } 571 } 572 573 func intEncoder(e *encodeState, v reflect.Value, opts encOpts) { 574 b := strconv.AppendInt(e.scratch[:0], v.Int(), 10) 575 if opts.quoted { 576 e.WriteByte('"') 577 } 578 e.Write(b) 579 if opts.quoted { 580 e.WriteByte('"') 581 } 582 } 583 584 func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) { 585 b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10) 586 if opts.quoted { 587 e.WriteByte('"') 588 } 589 e.Write(b) 590 if opts.quoted { 591 e.WriteByte('"') 592 } 593 } 594 595 type floatEncoder int // number of bits 596 597 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 598 f := v.Float() 599 if math.IsInf(f, 0) || math.IsNaN(f) { 600 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))}) 601 } 602 603 // Convert as if by ES6 number to string conversion. 604 // This matches most other JSON generators. 605 // See golang.org/issue/6384 and golang.org/issue/14135. 606 // Like fmt %g, but the exponent cutoffs are different 607 // and exponents themselves are not padded to two digits. 608 b := e.scratch[:0] 609 abs := math.Abs(f) 610 fmt := byte('f') 611 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. 612 if abs != 0 { 613 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { 614 fmt = 'e' 615 } 616 } 617 b = strconv.AppendFloat(b, f, fmt, -1, int(bits)) 618 if fmt == 'e' { 619 // clean up e-09 to e-9 620 n := len(b) 621 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' { 622 b[n-2] = b[n-1] 623 b = b[:n-1] 624 } 625 } 626 627 if opts.quoted { 628 e.WriteByte('"') 629 } 630 e.Write(b) 631 if opts.quoted { 632 e.WriteByte('"') 633 } 634 } 635 636 var ( 637 float32Encoder = (floatEncoder(32)).encode 638 float64Encoder = (floatEncoder(64)).encode 639 ) 640 641 func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { 642 if v.Type() == numberType { 643 numStr := v.String() 644 // In Go1.5 the empty string encodes to "0", while this is not a valid number literal 645 // we keep compatibility so check validity after this. 646 if numStr == "" { 647 numStr = "0" // Number's zero-val 648 } 649 if !isValidNumber(numStr) { 650 e.error(fmt.Errorf("json: invalid number literal %q", numStr)) 651 } 652 if opts.quoted { 653 e.WriteByte('"') 654 } 655 e.WriteString(numStr) 656 if opts.quoted { 657 e.WriteByte('"') 658 } 659 return 660 } 661 if opts.quoted { 662 e2 := newEncodeState() 663 // Since we encode the string twice, we only need to escape HTML 664 // the first time. 665 e2.string(v.String(), opts.escapeHTML) 666 e.stringBytes(e2.Bytes(), false) 667 encodeStatePool.Put(e2) 668 } else { 669 e.string(v.String(), opts.escapeHTML) 670 } 671 } 672 673 // isValidNumber reports whether s is a valid JSON number literal. 674 func isValidNumber(s string) bool { 675 // This function implements the JSON numbers grammar. 676 // See https://tools.ietf.org/html/rfc7159#section-6 677 // and https://www.json.org/img/number.png 678 679 if s == "" { 680 return false 681 } 682 683 // Optional - 684 if s[0] == '-' { 685 s = s[1:] 686 if s == "" { 687 return false 688 } 689 } 690 691 // Digits 692 switch { 693 default: 694 return false 695 696 case s[0] == '0': 697 s = s[1:] 698 699 case '1' <= s[0] && s[0] <= '9': 700 s = s[1:] 701 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { 702 s = s[1:] 703 } 704 } 705 706 // . followed by 1 or more digits. 707 if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { 708 s = s[2:] 709 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { 710 s = s[1:] 711 } 712 } 713 714 // e or E followed by an optional - or + and 715 // 1 or more digits. 716 if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { 717 s = s[1:] 718 if s[0] == '+' || s[0] == '-' { 719 s = s[1:] 720 if s == "" { 721 return false 722 } 723 } 724 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { 725 s = s[1:] 726 } 727 } 728 729 // Make sure we are at the end. 730 return s == "" 731 } 732 733 func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) { 734 if v.IsNil() { 735 e.WriteString("null") 736 return 737 } 738 if opts.isDiscriminatorSet() { 739 discriminatorInterfaceEncode(e, v, opts) 740 return 741 } 742 e.reflectValue(v.Elem(), opts) 743 } 744 745 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) { 746 e.error(&UnsupportedTypeError{v.Type()}) 747 } 748 749 type structEncoder struct { 750 fields structFields 751 } 752 753 type structFields struct { 754 list []field 755 nameIndex map[string]int 756 } 757 758 func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 759 next := byte('{') 760 if opts.isDiscriminatorSet() { 761 next = discriminatorStructEncode(e, v, opts) 762 } 763 FieldLoop: 764 for i := range se.fields.list { 765 f := &se.fields.list[i] 766 767 // Find the nested struct field by following f.index. 768 fv := v 769 for _, i := range f.index { 770 if fv.Kind() == reflect.Ptr { 771 if fv.IsNil() { 772 continue FieldLoop 773 } 774 fv = fv.Elem() 775 } 776 fv = fv.Field(i) 777 } 778 779 if f.omitEmpty && isEmptyValue(fv) { 780 continue 781 } 782 e.WriteByte(next) 783 next = ',' 784 if opts.escapeHTML { 785 e.WriteString(f.nameEscHTML) 786 } else { 787 e.WriteString(f.nameNonEsc) 788 } 789 opts.quoted = f.quoted 790 791 f.encoder(e, fv, opts) 792 } 793 if next == '{' { 794 e.WriteString("{}") 795 } else { 796 e.WriteByte('}') 797 } 798 } 799 800 func newStructEncoder(t reflect.Type) encoderFunc { 801 se := structEncoder{fields: cachedTypeFields(t)} 802 return se.encode 803 } 804 805 type mapEncoder struct { 806 elemEnc encoderFunc 807 } 808 809 func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 810 if v.IsNil() { 811 e.WriteString("null") 812 return 813 } 814 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter { 815 // We're a large number of nested ptrEncoder.encode calls deep; 816 // start checking if we've run into a pointer cycle. 817 ptr := v.Pointer() 818 if _, ok := e.ptrSeen[ptr]; ok { 819 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) 820 } 821 e.ptrSeen[ptr] = struct{}{} 822 defer delete(e.ptrSeen, ptr) 823 } 824 e.WriteByte('{') 825 826 if opts.isDiscriminatorSet() { 827 discriminatorMapEncode(e, v, opts) 828 } 829 830 // Extract and sort the keys. 831 sv := make([]reflectWithString, v.Len()) 832 mi := v.MapRange() 833 for i := 0; mi.Next(); i++ { 834 sv[i].k = mi.Key() 835 sv[i].v = mi.Value() 836 if err := sv[i].resolve(); err != nil { 837 e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error())) 838 } 839 } 840 sort.Slice(sv, func(i, j int) bool { return sv[i].ks < sv[j].ks }) 841 842 for i, kv := range sv { 843 if i > 0 { 844 e.WriteByte(',') 845 } 846 e.string(kv.ks, opts.escapeHTML) 847 e.WriteByte(':') 848 me.elemEnc(e, kv.v, opts) 849 } 850 e.WriteByte('}') 851 e.ptrLevel-- 852 } 853 854 func newMapEncoder(t reflect.Type) encoderFunc { 855 switch t.Key().Kind() { 856 case reflect.String, 857 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 858 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 859 default: 860 if !t.Key().Implements(textMarshalerType) { 861 return unsupportedTypeEncoder 862 } 863 } 864 me := mapEncoder{typeEncoder(t.Elem())} 865 return me.encode 866 } 867 868 func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) { 869 if v.IsNil() { 870 e.WriteString("null") 871 return 872 } 873 s := v.Bytes() 874 e.WriteByte('"') 875 encodedLen := base64.StdEncoding.EncodedLen(len(s)) 876 if encodedLen <= len(e.scratch) { 877 // If the encoded bytes fit in e.scratch, avoid an extra 878 // allocation and use the cheaper Encoding.Encode. 879 dst := e.scratch[:encodedLen] 880 base64.StdEncoding.Encode(dst, s) 881 e.Write(dst) 882 } else if encodedLen <= 1024 { 883 // The encoded bytes are short enough to allocate for, and 884 // Encoding.Encode is still cheaper. 885 dst := make([]byte, encodedLen) 886 base64.StdEncoding.Encode(dst, s) 887 e.Write(dst) 888 } else { 889 // The encoded bytes are too long to cheaply allocate, and 890 // Encoding.Encode is no longer noticeably cheaper. 891 enc := base64.NewEncoder(base64.StdEncoding, e) 892 enc.Write(s) 893 enc.Close() 894 } 895 e.WriteByte('"') 896 } 897 898 // sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil. 899 type sliceEncoder struct { 900 arrayEnc encoderFunc 901 } 902 903 func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 904 if v.IsNil() { 905 e.WriteString("null") 906 return 907 } 908 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter { 909 // We're a large number of nested ptrEncoder.encode calls deep; 910 // start checking if we've run into a pointer cycle. 911 // Here we use a struct to memorize the pointer to the first element of the slice 912 // and its length. 913 ptr := struct { 914 ptr uintptr 915 len int 916 }{v.Pointer(), v.Len()} 917 if _, ok := e.ptrSeen[ptr]; ok { 918 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) 919 } 920 e.ptrSeen[ptr] = struct{}{} 921 defer delete(e.ptrSeen, ptr) 922 } 923 se.arrayEnc(e, v, opts) 924 e.ptrLevel-- 925 } 926 927 func newSliceEncoder(t reflect.Type) encoderFunc { 928 // Byte slices get special treatment; arrays don't. 929 if t.Elem().Kind() == reflect.Uint8 { 930 p := reflect.PtrTo(t.Elem()) 931 if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) { 932 return encodeByteSlice 933 } 934 } 935 enc := sliceEncoder{newArrayEncoder(t)} 936 return enc.encode 937 } 938 939 type arrayEncoder struct { 940 elemEnc encoderFunc 941 } 942 943 func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 944 e.WriteByte('[') 945 n := v.Len() 946 for i := 0; i < n; i++ { 947 if i > 0 { 948 e.WriteByte(',') 949 } 950 ae.elemEnc(e, v.Index(i), opts) 951 } 952 e.WriteByte(']') 953 } 954 955 func newArrayEncoder(t reflect.Type) encoderFunc { 956 enc := arrayEncoder{typeEncoder(t.Elem())} 957 return enc.encode 958 } 959 960 type ptrEncoder struct { 961 elemEnc encoderFunc 962 } 963 964 func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 965 if v.IsNil() { 966 e.WriteString("null") 967 return 968 } 969 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter { 970 // We're a large number of nested ptrEncoder.encode calls deep; 971 // start checking if we've run into a pointer cycle. 972 ptr := v.Interface() 973 if _, ok := e.ptrSeen[ptr]; ok { 974 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) 975 } 976 e.ptrSeen[ptr] = struct{}{} 977 defer delete(e.ptrSeen, ptr) 978 } 979 pe.elemEnc(e, v.Elem(), opts) 980 e.ptrLevel-- 981 } 982 983 func newPtrEncoder(t reflect.Type) encoderFunc { 984 enc := ptrEncoder{typeEncoder(t.Elem())} 985 return enc.encode 986 } 987 988 type condAddrEncoder struct { 989 canAddrEnc, elseEnc encoderFunc 990 } 991 992 func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 993 if v.CanAddr() { 994 ce.canAddrEnc(e, v, opts) 995 } else { 996 ce.elseEnc(e, v, opts) 997 } 998 } 999 1000 // newCondAddrEncoder returns an encoder that checks whether its value 1001 // CanAddr and delegates to canAddrEnc if so, else to elseEnc. 1002 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc { 1003 enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc} 1004 return enc.encode 1005 } 1006 1007 func isValidTag(s string) bool { 1008 if s == "" { 1009 return false 1010 } 1011 for _, c := range s { 1012 switch { 1013 case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c): 1014 // Backslash and quote chars are reserved, but 1015 // otherwise any punctuation chars are allowed 1016 // in a tag name. 1017 case !unicode.IsLetter(c) && !unicode.IsDigit(c): 1018 return false 1019 } 1020 } 1021 return true 1022 } 1023 1024 func typeByIndex(t reflect.Type, index []int) reflect.Type { 1025 for _, i := range index { 1026 if t.Kind() == reflect.Ptr { 1027 t = t.Elem() 1028 } 1029 t = t.Field(i).Type 1030 } 1031 return t 1032 } 1033 1034 type reflectWithString struct { 1035 k reflect.Value 1036 v reflect.Value 1037 ks string 1038 } 1039 1040 func (w *reflectWithString) resolve() error { 1041 if w.k.Kind() == reflect.String { 1042 w.ks = w.k.String() 1043 return nil 1044 } 1045 if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok { 1046 if w.k.Kind() == reflect.Ptr && w.k.IsNil() { 1047 return nil 1048 } 1049 buf, err := tm.MarshalText() 1050 w.ks = string(buf) 1051 return err 1052 } 1053 switch w.k.Kind() { 1054 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1055 w.ks = strconv.FormatInt(w.k.Int(), 10) 1056 return nil 1057 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1058 w.ks = strconv.FormatUint(w.k.Uint(), 10) 1059 return nil 1060 } 1061 panic("unexpected map key type") 1062 } 1063 1064 // NOTE: keep in sync with stringBytes below. 1065 func (e *encodeState) string(s string, escapeHTML bool) { 1066 e.WriteByte('"') 1067 start := 0 1068 for i := 0; i < len(s); { 1069 if b := s[i]; b < utf8.RuneSelf { 1070 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 1071 i++ 1072 continue 1073 } 1074 if start < i { 1075 e.WriteString(s[start:i]) 1076 } 1077 e.WriteByte('\\') 1078 switch b { 1079 case '\\', '"': 1080 e.WriteByte(b) 1081 case '\n': 1082 e.WriteByte('n') 1083 case '\r': 1084 e.WriteByte('r') 1085 case '\t': 1086 e.WriteByte('t') 1087 default: 1088 // This encodes bytes < 0x20 except for \t, \n and \r. 1089 // If escapeHTML is set, it also escapes <, >, and & 1090 // because they can lead to security holes when 1091 // user-controlled strings are rendered into JSON 1092 // and served to some browsers. 1093 e.WriteString(`u00`) 1094 e.WriteByte(hex[b>>4]) 1095 e.WriteByte(hex[b&0xF]) 1096 } 1097 i++ 1098 start = i 1099 continue 1100 } 1101 c, size := utf8.DecodeRuneInString(s[i:]) 1102 if c == utf8.RuneError && size == 1 { 1103 if start < i { 1104 e.WriteString(s[start:i]) 1105 } 1106 e.WriteString(`\ufffd`) 1107 i += size 1108 start = i 1109 continue 1110 } 1111 // U+2028 is LINE SEPARATOR. 1112 // U+2029 is PARAGRAPH SEPARATOR. 1113 // They are both technically valid characters in JSON strings, 1114 // but don't work in JSONP, which has to be evaluated as JavaScript, 1115 // and can lead to security holes there. It is valid JSON to 1116 // escape them, so we do so unconditionally. 1117 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 1118 if c == '\u2028' || c == '\u2029' { 1119 if start < i { 1120 e.WriteString(s[start:i]) 1121 } 1122 e.WriteString(`\u202`) 1123 e.WriteByte(hex[c&0xF]) 1124 i += size 1125 start = i 1126 continue 1127 } 1128 i += size 1129 } 1130 if start < len(s) { 1131 e.WriteString(s[start:]) 1132 } 1133 e.WriteByte('"') 1134 } 1135 1136 // NOTE: keep in sync with string above. 1137 func (e *encodeState) stringBytes(s []byte, escapeHTML bool) { 1138 e.WriteByte('"') 1139 start := 0 1140 for i := 0; i < len(s); { 1141 if b := s[i]; b < utf8.RuneSelf { 1142 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 1143 i++ 1144 continue 1145 } 1146 if start < i { 1147 e.Write(s[start:i]) 1148 } 1149 e.WriteByte('\\') 1150 switch b { 1151 case '\\', '"': 1152 e.WriteByte(b) 1153 case '\n': 1154 e.WriteByte('n') 1155 case '\r': 1156 e.WriteByte('r') 1157 case '\t': 1158 e.WriteByte('t') 1159 default: 1160 // This encodes bytes < 0x20 except for \t, \n and \r. 1161 // If escapeHTML is set, it also escapes <, >, and & 1162 // because they can lead to security holes when 1163 // user-controlled strings are rendered into JSON 1164 // and served to some browsers. 1165 e.WriteString(`u00`) 1166 e.WriteByte(hex[b>>4]) 1167 e.WriteByte(hex[b&0xF]) 1168 } 1169 i++ 1170 start = i 1171 continue 1172 } 1173 c, size := utf8.DecodeRune(s[i:]) 1174 if c == utf8.RuneError && size == 1 { 1175 if start < i { 1176 e.Write(s[start:i]) 1177 } 1178 e.WriteString(`\ufffd`) 1179 i += size 1180 start = i 1181 continue 1182 } 1183 // U+2028 is LINE SEPARATOR. 1184 // U+2029 is PARAGRAPH SEPARATOR. 1185 // They are both technically valid characters in JSON strings, 1186 // but don't work in JSONP, which has to be evaluated as JavaScript, 1187 // and can lead to security holes there. It is valid JSON to 1188 // escape them, so we do so unconditionally. 1189 // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. 1190 if c == '\u2028' || c == '\u2029' { 1191 if start < i { 1192 e.Write(s[start:i]) 1193 } 1194 e.WriteString(`\u202`) 1195 e.WriteByte(hex[c&0xF]) 1196 i += size 1197 start = i 1198 continue 1199 } 1200 i += size 1201 } 1202 if start < len(s) { 1203 e.Write(s[start:]) 1204 } 1205 e.WriteByte('"') 1206 } 1207 1208 // A field represents a single field found in a struct. 1209 type field struct { 1210 name string 1211 nameBytes []byte // []byte(name) 1212 equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent 1213 1214 nameNonEsc string // `"` + name + `":` 1215 nameEscHTML string // `"` + HTMLEscape(name) + `":` 1216 1217 tag bool 1218 index []int 1219 typ reflect.Type 1220 omitEmpty bool 1221 quoted bool 1222 1223 encoder encoderFunc 1224 } 1225 1226 // byIndex sorts field by index sequence. 1227 type byIndex []field 1228 1229 func (x byIndex) Len() int { return len(x) } 1230 1231 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 1232 1233 func (x byIndex) Less(i, j int) bool { 1234 for k, xik := range x[i].index { 1235 if k >= len(x[j].index) { 1236 return false 1237 } 1238 if xik != x[j].index[k] { 1239 return xik < x[j].index[k] 1240 } 1241 } 1242 return len(x[i].index) < len(x[j].index) 1243 } 1244 1245 // typeFields returns a list of fields that JSON should recognize for the given type. 1246 // The algorithm is breadth-first search over the set of structs to include - the top struct 1247 // and then any reachable anonymous structs. 1248 func typeFields(t reflect.Type) structFields { 1249 // Anonymous fields to explore at the current level and the next. 1250 current := []field{} 1251 next := []field{{typ: t}} 1252 1253 // Count of queued names for current level and the next. 1254 var count, nextCount map[reflect.Type]int 1255 1256 // Types already visited at an earlier level. 1257 visited := map[reflect.Type]bool{} 1258 1259 // Fields found. 1260 var fields []field 1261 1262 // Buffer to run HTMLEscape on field names. 1263 var nameEscBuf bytes.Buffer 1264 1265 for len(next) > 0 { 1266 current, next = next, current[:0] 1267 count, nextCount = nextCount, map[reflect.Type]int{} 1268 1269 for _, f := range current { 1270 if visited[f.typ] { 1271 continue 1272 } 1273 visited[f.typ] = true 1274 1275 // Scan f.typ for fields to include. 1276 for i := 0; i < f.typ.NumField(); i++ { 1277 sf := f.typ.Field(i) 1278 if sf.Anonymous { 1279 t := sf.Type 1280 if t.Kind() == reflect.Ptr { 1281 t = t.Elem() 1282 } 1283 if !sf.IsExported() && t.Kind() != reflect.Struct { 1284 // Ignore embedded fields of unexported non-struct types. 1285 continue 1286 } 1287 // Do not ignore embedded fields of unexported struct types 1288 // since they may have exported fields. 1289 } else if !sf.IsExported() { 1290 // Ignore unexported non-embedded fields. 1291 continue 1292 } 1293 tag := sf.Tag.Get("json") 1294 if tag == "-" { 1295 continue 1296 } 1297 name, opts := parseTag(tag) 1298 if !isValidTag(name) { 1299 name = "" 1300 } 1301 index := make([]int, len(f.index)+1) 1302 copy(index, f.index) 1303 index[len(f.index)] = i 1304 1305 ft := sf.Type 1306 if ft.Name() == "" && ft.Kind() == reflect.Ptr { 1307 // Follow pointer. 1308 ft = ft.Elem() 1309 } 1310 1311 // Only strings, floats, integers, and booleans can be quoted. 1312 quoted := false 1313 if opts.Contains("string") { 1314 switch ft.Kind() { 1315 case reflect.Bool, 1316 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 1317 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 1318 reflect.Float32, reflect.Float64, 1319 reflect.String: 1320 quoted = true 1321 } 1322 } 1323 1324 // Record found field and index sequence. 1325 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { 1326 tagged := name != "" 1327 if name == "" { 1328 name = sf.Name 1329 } 1330 field := field{ 1331 name: name, 1332 tag: tagged, 1333 index: index, 1334 typ: ft, 1335 omitEmpty: opts.Contains("omitempty"), 1336 quoted: quoted, 1337 } 1338 field.nameBytes = []byte(field.name) 1339 field.equalFold = foldFunc(field.nameBytes) 1340 1341 // Build nameEscHTML and nameNonEsc ahead of time. 1342 nameEscBuf.Reset() 1343 nameEscBuf.WriteString(`"`) 1344 HTMLEscape(&nameEscBuf, field.nameBytes) 1345 nameEscBuf.WriteString(`":`) 1346 field.nameEscHTML = nameEscBuf.String() 1347 field.nameNonEsc = `"` + field.name + `":` 1348 1349 fields = append(fields, field) 1350 if count[f.typ] > 1 { 1351 // If there were multiple instances, add a second, 1352 // so that the annihilation code will see a duplicate. 1353 // It only cares about the distinction between 1 or 2, 1354 // so don't bother generating any more copies. 1355 fields = append(fields, fields[len(fields)-1]) 1356 } 1357 continue 1358 } 1359 1360 // Record new anonymous struct to explore in next round. 1361 nextCount[ft]++ 1362 if nextCount[ft] == 1 { 1363 next = append(next, field{name: ft.Name(), index: index, typ: ft}) 1364 } 1365 } 1366 } 1367 } 1368 1369 sort.Slice(fields, func(i, j int) bool { 1370 x := fields 1371 // sort field by name, breaking ties with depth, then 1372 // breaking ties with "name came from json tag", then 1373 // breaking ties with index sequence. 1374 if x[i].name != x[j].name { 1375 return x[i].name < x[j].name 1376 } 1377 if len(x[i].index) != len(x[j].index) { 1378 return len(x[i].index) < len(x[j].index) 1379 } 1380 if x[i].tag != x[j].tag { 1381 return x[i].tag 1382 } 1383 return byIndex(x).Less(i, j) 1384 }) 1385 1386 // Delete all fields that are hidden by the Go rules for embedded fields, 1387 // except that fields with JSON tags are promoted. 1388 1389 // The fields are sorted in primary order of name, secondary order 1390 // of field index length. Loop over names; for each name, delete 1391 // hidden fields by choosing the one dominant field that survives. 1392 out := fields[:0] 1393 for advance, i := 0, 0; i < len(fields); i += advance { 1394 // One iteration per name. 1395 // Find the sequence of fields with the name of this first field. 1396 fi := fields[i] 1397 name := fi.name 1398 for advance = 1; i+advance < len(fields); advance++ { 1399 fj := fields[i+advance] 1400 if fj.name != name { 1401 break 1402 } 1403 } 1404 if advance == 1 { // Only one field with this name 1405 out = append(out, fi) 1406 continue 1407 } 1408 dominant, ok := dominantField(fields[i : i+advance]) 1409 if ok { 1410 out = append(out, dominant) 1411 } 1412 } 1413 1414 fields = out 1415 sort.Sort(byIndex(fields)) 1416 1417 for i := range fields { 1418 f := &fields[i] 1419 f.encoder = typeEncoder(typeByIndex(t, f.index)) 1420 } 1421 nameIndex := make(map[string]int, len(fields)) 1422 for i, field := range fields { 1423 nameIndex[field.name] = i 1424 } 1425 return structFields{fields, nameIndex} 1426 } 1427 1428 // dominantField looks through the fields, all of which are known to 1429 // have the same name, to find the single field that dominates the 1430 // others using Go's embedding rules, modified by the presence of 1431 // JSON tags. If there are multiple top-level fields, the boolean 1432 // will be false: This condition is an error in Go and we skip all 1433 // the fields. 1434 func dominantField(fields []field) (field, bool) { 1435 // The fields are sorted in increasing index-length order, then by presence of tag. 1436 // That means that the first field is the dominant one. We need only check 1437 // for error cases: two fields at top level, either both tagged or neither tagged. 1438 if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag { 1439 return field{}, false 1440 } 1441 return fields[0], true 1442 } 1443 1444 var fieldCache sync.Map // map[reflect.Type]structFields 1445 1446 // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. 1447 func cachedTypeFields(t reflect.Type) structFields { 1448 if f, ok := fieldCache.Load(t); ok { 1449 return f.(structFields) 1450 } 1451 f, _ := fieldCache.LoadOrStore(t, typeFields(t)) 1452 return f.(structFields) 1453 }