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