github.com/neilotoole/jsoncolor@v0.7.2-0.20231115150201-1637fae69be1/codec.go (about) 1 package jsoncolor 2 3 import ( 4 "encoding" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "reflect" 9 "sort" 10 "strconv" 11 "strings" 12 "sync/atomic" 13 "time" 14 "unicode" 15 "unsafe" 16 ) 17 18 type codec struct { 19 encode encodeFunc 20 decode decodeFunc 21 } 22 23 type encoder struct { 24 flags AppendFlags 25 clrs *Colors 26 indentr *indenter 27 } 28 type decoder struct{ flags ParseFlags } 29 30 type ( 31 encodeFunc func(encoder, []byte, unsafe.Pointer) ([]byte, error) 32 decodeFunc func(decoder, []byte, unsafe.Pointer) ([]byte, error) 33 ) 34 35 type ( 36 emptyFunc func(unsafe.Pointer) bool 37 sortFunc func([]reflect.Value) 38 ) 39 40 // Eventually consistent cache mapping go types to dynamically generated 41 // codecs. 42 // 43 // Note: using a uintptr as key instead of reflect.Type shaved ~15ns off of 44 // the ~30ns Marshal/Unmarshal functions which were dominated by the map 45 // lookup time for simple types like bool, int, etc.. 46 var cache unsafe.Pointer // map[unsafe.Pointer]codec 47 48 func cacheLoad() map[unsafe.Pointer]codec { 49 p := atomic.LoadPointer(&cache) 50 return *(*map[unsafe.Pointer]codec)(unsafe.Pointer(&p)) 51 } 52 53 func cacheStore(typ reflect.Type, cod codec, oldCodecs map[unsafe.Pointer]codec) { 54 newCodecs := make(map[unsafe.Pointer]codec, len(oldCodecs)+1) 55 newCodecs[typeid(typ)] = cod 56 57 for t, c := range oldCodecs { 58 newCodecs[t] = c 59 } 60 61 atomic.StorePointer(&cache, *(*unsafe.Pointer)(unsafe.Pointer(&newCodecs))) 62 } 63 64 func typeid(t reflect.Type) unsafe.Pointer { 65 return (*iface)(unsafe.Pointer(&t)).ptr 66 } 67 68 func constructCachedCodec(t reflect.Type, cache map[unsafe.Pointer]codec) codec { 69 c := constructCodec(t, map[reflect.Type]*structType{}, t.Kind() == reflect.Ptr) 70 71 if inlined(t) { 72 c.encode = constructInlineValueEncodeFunc(c.encode) 73 } 74 75 cacheStore(t, c, cache) 76 return c 77 } 78 79 func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) (c codec) { 80 switch t { 81 case nullType, nil: 82 c = codec{encode: encoder.encodeNull, decode: decoder.decodeNull} 83 84 case numberType: 85 c = codec{encode: encoder.encodeNumber, decode: decoder.decodeNumber} 86 87 case bytesType: 88 c = codec{encode: encoder.encodeBytes, decode: decoder.decodeBytes} 89 90 case durationType: 91 c = codec{encode: encoder.encodeDuration, decode: decoder.decodeDuration} 92 93 case timeType: 94 c = codec{encode: encoder.encodeTime, decode: decoder.decodeTime} 95 96 case interfaceType: 97 c = codec{encode: encoder.encodeInterface, decode: decoder.decodeInterface} 98 99 case rawMessageType: 100 c = codec{encode: encoder.encodeRawMessage, decode: decoder.decodeRawMessage} 101 102 case numberPtrType: 103 c = constructPointerCodec(numberPtrType, nil) 104 105 case durationPtrType: 106 c = constructPointerCodec(durationPtrType, nil) 107 108 case timePtrType: 109 c = constructPointerCodec(timePtrType, nil) 110 111 case rawMessagePtrType: 112 c = constructPointerCodec(rawMessagePtrType, nil) 113 } 114 115 if c.encode != nil { 116 return c 117 } 118 119 switch t.Kind() { 120 case reflect.Bool: 121 c = codec{encode: encoder.encodeBool, decode: decoder.decodeBool} 122 123 case reflect.Int: 124 c = codec{encode: encoder.encodeInt, decode: decoder.decodeInt} 125 126 case reflect.Int8: 127 c = codec{encode: encoder.encodeInt8, decode: decoder.decodeInt8} 128 129 case reflect.Int16: 130 c = codec{encode: encoder.encodeInt16, decode: decoder.decodeInt16} 131 132 case reflect.Int32: 133 c = codec{encode: encoder.encodeInt32, decode: decoder.decodeInt32} 134 135 case reflect.Int64: 136 c = codec{encode: encoder.encodeInt64, decode: decoder.decodeInt64} 137 138 case reflect.Uint: 139 c = codec{encode: encoder.encodeUint, decode: decoder.decodeUint} 140 141 case reflect.Uintptr: 142 c = codec{encode: encoder.encodeUintptr, decode: decoder.decodeUintptr} 143 144 case reflect.Uint8: 145 c = codec{encode: encoder.encodeUint8, decode: decoder.decodeUint8} 146 147 case reflect.Uint16: 148 c = codec{encode: encoder.encodeUint16, decode: decoder.decodeUint16} 149 150 case reflect.Uint32: 151 c = codec{encode: encoder.encodeUint32, decode: decoder.decodeUint32} 152 153 case reflect.Uint64: 154 c = codec{encode: encoder.encodeUint64, decode: decoder.decodeUint64} 155 156 case reflect.Float32: 157 c = codec{encode: encoder.encodeFloat32, decode: decoder.decodeFloat32} 158 159 case reflect.Float64: 160 c = codec{encode: encoder.encodeFloat64, decode: decoder.decodeFloat64} 161 162 case reflect.String: 163 c = codec{encode: encoder.encodeString, decode: decoder.decodeString} 164 165 case reflect.Interface: 166 c = constructInterfaceCodec(t) 167 168 case reflect.Array: 169 c = constructArrayCodec(t, seen, canAddr) 170 171 case reflect.Slice: 172 c = constructSliceCodec(t, seen) 173 174 case reflect.Map: 175 c = constructMapCodec(t, seen) 176 177 case reflect.Struct: 178 c = constructStructCodec(t, seen, canAddr) 179 180 case reflect.Ptr: 181 c = constructPointerCodec(t, seen) 182 183 default: 184 c = constructUnsupportedTypeCodec(t) 185 } 186 187 p := reflect.PtrTo(t) 188 189 if canAddr { 190 switch { 191 case p.Implements(jsonMarshalerType): 192 c.encode = constructJSONMarshalerEncodeFunc(t, true) 193 case p.Implements(textMarshalerType): 194 c.encode = constructTextMarshalerEncodeFunc(t, true) 195 } 196 } 197 198 switch { 199 case t.Implements(jsonMarshalerType): 200 c.encode = constructJSONMarshalerEncodeFunc(t, false) 201 case t.Implements(textMarshalerType): 202 c.encode = constructTextMarshalerEncodeFunc(t, false) 203 } 204 205 switch { 206 case p.Implements(jsonUnmarshalerType): 207 c.decode = constructJSONUnmarshalerDecodeFunc(t, true) 208 case p.Implements(textUnmarshalerType): 209 c.decode = constructTextUnmarshalerDecodeFunc(t, true) 210 } 211 212 return c 213 } 214 215 func constructStringCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec { 216 c := constructCodec(t, seen, canAddr) 217 return codec{ 218 encode: constructStringEncodeFunc(c.encode), 219 decode: constructStringDecodeFunc(c.decode), 220 } 221 } 222 223 func constructStringEncodeFunc(encode encodeFunc) encodeFunc { 224 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 225 return e.encodeToString(b, p, encode) 226 } 227 } 228 229 func constructStringDecodeFunc(decode decodeFunc) decodeFunc { 230 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 231 return d.decodeFromString(b, p, decode) 232 } 233 } 234 235 func constructStringToIntDecodeFunc(t reflect.Type, decode decodeFunc) decodeFunc { 236 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 237 return d.decodeFromStringToInt(b, p, t, decode) 238 } 239 } 240 241 func constructArrayCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec { 242 e := t.Elem() 243 c := constructCodec(e, seen, canAddr) 244 s := alignedSize(e) 245 return codec{ 246 encode: constructArrayEncodeFunc(s, t, c.encode), 247 decode: constructArrayDecodeFunc(s, t, c.decode), 248 } 249 } 250 251 func constructArrayEncodeFunc(size uintptr, t reflect.Type, encode encodeFunc) encodeFunc { 252 n := t.Len() 253 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 254 return e.encodeArray(b, p, n, size, t, encode) 255 } 256 } 257 258 func constructArrayDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) decodeFunc { 259 n := t.Len() 260 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 261 return d.decodeArray(b, p, n, size, t, decode) 262 } 263 } 264 265 func constructSliceCodec(t reflect.Type, seen map[reflect.Type]*structType) codec { 266 e := t.Elem() 267 s := alignedSize(e) 268 269 if e.Kind() == reflect.Uint8 { 270 // Go 1.7+ behavior: slices of byte types (and aliases) may override the 271 // default encoding and decoding behaviors by implementing marshaler and 272 // unmarshaler interfaces. 273 p := reflect.PtrTo(e) 274 c := codec{} 275 276 switch { 277 case e.Implements(jsonMarshalerType): 278 c.encode = constructJSONMarshalerEncodeFunc(e, false) 279 case e.Implements(textMarshalerType): 280 c.encode = constructTextMarshalerEncodeFunc(e, false) 281 case p.Implements(jsonMarshalerType): 282 c.encode = constructJSONMarshalerEncodeFunc(e, true) 283 case p.Implements(textMarshalerType): 284 c.encode = constructTextMarshalerEncodeFunc(e, true) 285 } 286 287 switch { 288 case e.Implements(jsonUnmarshalerType): 289 c.decode = constructJSONUnmarshalerDecodeFunc(e, false) 290 case e.Implements(textUnmarshalerType): 291 c.decode = constructTextUnmarshalerDecodeFunc(e, false) 292 case p.Implements(jsonUnmarshalerType): 293 c.decode = constructJSONUnmarshalerDecodeFunc(e, true) 294 case p.Implements(textUnmarshalerType): 295 c.decode = constructTextUnmarshalerDecodeFunc(e, true) 296 } 297 298 if c.encode != nil { 299 c.encode = constructSliceEncodeFunc(s, t, c.encode) 300 } else { 301 c.encode = encoder.encodeBytes 302 } 303 304 if c.decode != nil { 305 c.decode = constructSliceDecodeFunc(s, t, c.decode) 306 } else { 307 c.decode = decoder.decodeBytes 308 } 309 310 return c 311 } 312 313 c := constructCodec(e, seen, true) 314 return codec{ 315 encode: constructSliceEncodeFunc(s, t, c.encode), 316 decode: constructSliceDecodeFunc(s, t, c.decode), 317 } 318 } 319 320 func constructSliceEncodeFunc(size uintptr, t reflect.Type, encode encodeFunc) encodeFunc { 321 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 322 return e.encodeSlice(b, p, size, t, encode) 323 } 324 } 325 326 func constructSliceDecodeFunc(size uintptr, t reflect.Type, decode decodeFunc) decodeFunc { 327 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 328 return d.decodeSlice(b, p, size, t, decode) 329 } 330 } 331 332 func constructMapCodec(t reflect.Type, seen map[reflect.Type]*structType) codec { 333 var sortKeys sortFunc 334 k := t.Key() 335 v := t.Elem() 336 337 // Faster implementations for some common cases. 338 switch { 339 case k == stringType && v == interfaceType: 340 return codec{ 341 encode: encoder.encodeMapStringInterface, 342 decode: decoder.decodeMapStringInterface, 343 } 344 345 case k == stringType && v == rawMessageType: 346 return codec{ 347 encode: encoder.encodeMapStringRawMessage, 348 decode: decoder.decodeMapStringRawMessage, 349 } 350 } 351 352 kc := codec{} 353 vc := constructCodec(v, seen, false) 354 355 if k.Implements(textMarshalerType) || reflect.PtrTo(k).Implements(textUnmarshalerType) { 356 kc.encode = constructTextMarshalerEncodeFunc(k, false) 357 kc.decode = constructTextUnmarshalerDecodeFunc(k, true) 358 359 sortKeys = func(keys []reflect.Value) { 360 sort.Slice(keys, func(i, j int) bool { 361 // This is a performance abomination but the use case is rare 362 // enough that it shouldn't be a problem in practice. 363 k1, _ := keys[i].Interface().(encoding.TextMarshaler).MarshalText() 364 k2, _ := keys[j].Interface().(encoding.TextMarshaler).MarshalText() 365 return string(k1) < string(k2) 366 }) 367 } 368 } else { 369 switch k.Kind() { 370 case reflect.String: 371 kc.encode = encoder.encodeKey 372 kc.decode = decoder.decodeString 373 374 sortKeys = func(keys []reflect.Value) { 375 sort.Slice(keys, func(i, j int) bool { return keys[i].String() < keys[j].String() }) 376 } 377 378 case reflect.Int, 379 reflect.Int8, 380 reflect.Int16, 381 reflect.Int32, 382 reflect.Int64: 383 kc = constructStringCodec(k, seen, false) 384 385 sortKeys = func(keys []reflect.Value) { 386 sort.Slice(keys, func(i, j int) bool { return intStringsAreSorted(keys[i].Int(), keys[j].Int()) }) 387 } 388 389 case reflect.Uint, 390 reflect.Uintptr, 391 reflect.Uint8, 392 reflect.Uint16, 393 reflect.Uint32, 394 reflect.Uint64: 395 kc = constructStringCodec(k, seen, false) 396 397 sortKeys = func(keys []reflect.Value) { 398 sort.Slice(keys, func(i, j int) bool { return uintStringsAreSorted(keys[i].Uint(), keys[j].Uint()) }) 399 } 400 401 default: 402 return constructUnsupportedTypeCodec(t) 403 } 404 } 405 406 if inlined(v) { 407 vc.encode = constructInlineValueEncodeFunc(vc.encode) 408 } 409 410 return codec{ 411 encode: constructMapEncodeFunc(t, kc.encode, vc.encode, sortKeys), 412 decode: constructMapDecodeFunc(t, kc.decode, vc.decode), 413 } 414 } 415 416 func constructMapEncodeFunc(t reflect.Type, encodeKey, encodeValue encodeFunc, sortKeys sortFunc) encodeFunc { 417 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 418 return e.encodeMap(b, p, t, encodeKey, encodeValue, sortKeys) 419 } 420 } 421 422 func constructMapDecodeFunc(t reflect.Type, decodeKey, decodeValue decodeFunc) decodeFunc { 423 kt := t.Key() 424 vt := t.Elem() 425 kz := reflect.Zero(kt) 426 vz := reflect.Zero(vt) 427 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 428 return d.decodeMap(b, p, t, kt, vt, kz, vz, decodeKey, decodeValue) 429 } 430 } 431 432 func constructStructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) codec { 433 st := constructStructType(t, seen, canAddr) 434 return codec{ 435 encode: constructStructEncodeFunc(st), 436 decode: constructStructDecodeFunc(st), 437 } 438 } 439 440 func constructStructType(t reflect.Type, seen map[reflect.Type]*structType, canAddr bool) *structType { 441 // Used for preventing infinite recursion on types that have pointers to 442 // themselves. 443 st := seen[t] 444 445 if st == nil { 446 st = &structType{ 447 fields: make([]structField, 0, t.NumField()), 448 fieldsIndex: make(map[string]*structField), 449 ficaseIndex: make(map[string]*structField), 450 typ: t, 451 } 452 453 seen[t] = st 454 st.fields = appendStructFields(st.fields, t, 0, seen, canAddr) 455 456 for i := range st.fields { 457 f := &st.fields[i] 458 s := strings.ToLower(f.name) 459 st.fieldsIndex[f.name] = f 460 // When there is ambiguity because multiple fields have the same 461 // case-insensitive representation, the first field must win. 462 if _, exists := st.ficaseIndex[s]; !exists { 463 st.ficaseIndex[s] = f 464 } 465 } 466 } 467 468 return st 469 } 470 471 func constructStructEncodeFunc(st *structType) encodeFunc { 472 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 473 return e.encodeStruct(b, p, st) 474 } 475 } 476 477 func constructStructDecodeFunc(st *structType) decodeFunc { 478 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 479 return d.decodeStruct(b, p, st) 480 } 481 } 482 483 func constructEmbeddedStructPointerCodec(t reflect.Type, unexported bool, offset uintptr, field codec) codec { 484 return codec{ 485 encode: constructEmbeddedStructPointerEncodeFunc(t, unexported, offset, field.encode), 486 decode: constructEmbeddedStructPointerDecodeFunc(t, unexported, offset, field.decode), 487 } 488 } 489 490 func constructEmbeddedStructPointerEncodeFunc(t reflect.Type, unexported bool, offset uintptr, encode encodeFunc) encodeFunc { 491 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 492 return e.encodeEmbeddedStructPointer(b, p, t, unexported, offset, encode) 493 } 494 } 495 496 func constructEmbeddedStructPointerDecodeFunc(t reflect.Type, unexported bool, offset uintptr, decode decodeFunc) decodeFunc { 497 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 498 return d.decodeEmbeddedStructPointer(b, p, t, unexported, offset, decode) 499 } 500 } 501 502 type embeddedField struct { 503 index int 504 offset uintptr 505 pointer bool 506 unexported bool 507 subtype *structType 508 subfield *structField 509 } 510 511 func appendStructFields(fields []structField, t reflect.Type, offset uintptr, seen map[reflect.Type]*structType, canAddr bool) []structField { 512 names := make(map[string]struct{}) 513 embedded := make([]embeddedField, 0, 10) 514 515 for i, n := 0, t.NumField(); i < n; i++ { 516 f := t.Field(i) 517 518 var ( 519 name = f.Name 520 anonymous = f.Anonymous 521 isTag = false 522 omitempty = false 523 stringifyEnabled = false 524 unexported = len(f.PkgPath) != 0 525 ) 526 527 if unexported && !anonymous { // unexported 528 continue 529 } 530 531 if parts := strings.Split(f.Tag.Get("json"), ","); len(parts) != 0 { 532 if len(parts[0]) != 0 { 533 name, isTag = parts[0], true 534 } 535 536 if name == "-" && len(parts) == 1 { // ignored 537 continue 538 } 539 540 if !isValidTag(name) { 541 name = f.Name 542 } 543 544 for _, tag := range parts[1:] { 545 switch tag { 546 case "omitempty": 547 omitempty = true 548 case "string": 549 stringifyEnabled = true 550 } 551 } 552 } 553 554 if anonymous && !isTag { // embedded 555 typ := f.Type 556 ptr := f.Type.Kind() == reflect.Ptr 557 558 if ptr { 559 typ = f.Type.Elem() 560 } 561 562 if typ.Kind() == reflect.Struct { 563 // When the embedded fields is inlined the fields can be looked 564 // up by offset from the address of the wrapping object, so we 565 // simply add the embedded struct fields to the list of fields 566 // of the current struct type. 567 subtype := constructStructType(typ, seen, canAddr) 568 569 for j := range subtype.fields { 570 embedded = append(embedded, embeddedField{ 571 index: i<<32 | j, 572 offset: offset + f.Offset, 573 pointer: ptr, 574 unexported: unexported, 575 subtype: subtype, 576 subfield: &subtype.fields[j], 577 }) 578 } 579 580 continue 581 } 582 583 if unexported { // ignore unexported non-struct types 584 continue 585 } 586 } 587 588 c := constructCodec(f.Type, seen, canAddr) 589 590 if stringifyEnabled { 591 c = stringify(&f, c) 592 } 593 594 fields = append(fields, structField{ 595 codec: c, 596 offset: offset + f.Offset, 597 empty: emptyFuncOf(f.Type), 598 tag: isTag, 599 omitempty: omitempty, 600 name: name, 601 index: i << 32, 602 typ: f.Type, 603 zero: reflect.Zero(f.Type), 604 }) 605 606 names[name] = struct{}{} 607 } 608 609 // Only unambiguous embedded fields must be serialized. 610 ambiguousNames, ambiguousTags := ambiguousNameTagCount(names, embedded) 611 612 for _, embfield := range embedded { 613 subfield := *embfield.subfield 614 615 if ambiguousNames[subfield.name] > 1 && !(subfield.tag && ambiguousTags[subfield.name] == 1) { 616 continue // ambiguous embedded field 617 } 618 619 if embfield.pointer { 620 subfield.codec = constructEmbeddedStructPointerCodec(embfield.subtype.typ, embfield.unexported, subfield.offset, subfield.codec) 621 subfield.offset = embfield.offset 622 } else { 623 subfield.offset += embfield.offset 624 } 625 626 // To prevent dominant flags more than one level below the embedded one. 627 subfield.tag = false 628 629 // To ensure the order of the fields in the output is the same is in the 630 // struct type. 631 subfield.index = embfield.index 632 633 fields = append(fields, subfield) 634 } 635 636 for i := range fields { 637 fields[i].json = encodeString(fields[i].name, 0) 638 fields[i].html = encodeString(fields[i].name, EscapeHTML) 639 } 640 641 sort.Slice(fields, func(i, j int) bool { return fields[i].index < fields[j].index }) 642 return fields 643 } 644 645 func ambiguousNameTagCount(names map[string]struct{}, embedded []embeddedField) (map[string]int, map[string]int) { 646 ambiguousNames := make(map[string]int) 647 ambiguousTags := make(map[string]int) 648 649 // Embedded types can never override a field that was already present at 650 // the top-level. 651 for name := range names { 652 ambiguousNames[name]++ 653 ambiguousTags[name]++ 654 } 655 656 for _, embfield := range embedded { 657 ambiguousNames[embfield.subfield.name]++ 658 if embfield.subfield.tag { 659 ambiguousTags[embfield.subfield.name]++ 660 } 661 } 662 663 return ambiguousNames, ambiguousTags 664 } 665 666 func stringify(f *reflect.StructField, c codec) codec { 667 // https://golang.org/pkg/encoding/json/#Marshal 668 // 669 // The "string" option signals that a field is stored as JSON inside 670 // a JSON-encoded string. It applies only to fields of string, 671 // floating point, integer, or boolean types. This extra level of 672 // encoding is sometimes used when communicating with JavaScript 673 // programs: 674 typ := f.Type 675 676 if typ.Kind() == reflect.Ptr { 677 typ = typ.Elem() 678 } 679 680 switch typ.Kind() { 681 case reflect.Int, 682 reflect.Int8, 683 reflect.Int16, 684 reflect.Int32, 685 reflect.Int64, 686 reflect.Uint, 687 reflect.Uintptr, 688 reflect.Uint8, 689 reflect.Uint16, 690 reflect.Uint32, 691 reflect.Uint64: 692 c.encode = constructStringEncodeFunc(c.encode) 693 c.decode = constructStringToIntDecodeFunc(typ, c.decode) 694 case reflect.Bool, 695 reflect.Float32, 696 reflect.Float64, 697 reflect.String: 698 c.encode = constructStringEncodeFunc(c.encode) 699 c.decode = constructStringDecodeFunc(c.decode) 700 } 701 702 return c 703 } 704 705 func encodeString(s string, flags AppendFlags) string { 706 b := make([]byte, 0, len(s)+2) 707 e := encoder{flags: flags} 708 b, _ = e.doEncodeString(b, unsafe.Pointer(&s)) 709 return *(*string)(unsafe.Pointer(&b)) 710 } 711 712 func constructPointerCodec(t reflect.Type, seen map[reflect.Type]*structType) codec { 713 e := t.Elem() 714 c := constructCodec(e, seen, true) 715 return codec{ 716 encode: constructPointerEncodeFunc(e, c.encode), 717 decode: constructPointerDecodeFunc(e, c.decode), 718 } 719 } 720 721 func constructPointerEncodeFunc(t reflect.Type, encode encodeFunc) encodeFunc { 722 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 723 return e.encodePointer(b, p, t, encode) 724 } 725 } 726 727 func constructPointerDecodeFunc(t reflect.Type, decode decodeFunc) decodeFunc { 728 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 729 return d.decodePointer(b, p, t, decode) 730 } 731 } 732 733 func constructInterfaceCodec(t reflect.Type) codec { 734 return codec{ 735 encode: constructMaybeEmptyInterfaceEncoderFunc(t), 736 decode: constructMaybeEmptyInterfaceDecoderFunc(t), 737 } 738 } 739 740 func constructMaybeEmptyInterfaceEncoderFunc(t reflect.Type) encodeFunc { 741 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 742 return e.encodeMaybeEmptyInterface(b, p, t) 743 } 744 } 745 746 func constructMaybeEmptyInterfaceDecoderFunc(t reflect.Type) decodeFunc { 747 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 748 return d.decodeMaybeEmptyInterface(b, p, t) 749 } 750 } 751 752 func constructUnsupportedTypeCodec(t reflect.Type) codec { 753 return codec{ 754 encode: constructUnsupportedTypeEncodeFunc(t), 755 decode: constructUnsupportedTypeDecodeFunc(t), 756 } 757 } 758 759 func constructUnsupportedTypeEncodeFunc(t reflect.Type) encodeFunc { 760 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 761 return e.encodeUnsupportedTypeError(b, p, t) 762 } 763 } 764 765 func constructUnsupportedTypeDecodeFunc(t reflect.Type) decodeFunc { 766 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 767 return d.decodeUnmarshalTypeError(b, p, t) 768 } 769 } 770 771 func constructJSONMarshalerEncodeFunc(t reflect.Type, pointer bool) encodeFunc { 772 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 773 return e.encodeJSONMarshaler(b, p, t, pointer) 774 } 775 } 776 777 func constructJSONUnmarshalerDecodeFunc(t reflect.Type, pointer bool) decodeFunc { 778 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 779 return d.decodeJSONUnmarshaler(b, p, t, pointer) 780 } 781 } 782 783 func constructTextMarshalerEncodeFunc(t reflect.Type, pointer bool) encodeFunc { 784 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 785 return e.encodeTextMarshaler(b, p, t, pointer) 786 } 787 } 788 789 func constructTextUnmarshalerDecodeFunc(t reflect.Type, pointer bool) decodeFunc { 790 return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { 791 return d.decodeTextUnmarshaler(b, p, t, pointer) 792 } 793 } 794 795 func constructInlineValueEncodeFunc(encode encodeFunc) encodeFunc { 796 return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { 797 return encode(e, b, noescape(unsafe.Pointer(&p))) 798 } 799 } 800 801 // noescape hides a pointer from escape analysis. noescape is 802 // the identity function but escape analysis doesn't think the 803 // output depends on the input. noescape is inlined and currently 804 // compiles down to zero instructions. 805 // USE CAREFULLY! 806 // This was copied from the runtime; see issues 23382 and 7921. 807 // 808 //go:nosplit 809 func noescape(p unsafe.Pointer) unsafe.Pointer { 810 x := uintptr(p) 811 return unsafe.Pointer(x) 812 } 813 814 func alignedSize(t reflect.Type) uintptr { 815 a := t.Align() 816 s := t.Size() 817 return align(uintptr(a), s) 818 } 819 820 func align(align, size uintptr) uintptr { 821 if align != 0 && (size%align) != 0 { 822 size = ((size / align) + 1) * align 823 } 824 return size 825 } 826 827 func inlined(t reflect.Type) bool { 828 switch t.Kind() { 829 case reflect.Ptr: 830 return true 831 case reflect.Map: 832 return true 833 case reflect.Struct: 834 return t.NumField() == 1 && inlined(t.Field(0).Type) 835 default: 836 return false 837 } 838 } 839 840 func isValidTag(s string) bool { 841 if s == "" { 842 return false 843 } 844 for _, c := range s { 845 switch { 846 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): 847 // Backslash and quote chars are reserved, but 848 // otherwise any punctuation chars are allowed 849 // in a tag name. 850 default: 851 if !unicode.IsLetter(c) && !unicode.IsDigit(c) { 852 return false 853 } 854 } 855 } 856 return true 857 } 858 859 func emptyFuncOf(t reflect.Type) emptyFunc { 860 switch t { 861 case bytesType, rawMessageType: 862 return func(p unsafe.Pointer) bool { return (*slice)(p).len == 0 } 863 } 864 865 switch t.Kind() { 866 case reflect.Array: 867 if t.Len() == 0 { 868 return func(unsafe.Pointer) bool { return true } 869 } 870 871 case reflect.Map: 872 return func(p unsafe.Pointer) bool { return reflect.NewAt(t, p).Elem().Len() == 0 } 873 874 case reflect.Slice: 875 return func(p unsafe.Pointer) bool { return (*slice)(p).len == 0 } 876 877 case reflect.String: 878 return func(p unsafe.Pointer) bool { return len(*(*string)(p)) == 0 } 879 880 case reflect.Bool: 881 return func(p unsafe.Pointer) bool { return !*(*bool)(p) } 882 883 case reflect.Int, reflect.Uint: 884 return func(p unsafe.Pointer) bool { return *(*uint)(p) == 0 } 885 886 case reflect.Uintptr: 887 return func(p unsafe.Pointer) bool { return *(*uintptr)(p) == 0 } 888 889 case reflect.Int8, reflect.Uint8: 890 return func(p unsafe.Pointer) bool { return *(*uint8)(p) == 0 } 891 892 case reflect.Int16, reflect.Uint16: 893 return func(p unsafe.Pointer) bool { return *(*uint16)(p) == 0 } 894 895 case reflect.Int32, reflect.Uint32: 896 return func(p unsafe.Pointer) bool { return *(*uint32)(p) == 0 } 897 898 case reflect.Int64, reflect.Uint64: 899 return func(p unsafe.Pointer) bool { return *(*uint64)(p) == 0 } 900 901 case reflect.Float32: 902 return func(p unsafe.Pointer) bool { return *(*float32)(p) == 0 } 903 904 case reflect.Float64: 905 return func(p unsafe.Pointer) bool { return *(*float64)(p) == 0 } 906 907 case reflect.Ptr: 908 return func(p unsafe.Pointer) bool { return *(*unsafe.Pointer)(p) == nil } 909 910 case reflect.Interface: 911 return func(p unsafe.Pointer) bool { return (*iface)(p).ptr == nil } 912 } 913 914 return func(unsafe.Pointer) bool { return false } 915 } 916 917 type iface struct { 918 typ unsafe.Pointer 919 ptr unsafe.Pointer 920 } 921 922 type slice struct { 923 data unsafe.Pointer 924 len int 925 cap int 926 } 927 928 type structType struct { 929 fields []structField 930 fieldsIndex map[string]*structField 931 ficaseIndex map[string]*structField 932 typ reflect.Type 933 } 934 935 type structField struct { 936 codec codec 937 offset uintptr 938 empty emptyFunc 939 tag bool 940 omitempty bool 941 json string 942 html string 943 name string 944 typ reflect.Type 945 zero reflect.Value 946 index int 947 } 948 949 func unmarshalTypeError(b []byte, t reflect.Type) error { 950 return &UnmarshalTypeError{Value: strconv.Quote(prefix(b)), Type: t} 951 } 952 953 func unmarshalOverflow(b []byte, t reflect.Type) error { 954 return &UnmarshalTypeError{Value: "number " + prefix(b) + " overflows", Type: t} 955 } 956 957 func unexpectedEOF(b []byte) error { 958 return syntaxError(b, "unexpected end of JSON input") 959 } 960 961 func syntaxError(b []byte, msg string, args ...interface{}) error { 962 e := new(SyntaxError) 963 s := "json: " + fmt.Sprintf(msg, args...) + ": " + prefix(b) 964 p := unsafe.Pointer(e) 965 // Hack to set the unexported `msg` field. 966 *(*string)(p) = s 967 return e 968 } 969 970 func inputError(b []byte, t reflect.Type) ([]byte, error) { 971 if len(b) == 0 { 972 return nil, unexpectedEOF(b) 973 } 974 _, r, err := parseValue(b) 975 if err != nil { 976 return r, err 977 } 978 return skipSpaces(r), unmarshalTypeError(b, t) 979 } 980 981 func objectKeyError(b []byte, err error) ([]byte, error) { 982 if len(b) == 0 { 983 return nil, unexpectedEOF(b) 984 } 985 var e *UnmarshalTypeError 986 if errors.As(err, &e) { 987 err = syntaxError(b, "invalid character '%c' looking for beginning of object key", b[0]) 988 } 989 return b, err 990 } 991 992 func prefix(b []byte) string { 993 if len(b) < 32 { 994 return string(b) 995 } 996 return string(b[:32]) + "..." 997 } 998 999 func intStringsAreSorted(i0, i1 int64) bool { 1000 var b0, b1 [32]byte 1001 return string(strconv.AppendInt(b0[:0], i0, 10)) < string(strconv.AppendInt(b1[:0], i1, 10)) 1002 } 1003 1004 func uintStringsAreSorted(u0, u1 uint64) bool { 1005 var b0, b1 [32]byte 1006 return string(strconv.AppendUint(b0[:0], u0, 10)) < string(strconv.AppendUint(b1[:0], u1, 10)) 1007 } 1008 1009 //go:nosplit 1010 func stringToBytes(s string) []byte { 1011 return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ //nolint:govet // from segment's code 1012 Data: ((*reflect.StringHeader)(unsafe.Pointer(&s))).Data, 1013 Len: len(s), 1014 Cap: len(s), 1015 })) 1016 } 1017 1018 var ( 1019 nullType = reflect.TypeOf(nil) 1020 boolType = reflect.TypeOf(false) 1021 1022 intType = reflect.TypeOf(int(0)) 1023 int8Type = reflect.TypeOf(int8(0)) 1024 int16Type = reflect.TypeOf(int16(0)) 1025 int32Type = reflect.TypeOf(int32(0)) 1026 int64Type = reflect.TypeOf(int64(0)) 1027 1028 uintType = reflect.TypeOf(uint(0)) 1029 uint8Type = reflect.TypeOf(uint8(0)) 1030 uint16Type = reflect.TypeOf(uint16(0)) 1031 uint32Type = reflect.TypeOf(uint32(0)) 1032 uint64Type = reflect.TypeOf(uint64(0)) 1033 uintptrType = reflect.TypeOf(uintptr(0)) 1034 1035 float32Type = reflect.TypeOf(float32(0)) 1036 float64Type = reflect.TypeOf(float64(0)) 1037 1038 numberType = reflect.TypeOf(json.Number("")) 1039 stringType = reflect.TypeOf("") 1040 bytesType = reflect.TypeOf(([]byte)(nil)) 1041 durationType = reflect.TypeOf(time.Duration(0)) 1042 timeType = reflect.TypeOf(time.Time{}) 1043 rawMessageType = reflect.TypeOf(RawMessage(nil)) 1044 1045 numberPtrType = reflect.PtrTo(numberType) 1046 durationPtrType = reflect.PtrTo(durationType) 1047 timePtrType = reflect.PtrTo(timeType) 1048 rawMessagePtrType = reflect.PtrTo(rawMessageType) 1049 1050 sliceInterfaceType = reflect.TypeOf(([]interface{})(nil)) 1051 mapStringInterfaceType = reflect.TypeOf((map[string]interface{})(nil)) 1052 mapStringRawMessageType = reflect.TypeOf((map[string]RawMessage)(nil)) 1053 1054 interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() 1055 jsonMarshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() 1056 jsonUnmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() 1057 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 1058 textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() 1059 )