1
2
3
4
5
6
7 package json
8
9 import (
10 "bytes"
11 "cmp"
12 "encoding"
13 "encoding/base32"
14 "encoding/base64"
15 "encoding/hex"
16 "errors"
17 "fmt"
18 "math"
19 "reflect"
20 "slices"
21 "strconv"
22 "strings"
23 "sync"
24
25 "encoding/json/internal"
26 "encoding/json/internal/jsonflags"
27 "encoding/json/internal/jsonopts"
28 "encoding/json/internal/jsonwire"
29 "encoding/json/jsontext"
30 )
31
32
33
34
35 const optimizeCommon = true
36
37 var (
38
39 anyType = reflect.TypeFor[any]()
40 boolType = reflect.TypeFor[bool]()
41 stringType = reflect.TypeFor[string]()
42 float64Type = reflect.TypeFor[float64]()
43 mapStringAnyType = reflect.TypeFor[map[string]any]()
44 sliceAnyType = reflect.TypeFor[[]any]()
45
46 bytesType = reflect.TypeFor[[]byte]()
47 emptyStructType = reflect.TypeFor[struct{}]()
48 )
49
50 const startDetectingCyclesAfter = 1000
51
52 type seenPointers = map[any]struct{}
53
54 type typedPointer struct {
55 typ reflect.Type
56 ptr any
57 len int
58 }
59
60
61
62 func visitPointer(m *seenPointers, v reflect.Value) error {
63 p := typedPointer{v.Type(), v.UnsafePointer(), sliceLen(v)}
64 if _, ok := (*m)[p]; ok {
65 return internal.ErrCycle
66 }
67 if *m == nil {
68 *m = make(seenPointers)
69 }
70 (*m)[p] = struct{}{}
71 return nil
72 }
73 func leavePointer(m *seenPointers, v reflect.Value) {
74 p := typedPointer{v.Type(), v.UnsafePointer(), sliceLen(v)}
75 delete(*m, p)
76 }
77
78 func sliceLen(v reflect.Value) int {
79 if v.Kind() == reflect.Slice {
80 return v.Len()
81 }
82 return 0
83 }
84
85 func len64[Bytes ~[]byte | ~string](in Bytes) int64 {
86 return int64(len(in))
87 }
88
89 func makeDefaultArshaler(t reflect.Type) *arshaler {
90 switch t.Kind() {
91 case reflect.Bool:
92 return makeBoolArshaler(t)
93 case reflect.String:
94 return makeStringArshaler(t)
95 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
96 return makeIntArshaler(t)
97 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
98 return makeUintArshaler(t)
99 case reflect.Float32, reflect.Float64:
100 return makeFloatArshaler(t)
101 case reflect.Map:
102 return makeMapArshaler(t)
103 case reflect.Struct:
104 return makeStructArshaler(t)
105 case reflect.Slice:
106 fncs := makeSliceArshaler(t)
107 if t.Elem().Kind() == reflect.Uint8 {
108 return makeBytesArshaler(t, fncs)
109 }
110 return fncs
111 case reflect.Array:
112 fncs := makeArrayArshaler(t)
113 if t.Elem().Kind() == reflect.Uint8 {
114 return makeBytesArshaler(t, fncs)
115 }
116 return fncs
117 case reflect.Pointer:
118 return makePointerArshaler(t)
119 case reflect.Interface:
120 return makeInterfaceArshaler(t)
121 default:
122 return makeInvalidArshaler(t)
123 }
124 }
125
126 func makeBoolArshaler(t reflect.Type) *arshaler {
127 var fncs arshaler
128 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
129 xe := export.Encoder(enc)
130 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
131 return newInvalidFormatError(enc, t)
132 }
133
134
135 if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyBoolsAndStrings) && !xe.Tokens.Last.NeedObjectName() {
136 xe.Buf = strconv.AppendBool(xe.Tokens.MayAppendDelim(xe.Buf, 't'), va.Bool())
137 xe.Tokens.Last.Increment()
138 if xe.NeedFlush() {
139 return xe.Flush()
140 }
141 return nil
142 }
143
144 if mo.Flags.Get(jsonflags.StringifyBoolsAndStrings) {
145 if va.Bool() {
146 return enc.WriteToken(jsontext.String("true"))
147 } else {
148 return enc.WriteToken(jsontext.String("false"))
149 }
150 }
151 return enc.WriteToken(jsontext.Bool(va.Bool()))
152 }
153 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
154 xd := export.Decoder(dec)
155 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
156 return newInvalidFormatError(dec, t)
157 }
158 tok, err := dec.ReadToken()
159 if err != nil {
160 return err
161 }
162 k := tok.Kind()
163 switch k {
164 case 'n':
165 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
166 va.SetBool(false)
167 }
168 return nil
169 case 't', 'f':
170 if !uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) {
171 va.SetBool(tok.Bool())
172 return nil
173 }
174 case '"':
175 if uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) {
176 switch tok.String() {
177 case "true":
178 va.SetBool(true)
179 case "false":
180 va.SetBool(false)
181 default:
182 if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && tok.String() == "null" {
183 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
184 va.SetBool(false)
185 }
186 return nil
187 }
188 return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax)
189 }
190 return nil
191 }
192 }
193 return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
194 }
195 return &fncs
196 }
197
198 func makeStringArshaler(t reflect.Type) *arshaler {
199 var fncs arshaler
200 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
201 xe := export.Encoder(enc)
202 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
203 return newInvalidFormatError(enc, t)
204 }
205
206
207 s := va.String()
208 if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyBoolsAndStrings) && !xe.Tokens.Last.NeedObjectName() {
209 b := xe.Buf
210 b = xe.Tokens.MayAppendDelim(b, '"')
211 b, err := jsonwire.AppendQuote(b, s, &mo.Flags)
212 if err == nil {
213 xe.Buf = b
214 xe.Tokens.Last.Increment()
215 if xe.NeedFlush() {
216 return xe.Flush()
217 }
218 return nil
219 }
220
221
222 }
223
224 if mo.Flags.Get(jsonflags.StringifyBoolsAndStrings) {
225 b, err := jsonwire.AppendQuote(nil, s, &mo.Flags)
226 if err != nil {
227 return newMarshalErrorBefore(enc, t, &jsontext.SyntacticError{Err: err})
228 }
229 q, err := jsontext.AppendQuote(nil, b)
230 if err != nil {
231 panic("BUG: second AppendQuote should never fail: " + err.Error())
232 }
233 return enc.WriteValue(q)
234 }
235 return enc.WriteToken(jsontext.String(s))
236 }
237 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
238 xd := export.Decoder(dec)
239 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
240 return newInvalidFormatError(dec, t)
241 }
242 var flags jsonwire.ValueFlags
243 val, err := xd.ReadValue(&flags)
244 if err != nil {
245 return err
246 }
247 k := val.Kind()
248 switch k {
249 case 'n':
250 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
251 va.SetString("")
252 }
253 return nil
254 case '"':
255 val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
256 if uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) {
257 val, err = jsontext.AppendUnquote(nil, val)
258 if err != nil {
259 return newUnmarshalErrorAfter(dec, t, err)
260 }
261 if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" {
262 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
263 va.SetString("")
264 }
265 return nil
266 }
267 }
268 if xd.StringCache == nil {
269 xd.StringCache = new(stringCache)
270 }
271 str := makeString(xd.StringCache, val)
272 va.SetString(str)
273 return nil
274 }
275 return newUnmarshalErrorAfter(dec, t, nil)
276 }
277 return &fncs
278 }
279
280 var (
281 appendEncodeBase16 = hex.AppendEncode
282 appendEncodeBase32 = base32.StdEncoding.AppendEncode
283 appendEncodeBase32Hex = base32.HexEncoding.AppendEncode
284 appendEncodeBase64 = base64.StdEncoding.AppendEncode
285 appendEncodeBase64URL = base64.URLEncoding.AppendEncode
286 encodedLenBase16 = hex.EncodedLen
287 encodedLenBase32 = base32.StdEncoding.EncodedLen
288 encodedLenBase32Hex = base32.HexEncoding.EncodedLen
289 encodedLenBase64 = base64.StdEncoding.EncodedLen
290 encodedLenBase64URL = base64.URLEncoding.EncodedLen
291 appendDecodeBase16 = hex.AppendDecode
292 appendDecodeBase32 = base32.StdEncoding.AppendDecode
293 appendDecodeBase32Hex = base32.HexEncoding.AppendDecode
294 appendDecodeBase64 = base64.StdEncoding.AppendDecode
295 appendDecodeBase64URL = base64.URLEncoding.AppendDecode
296 )
297
298 func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
299
300
301
302
303
304
305 marshalArray := fncs.marshal
306 isNamedByte := t.Elem().PkgPath() != ""
307 hasMarshaler := implementsAny(t.Elem(), allMarshalerTypes...)
308 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
309 if !mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && isNamedByte {
310 return marshalArray(enc, va, mo)
311 }
312 xe := export.Encoder(enc)
313 appendEncode := appendEncodeBase64
314 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
315 switch mo.Format {
316 case "base64":
317 appendEncode = appendEncodeBase64
318 case "base64url":
319 appendEncode = appendEncodeBase64URL
320 case "base32":
321 appendEncode = appendEncodeBase32
322 case "base32hex":
323 appendEncode = appendEncodeBase32Hex
324 case "base16", "hex":
325 appendEncode = appendEncodeBase16
326 case "array":
327 mo.Format = ""
328 return marshalArray(enc, va, mo)
329 default:
330 return newInvalidFormatError(enc, t)
331 }
332 } else if mo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array {
333 return marshalArray(enc, va, mo)
334 } else if mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && hasMarshaler {
335 return marshalArray(enc, va, mo)
336 }
337 if mo.Flags.Get(jsonflags.FormatNilSliceAsNull) && va.Kind() == reflect.Slice && va.IsNil() {
338
339 return enc.WriteToken(jsontext.Null)
340 }
341 return xe.AppendRaw('"', true, func(b []byte) ([]byte, error) {
342 return appendEncode(b, va.Bytes()), nil
343 })
344 }
345 unmarshalArray := fncs.unmarshal
346 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
347 if !uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && isNamedByte {
348 return unmarshalArray(dec, va, uo)
349 }
350 xd := export.Decoder(dec)
351 appendDecode, encodedLen := appendDecodeBase64, encodedLenBase64
352 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
353 switch uo.Format {
354 case "base64":
355 appendDecode, encodedLen = appendDecodeBase64, encodedLenBase64
356 case "base64url":
357 appendDecode, encodedLen = appendDecodeBase64URL, encodedLenBase64URL
358 case "base32":
359 appendDecode, encodedLen = appendDecodeBase32, encodedLenBase32
360 case "base32hex":
361 appendDecode, encodedLen = appendDecodeBase32Hex, encodedLenBase32Hex
362 case "base16", "hex":
363 appendDecode, encodedLen = appendDecodeBase16, encodedLenBase16
364 case "array":
365 uo.Format = ""
366 return unmarshalArray(dec, va, uo)
367 default:
368 return newInvalidFormatError(dec, t)
369 }
370 } else if uo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array {
371 return unmarshalArray(dec, va, uo)
372 } else if uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && dec.PeekKind() == '[' {
373 return unmarshalArray(dec, va, uo)
374 }
375 var flags jsonwire.ValueFlags
376 val, err := xd.ReadValue(&flags)
377 if err != nil {
378 return err
379 }
380 k := val.Kind()
381 switch k {
382 case 'n':
383 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) || va.Kind() != reflect.Array {
384 va.SetZero()
385 }
386 return nil
387 case '"':
388
389
390
391
392
393
394
395 val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
396 b, err := appendDecode(va.Bytes()[:0], val)
397 if err != nil {
398 return newUnmarshalErrorAfter(dec, t, err)
399 }
400 if len(val) != encodedLen(len(b)) && !uo.Flags.Get(jsonflags.ParseBytesWithLooseRFC4648) {
401
402
403
404
405 i := bytes.IndexAny(val, "\r\n")
406 err := fmt.Errorf("illegal character %s at offset %d", jsonwire.QuoteRune(val[i:]), i)
407 return newUnmarshalErrorAfter(dec, t, err)
408 }
409
410 if va.Kind() == reflect.Array {
411 dst := va.Bytes()
412 clear(dst[copy(dst, b):])
413 if len(b) != len(dst) && !uo.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) {
414 err := fmt.Errorf("decoded length of %d mismatches array length of %d", len(b), len(dst))
415 return newUnmarshalErrorAfter(dec, t, err)
416 }
417 } else {
418 if b == nil {
419 b = []byte{}
420 }
421 va.SetBytes(b)
422 }
423 return nil
424 }
425 return newUnmarshalErrorAfter(dec, t, nil)
426 }
427 return fncs
428 }
429
430 func makeIntArshaler(t reflect.Type) *arshaler {
431 var fncs arshaler
432 bits := t.Bits()
433 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
434 xe := export.Encoder(enc)
435 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
436 return newInvalidFormatError(enc, t)
437 }
438
439
440 if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() {
441 xe.Buf = strconv.AppendInt(xe.Tokens.MayAppendDelim(xe.Buf, '0'), va.Int(), 10)
442 xe.Tokens.Last.Increment()
443 if xe.NeedFlush() {
444 return xe.Flush()
445 }
446 return nil
447 }
448
449 k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers))
450 return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) {
451 return strconv.AppendInt(b, va.Int(), 10), nil
452 })
453 }
454 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
455 xd := export.Decoder(dec)
456 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
457 return newInvalidFormatError(dec, t)
458 }
459 stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers)
460 var flags jsonwire.ValueFlags
461 val, err := xd.ReadValue(&flags)
462 if err != nil {
463 return err
464 }
465 k := val.Kind()
466 switch k {
467 case 'n':
468 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
469 va.SetInt(0)
470 }
471 return nil
472 case '"':
473 if !stringify {
474 break
475 }
476 val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
477 if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
478
479
480
481 n, err := strconv.ParseInt(string(val), 10, bits)
482 if err != nil {
483 if string(val) == "null" {
484 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
485 va.SetInt(0)
486 }
487 return nil
488 }
489 return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err))
490 }
491 va.SetInt(n)
492 return nil
493 }
494 fallthrough
495 case '0':
496 if stringify && k == '0' {
497 break
498 }
499 var negOffset int
500 neg := len(val) > 0 && val[0] == '-'
501 if neg {
502 negOffset = 1
503 }
504 n, ok := jsonwire.ParseUint(val[negOffset:])
505 maxInt := uint64(1) << (bits - 1)
506 overflow := (neg && n > maxInt) || (!neg && n > maxInt-1)
507 if !ok {
508 if n != math.MaxUint64 {
509 return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax)
510 }
511 overflow = true
512 }
513 if overflow {
514 return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange)
515 }
516 if neg {
517 va.SetInt(int64(-n))
518 } else {
519 va.SetInt(int64(+n))
520 }
521 return nil
522 }
523 return newUnmarshalErrorAfter(dec, t, nil)
524 }
525 return &fncs
526 }
527
528 func makeUintArshaler(t reflect.Type) *arshaler {
529 var fncs arshaler
530 bits := t.Bits()
531 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
532 xe := export.Encoder(enc)
533 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
534 return newInvalidFormatError(enc, t)
535 }
536
537
538 if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() {
539 xe.Buf = strconv.AppendUint(xe.Tokens.MayAppendDelim(xe.Buf, '0'), va.Uint(), 10)
540 xe.Tokens.Last.Increment()
541 if xe.NeedFlush() {
542 return xe.Flush()
543 }
544 return nil
545 }
546
547 k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers))
548 return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) {
549 return strconv.AppendUint(b, va.Uint(), 10), nil
550 })
551 }
552 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
553 xd := export.Decoder(dec)
554 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
555 return newInvalidFormatError(dec, t)
556 }
557 stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers)
558 var flags jsonwire.ValueFlags
559 val, err := xd.ReadValue(&flags)
560 if err != nil {
561 return err
562 }
563 k := val.Kind()
564 switch k {
565 case 'n':
566 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
567 va.SetUint(0)
568 }
569 return nil
570 case '"':
571 if !stringify {
572 break
573 }
574 val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
575 if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
576
577
578
579 n, err := strconv.ParseUint(string(val), 10, bits)
580 if err != nil {
581 if string(val) == "null" {
582 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
583 va.SetUint(0)
584 }
585 return nil
586 }
587 return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err))
588 }
589 va.SetUint(n)
590 return nil
591 }
592 fallthrough
593 case '0':
594 if stringify && k == '0' {
595 break
596 }
597 n, ok := jsonwire.ParseUint(val)
598 maxUint := uint64(1) << bits
599 overflow := n > maxUint-1
600 if !ok {
601 if n != math.MaxUint64 {
602 return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax)
603 }
604 overflow = true
605 }
606 if overflow {
607 return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange)
608 }
609 va.SetUint(n)
610 return nil
611 }
612 return newUnmarshalErrorAfter(dec, t, nil)
613 }
614 return &fncs
615 }
616
617 func makeFloatArshaler(t reflect.Type) *arshaler {
618 var fncs arshaler
619 bits := t.Bits()
620 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
621 xe := export.Encoder(enc)
622 var allowNonFinite bool
623 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
624 if mo.Format == "nonfinite" {
625 allowNonFinite = true
626 } else {
627 return newInvalidFormatError(enc, t)
628 }
629 }
630
631 fv := va.Float()
632 if math.IsNaN(fv) || math.IsInf(fv, 0) {
633 if !allowNonFinite {
634 err := fmt.Errorf("unsupported value: %v", fv)
635 return newMarshalErrorBefore(enc, t, err)
636 }
637 return enc.WriteToken(jsontext.Float(fv))
638 }
639
640
641 if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() {
642 xe.Buf = jsonwire.AppendFloat(xe.Tokens.MayAppendDelim(xe.Buf, '0'), fv, bits)
643 xe.Tokens.Last.Increment()
644 if xe.NeedFlush() {
645 return xe.Flush()
646 }
647 return nil
648 }
649
650 k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers))
651 return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) {
652 return jsonwire.AppendFloat(b, va.Float(), bits), nil
653 })
654 }
655 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
656 xd := export.Decoder(dec)
657 var allowNonFinite bool
658 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
659 if uo.Format == "nonfinite" {
660 allowNonFinite = true
661 } else {
662 return newInvalidFormatError(dec, t)
663 }
664 }
665 stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers)
666 var flags jsonwire.ValueFlags
667 val, err := xd.ReadValue(&flags)
668 if err != nil {
669 return err
670 }
671 k := val.Kind()
672 switch k {
673 case 'n':
674 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
675 va.SetFloat(0)
676 }
677 return nil
678 case '"':
679 val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
680 if allowNonFinite {
681 switch string(val) {
682 case "NaN":
683 va.SetFloat(math.NaN())
684 return nil
685 case "Infinity":
686 va.SetFloat(math.Inf(+1))
687 return nil
688 case "-Infinity":
689 va.SetFloat(math.Inf(-1))
690 return nil
691 }
692 }
693 if !stringify {
694 break
695 }
696 if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
697
698
699
700 n, err := strconv.ParseFloat(string(val), bits)
701 if err != nil {
702 if string(val) == "null" {
703 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
704 va.SetFloat(0)
705 }
706 return nil
707 }
708 return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err))
709 }
710 va.SetFloat(n)
711 return nil
712 }
713 if n, err := jsonwire.ConsumeNumber(val); n != len(val) || err != nil {
714 return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax)
715 }
716 fallthrough
717 case '0':
718 if stringify && k == '0' {
719 break
720 }
721 fv, ok := jsonwire.ParseFloat(val, bits)
722 va.SetFloat(fv)
723 if !ok {
724 return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange)
725 }
726 return nil
727 }
728 return newUnmarshalErrorAfter(dec, t, nil)
729 }
730 return &fncs
731 }
732
733 func makeMapArshaler(t reflect.Type) *arshaler {
734
735
736
737
738
739
740
741 var fncs arshaler
742 var (
743 once sync.Once
744 keyFncs *arshaler
745 valFncs *arshaler
746 )
747 init := func() {
748 keyFncs = lookupArshaler(t.Key())
749 valFncs = lookupArshaler(t.Elem())
750 }
751 nillableLegacyKey := t.Key().Kind() == reflect.Pointer &&
752 implementsAny(t.Key(), textMarshalerType, textAppenderType)
753 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
754
755 xe := export.Encoder(enc)
756 if xe.Tokens.Depth() > startDetectingCyclesAfter {
757 if err := visitPointer(&xe.SeenPointers, va.Value); err != nil {
758 return newMarshalErrorBefore(enc, t, err)
759 }
760 defer leavePointer(&xe.SeenPointers, va.Value)
761 }
762
763 emitNull := mo.Flags.Get(jsonflags.FormatNilMapAsNull)
764 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
765 switch mo.Format {
766 case "emitnull":
767 emitNull = true
768 mo.Format = ""
769 case "emitempty":
770 emitNull = false
771 mo.Format = ""
772 default:
773 return newInvalidFormatError(enc, t)
774 }
775 }
776
777
778 n := va.Len()
779 if n == 0 {
780 if emitNull && va.IsNil() {
781 return enc.WriteToken(jsontext.Null)
782 }
783
784 if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() {
785 xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '{'), "{}"...)
786 xe.Tokens.Last.Increment()
787 if xe.NeedFlush() {
788 return xe.Flush()
789 }
790 return nil
791 }
792 }
793
794 once.Do(init)
795 if err := enc.WriteToken(jsontext.BeginObject); err != nil {
796 return err
797 }
798 if n > 0 {
799 nonDefaultKey := keyFncs.nonDefault
800 marshalKey := keyFncs.marshal
801 marshalVal := valFncs.marshal
802 if mo.Marshalers != nil {
803 var ok bool
804 marshalKey, ok = mo.Marshalers.(*Marshalers).lookup(marshalKey, t.Key())
805 marshalVal, _ = mo.Marshalers.(*Marshalers).lookup(marshalVal, t.Elem())
806 nonDefaultKey = nonDefaultKey || ok
807 }
808 k := newAddressableValue(t.Key())
809 v := newAddressableValue(t.Elem())
810
811
812
813
814 if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), mo.Flags.Get(jsonflags.AllowInvalidUTF8)) {
815 xe.Tokens.Last.DisableNamespace()
816 }
817
818 switch {
819 case !mo.Flags.Get(jsonflags.Deterministic) || n <= 1:
820 for iter := va.Value.MapRange(); iter.Next(); {
821 k.SetIterKey(iter)
822 err := marshalKey(enc, k, mo)
823 if err != nil {
824 if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&
825 errors.Is(err, jsontext.ErrNonStringName) && nillableLegacyKey && k.IsNil() {
826 err = enc.WriteToken(jsontext.String(""))
827 }
828 if err != nil {
829 if serr, ok := err.(*jsontext.SyntacticError); ok && serr.Err == jsontext.ErrNonStringName {
830 err = newMarshalErrorBefore(enc, k.Type(), err)
831 }
832 return err
833 }
834 }
835 v.SetIterValue(iter)
836 if err := marshalVal(enc, v, mo); err != nil {
837 return err
838 }
839 }
840 case !nonDefaultKey && t.Key().Kind() == reflect.String:
841 names := getStrings(n)
842 for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ {
843 k.SetIterKey(iter)
844 (*names)[i] = k.String()
845 }
846 slices.Sort(*names)
847 for _, name := range *names {
848 if err := enc.WriteToken(jsontext.String(name)); err != nil {
849 return err
850 }
851
852 k.SetString(name)
853 v.Set(va.MapIndex(k.Value))
854 if err := marshalVal(enc, v, mo); err != nil {
855 return err
856 }
857 }
858 putStrings(names)
859 default:
860 type member struct {
861 name string
862 key addressableValue
863 val addressableValue
864 }
865 members := make([]member, n)
866 keys := reflect.MakeSlice(reflect.SliceOf(t.Key()), n, n)
867 vals := reflect.MakeSlice(reflect.SliceOf(t.Elem()), n, n)
868 for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ {
869
870 k := addressableValue{keys.Index(i), true}
871 k.SetIterKey(iter)
872 v := addressableValue{vals.Index(i), true}
873 v.SetIterValue(iter)
874 err := marshalKey(enc, k, mo)
875 if err != nil {
876 if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&
877 errors.Is(err, jsontext.ErrNonStringName) && nillableLegacyKey && k.IsNil() {
878 err = enc.WriteToken(jsontext.String(""))
879 }
880 if err != nil {
881 if serr, ok := err.(*jsontext.SyntacticError); ok && serr.Err == jsontext.ErrNonStringName {
882 err = newMarshalErrorBefore(enc, k.Type(), err)
883 }
884 return err
885 }
886 }
887 name := xe.UnwriteOnlyObjectMemberName()
888 members[i] = member{name, k, v}
889 }
890
891
892
893 slices.SortFunc(members, func(x, y member) int {
894 return strings.Compare(x.name, y.name)
895 })
896 for _, member := range members {
897 if err := enc.WriteToken(jsontext.String(member.name)); err != nil {
898 return err
899 }
900 if err := marshalVal(enc, member.val, mo); err != nil {
901 return err
902 }
903 }
904 }
905 }
906 if err := enc.WriteToken(jsontext.EndObject); err != nil {
907 return err
908 }
909 return nil
910 }
911 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
912 xd := export.Decoder(dec)
913 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
914 switch uo.Format {
915 case "emitnull", "emitempty":
916 uo.Format = ""
917 default:
918 return newInvalidFormatError(dec, t)
919 }
920 }
921 tok, err := dec.ReadToken()
922 if err != nil {
923 return err
924 }
925 k := tok.Kind()
926 switch k {
927 case 'n':
928 va.SetZero()
929 return nil
930 case '{':
931 once.Do(init)
932 if va.IsNil() {
933 va.Set(reflect.MakeMap(t))
934 }
935
936 nonDefaultKey := keyFncs.nonDefault
937 unmarshalKey := keyFncs.unmarshal
938 unmarshalVal := valFncs.unmarshal
939 if uo.Unmarshalers != nil {
940 var ok bool
941 unmarshalKey, ok = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshalKey, t.Key())
942 unmarshalVal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshalVal, t.Elem())
943 nonDefaultKey = nonDefaultKey || ok
944 }
945 k := newAddressableValue(t.Key())
946 v := newAddressableValue(t.Elem())
947
948
949
950
951
952
953
954 if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), uo.Flags.Get(jsonflags.AllowInvalidUTF8)) {
955 xd.Tokens.Last.DisableNamespace()
956 }
957
958
959
960
961
962 var seen reflect.Value
963 if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && va.Len() > 0 {
964 seen = reflect.MakeMap(reflect.MapOf(k.Type(), emptyStructType))
965 }
966
967 var errUnmarshal error
968 for dec.PeekKind() != '}' {
969
970 k.SetZero()
971 err := unmarshalKey(dec, k, uo)
972 if err != nil {
973 if isFatalError(err, uo.Flags) {
974 return err
975 }
976 if err := dec.SkipValue(); err != nil {
977 return err
978 }
979 errUnmarshal = cmp.Or(errUnmarshal, err)
980 continue
981 }
982 if k.Kind() == reflect.Interface && !k.IsNil() && !k.Elem().Type().Comparable() {
983 err := newUnmarshalErrorAfter(dec, t, fmt.Errorf("invalid incomparable key type %v", k.Elem().Type()))
984 if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
985 return err
986 }
987 if err2 := dec.SkipValue(); err2 != nil {
988 return err2
989 }
990 errUnmarshal = cmp.Or(errUnmarshal, err)
991 continue
992 }
993
994
995 if v2 := va.MapIndex(k.Value); v2.IsValid() {
996 if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && (!seen.IsValid() || seen.MapIndex(k.Value).IsValid()) {
997
998 name := xd.PreviousTokenOrValue()
999 return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(name))
1000 }
1001 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
1002 v.Set(v2)
1003 } else {
1004 v.SetZero()
1005 }
1006 } else {
1007 v.SetZero()
1008 }
1009
1010
1011 err = unmarshalVal(dec, v, uo)
1012 va.SetMapIndex(k.Value, v.Value)
1013 if seen.IsValid() {
1014 seen.SetMapIndex(k.Value, reflect.Zero(emptyStructType))
1015 }
1016 if err != nil {
1017 if isFatalError(err, uo.Flags) {
1018 return err
1019 }
1020 errUnmarshal = cmp.Or(errUnmarshal, err)
1021 }
1022 }
1023 if _, err := dec.ReadToken(); err != nil {
1024 return err
1025 }
1026 return errUnmarshal
1027 }
1028 return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
1029 }
1030 return &fncs
1031 }
1032
1033
1034
1035
1036
1037 func mapKeyWithUniqueRepresentation(k reflect.Kind, allowInvalidUTF8 bool) bool {
1038 switch k {
1039 case reflect.Bool,
1040 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
1041 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1042 return true
1043 case reflect.String:
1044
1045
1046 return !allowInvalidUTF8
1047 default:
1048
1049
1050 return false
1051 }
1052 }
1053
1054 var errNilField = errors.New("cannot set embedded pointer to unexported struct type")
1055
1056 func makeStructArshaler(t reflect.Type) *arshaler {
1057
1058
1059
1060
1061 var fncs arshaler
1062 var (
1063 once sync.Once
1064 fields structFields
1065 errInit *SemanticError
1066 )
1067 init := func() {
1068 fields, errInit = makeStructFields(t)
1069 }
1070 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
1071 xe := export.Encoder(enc)
1072 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
1073 return newInvalidFormatError(enc, t)
1074 }
1075 once.Do(init)
1076 if errInit != nil && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
1077 return newMarshalErrorBefore(enc, errInit.GoType, errInit.Err)
1078 }
1079 if err := enc.WriteToken(jsontext.BeginObject); err != nil {
1080 return err
1081 }
1082 var seenIdxs uintSet
1083 prevIdx := -1
1084 xe.Tokens.Last.DisableNamespace()
1085 for i := range fields.flattened {
1086 f := &fields.flattened[i]
1087 v := addressableValue{va.Field(f.index0), va.forcedAddr}
1088 if len(f.index) > 0 {
1089 v = v.fieldByIndex(f.index, false)
1090 if !v.IsValid() {
1091 continue
1092 }
1093 }
1094
1095
1096
1097 if (f.omitzero || mo.Flags.Get(jsonflags.OmitZeroStructFields)) &&
1098 ((f.isZero == nil && v.IsZero()) || (f.isZero != nil && f.isZero(v))) {
1099 continue
1100 }
1101
1102
1103 if f.omitempty && mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) && isLegacyEmpty(v) {
1104 continue
1105 }
1106
1107 marshal := f.fncs.marshal
1108 nonDefault := f.fncs.nonDefault
1109 if mo.Marshalers != nil {
1110 var ok bool
1111 marshal, ok = mo.Marshalers.(*Marshalers).lookup(marshal, f.typ)
1112 nonDefault = nonDefault || ok
1113 }
1114
1115
1116
1117
1118 if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) &&
1119 !nonDefault && f.isEmpty != nil && f.isEmpty(v) {
1120 continue
1121 }
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133 if optimizeCommon {
1134
1135 b := xe.Buf
1136 if xe.Tokens.Last.Length() > 0 {
1137 b = append(b, ',')
1138 if mo.Flags.Get(jsonflags.SpaceAfterComma) {
1139 b = append(b, ' ')
1140 }
1141 }
1142 if mo.Flags.Get(jsonflags.Multiline) {
1143 b = xe.AppendIndent(b, xe.Tokens.NeedIndent('"'))
1144 }
1145
1146
1147 n0 := len(b)
1148 if !f.nameNeedEscape {
1149 b = append(b, f.quotedName...)
1150 } else {
1151 b, _ = jsonwire.AppendQuote(b, f.name, &mo.Flags)
1152 }
1153 xe.Buf = b
1154 xe.Names.ReplaceLastQuotedOffset(n0)
1155 xe.Tokens.Last.Increment()
1156 } else {
1157 if err := enc.WriteToken(jsontext.String(f.name)); err != nil {
1158 return err
1159 }
1160 }
1161
1162
1163 flagsOriginal := mo.Flags
1164 if f.string {
1165 if !mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
1166 mo.Flags.Set(jsonflags.StringifyNumbers | 1)
1167 } else if canLegacyStringify(f.typ) {
1168 mo.Flags.Set(jsonflags.StringifyNumbers | jsonflags.StringifyBoolsAndStrings | 1)
1169 }
1170 }
1171 if f.format != "" {
1172 mo.FormatDepth = xe.Tokens.Depth()
1173 mo.Format = f.format
1174 }
1175 err := marshal(enc, v, mo)
1176 mo.Flags = flagsOriginal
1177 mo.Format = ""
1178 if err != nil {
1179 return err
1180 }
1181
1182
1183 if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) {
1184 var prevName *string
1185 if prevIdx >= 0 {
1186 prevName = &fields.flattened[prevIdx].name
1187 }
1188 if xe.UnwriteEmptyObjectMember(prevName) {
1189 continue
1190 }
1191 }
1192
1193
1194
1195
1196 if !mo.Flags.Get(jsonflags.AllowDuplicateNames) && fields.inlinedFallback != nil {
1197 seenIdxs.insert(uint(f.id))
1198 }
1199 prevIdx = f.id
1200 }
1201 if fields.inlinedFallback != nil && !(mo.Flags.Get(jsonflags.DiscardUnknownMembers) && fields.inlinedFallback.unknown) {
1202 var insertUnquotedName func([]byte) bool
1203 if !mo.Flags.Get(jsonflags.AllowDuplicateNames) {
1204 insertUnquotedName = func(name []byte) bool {
1205
1206
1207 if foldedFields := fields.lookupByFoldedName(name); len(foldedFields) > 0 {
1208 if f := fields.byActualName[string(name)]; f != nil {
1209 return seenIdxs.insert(uint(f.id))
1210 }
1211 for _, f := range foldedFields {
1212 if f.matchFoldedName(name, &mo.Flags) {
1213 return seenIdxs.insert(uint(f.id))
1214 }
1215 }
1216 }
1217
1218
1219
1220 return xe.Namespaces.Last().InsertUnquoted(name)
1221 }
1222 }
1223 if err := marshalInlinedFallbackAll(enc, va, mo, fields.inlinedFallback, insertUnquotedName); err != nil {
1224 return err
1225 }
1226 }
1227 if err := enc.WriteToken(jsontext.EndObject); err != nil {
1228 return err
1229 }
1230 return nil
1231 }
1232 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
1233 xd := export.Decoder(dec)
1234 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
1235 return newInvalidFormatError(dec, t)
1236 }
1237 tok, err := dec.ReadToken()
1238 if err != nil {
1239 return err
1240 }
1241 k := tok.Kind()
1242 switch k {
1243 case 'n':
1244 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
1245 va.SetZero()
1246 }
1247 return nil
1248 case '{':
1249 once.Do(init)
1250 if errInit != nil && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
1251 return newUnmarshalErrorAfter(dec, errInit.GoType, errInit.Err)
1252 }
1253 var seenIdxs uintSet
1254 xd.Tokens.Last.DisableNamespace()
1255 var errUnmarshal error
1256 for dec.PeekKind() != '}' {
1257
1258 var flags jsonwire.ValueFlags
1259 val, err := xd.ReadValue(&flags)
1260 if err != nil {
1261 return err
1262 }
1263 name := jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
1264 f := fields.byActualName[string(name)]
1265 if f == nil {
1266 for _, f2 := range fields.lookupByFoldedName(name) {
1267 if f2.matchFoldedName(name, &uo.Flags) {
1268 f = f2
1269 break
1270 }
1271 }
1272 if f == nil {
1273 if uo.Flags.Get(jsonflags.RejectUnknownMembers) && (fields.inlinedFallback == nil || fields.inlinedFallback.unknown) {
1274 err := newUnmarshalErrorAfter(dec, t, ErrUnknownName)
1275 if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
1276 return err
1277 }
1278 errUnmarshal = cmp.Or(errUnmarshal, err)
1279 }
1280 if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && !xd.Namespaces.Last().InsertUnquoted(name) {
1281
1282 return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val))
1283 }
1284
1285 if fields.inlinedFallback == nil {
1286
1287 if err := dec.SkipValue(); err != nil {
1288 return err
1289 }
1290 } else {
1291
1292 if err := unmarshalInlinedFallbackNext(dec, va, uo, fields.inlinedFallback, val, name); err != nil {
1293 if isFatalError(err, uo.Flags) {
1294 return err
1295 }
1296 errUnmarshal = cmp.Or(errUnmarshal, err)
1297 }
1298 }
1299 continue
1300 }
1301 }
1302 if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && !seenIdxs.insert(uint(f.id)) {
1303
1304 return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val))
1305 }
1306
1307
1308 unmarshal := f.fncs.unmarshal
1309 if uo.Unmarshalers != nil {
1310 unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, f.typ)
1311 }
1312 flagsOriginal := uo.Flags
1313 if f.string {
1314 if !uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
1315 uo.Flags.Set(jsonflags.StringifyNumbers | 1)
1316 } else if canLegacyStringify(f.typ) {
1317 uo.Flags.Set(jsonflags.StringifyNumbers | jsonflags.StringifyBoolsAndStrings | 1)
1318 }
1319 }
1320 if f.format != "" {
1321 uo.FormatDepth = xd.Tokens.Depth()
1322 uo.Format = f.format
1323 }
1324 v := addressableValue{va.Field(f.index0), va.forcedAddr}
1325 if len(f.index) > 0 {
1326 v = v.fieldByIndex(f.index, true)
1327 if !v.IsValid() {
1328 err := newUnmarshalErrorBefore(dec, t, errNilField)
1329 if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
1330 return err
1331 }
1332 errUnmarshal = cmp.Or(errUnmarshal, err)
1333 unmarshal = func(dec *jsontext.Decoder, _ addressableValue, _ *jsonopts.Struct) error {
1334 return dec.SkipValue()
1335 }
1336 }
1337 }
1338 err = unmarshal(dec, v, uo)
1339 uo.Flags = flagsOriginal
1340 uo.Format = ""
1341 if err != nil {
1342 if isFatalError(err, uo.Flags) {
1343 return err
1344 }
1345 errUnmarshal = cmp.Or(errUnmarshal, err)
1346 }
1347 }
1348 if _, err := dec.ReadToken(); err != nil {
1349 return err
1350 }
1351 return errUnmarshal
1352 }
1353 return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
1354 }
1355 return &fncs
1356 }
1357
1358 func (va addressableValue) fieldByIndex(index []int, mayAlloc bool) addressableValue {
1359 for _, i := range index {
1360 va = va.indirect(mayAlloc)
1361 if !va.IsValid() {
1362 return va
1363 }
1364 va = addressableValue{va.Field(i), va.forcedAddr}
1365 }
1366 return va
1367 }
1368
1369 func (va addressableValue) indirect(mayAlloc bool) addressableValue {
1370 if va.Kind() == reflect.Pointer {
1371 if va.IsNil() {
1372 if !mayAlloc || !va.CanSet() {
1373 return addressableValue{}
1374 }
1375 va.Set(reflect.New(va.Type().Elem()))
1376 }
1377 va = addressableValue{va.Elem(), false}
1378 }
1379 return va
1380 }
1381
1382
1383 func isLegacyEmpty(v addressableValue) bool {
1384
1385 switch v.Kind() {
1386 case reflect.Bool:
1387 return v.Bool() == false
1388 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1389 return v.Int() == 0
1390 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1391 return v.Uint() == 0
1392 case reflect.Float32, reflect.Float64:
1393 return v.Float() == 0
1394 case reflect.String, reflect.Map, reflect.Slice, reflect.Array:
1395 return v.Len() == 0
1396 case reflect.Pointer, reflect.Interface:
1397 return v.IsNil()
1398 }
1399 return false
1400 }
1401
1402
1403
1404
1405
1406 func canLegacyStringify(t reflect.Type) bool {
1407
1408 if t.Name() == "" && t.Kind() == reflect.Ptr {
1409 t = t.Elem()
1410 }
1411 switch t.Kind() {
1412 case reflect.Bool, reflect.String,
1413 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
1414 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
1415 reflect.Float32, reflect.Float64:
1416 return true
1417 }
1418 return false
1419 }
1420
1421 func makeSliceArshaler(t reflect.Type) *arshaler {
1422 var fncs arshaler
1423 var (
1424 once sync.Once
1425 valFncs *arshaler
1426 )
1427 init := func() {
1428 valFncs = lookupArshaler(t.Elem())
1429 }
1430 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
1431
1432 xe := export.Encoder(enc)
1433 if xe.Tokens.Depth() > startDetectingCyclesAfter {
1434 if err := visitPointer(&xe.SeenPointers, va.Value); err != nil {
1435 return newMarshalErrorBefore(enc, t, err)
1436 }
1437 defer leavePointer(&xe.SeenPointers, va.Value)
1438 }
1439
1440 emitNull := mo.Flags.Get(jsonflags.FormatNilSliceAsNull)
1441 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
1442 switch mo.Format {
1443 case "emitnull":
1444 emitNull = true
1445 mo.Format = ""
1446 case "emitempty":
1447 emitNull = false
1448 mo.Format = ""
1449 default:
1450 return newInvalidFormatError(enc, t)
1451 }
1452 }
1453
1454
1455 n := va.Len()
1456 if n == 0 {
1457 if emitNull && va.IsNil() {
1458 return enc.WriteToken(jsontext.Null)
1459 }
1460
1461 if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() {
1462 xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '['), "[]"...)
1463 xe.Tokens.Last.Increment()
1464 if xe.NeedFlush() {
1465 return xe.Flush()
1466 }
1467 return nil
1468 }
1469 }
1470
1471 once.Do(init)
1472 if err := enc.WriteToken(jsontext.BeginArray); err != nil {
1473 return err
1474 }
1475 marshal := valFncs.marshal
1476 if mo.Marshalers != nil {
1477 marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem())
1478 }
1479 for i := range n {
1480 v := addressableValue{va.Index(i), false}
1481 if err := marshal(enc, v, mo); err != nil {
1482 return err
1483 }
1484 }
1485 if err := enc.WriteToken(jsontext.EndArray); err != nil {
1486 return err
1487 }
1488 return nil
1489 }
1490 emptySlice := reflect.MakeSlice(t, 0, 0)
1491 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
1492 xd := export.Decoder(dec)
1493 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
1494 switch uo.Format {
1495 case "emitnull", "emitempty":
1496 uo.Format = ""
1497 default:
1498 return newInvalidFormatError(dec, t)
1499 }
1500 }
1501
1502 tok, err := dec.ReadToken()
1503 if err != nil {
1504 return err
1505 }
1506 k := tok.Kind()
1507 switch k {
1508 case 'n':
1509 va.SetZero()
1510 return nil
1511 case '[':
1512 once.Do(init)
1513 unmarshal := valFncs.unmarshal
1514 if uo.Unmarshalers != nil {
1515 unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem())
1516 }
1517 mustZero := true
1518 cap := va.Cap()
1519 if cap > 0 {
1520 va.SetLen(cap)
1521 }
1522 var i int
1523 var errUnmarshal error
1524 for dec.PeekKind() != ']' {
1525 if i == cap {
1526 va.Value.Grow(1)
1527 cap = va.Cap()
1528 va.SetLen(cap)
1529 mustZero = false
1530 }
1531 v := addressableValue{va.Index(i), false}
1532 i++
1533 if mustZero && !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
1534 v.SetZero()
1535 }
1536 if err := unmarshal(dec, v, uo); err != nil {
1537 if isFatalError(err, uo.Flags) {
1538 va.SetLen(i)
1539 return err
1540 }
1541 errUnmarshal = cmp.Or(errUnmarshal, err)
1542 }
1543 }
1544 if i == 0 {
1545 va.Set(emptySlice)
1546 } else {
1547 va.SetLen(i)
1548 }
1549 if _, err := dec.ReadToken(); err != nil {
1550 return err
1551 }
1552 return errUnmarshal
1553 }
1554 return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
1555 }
1556 return &fncs
1557 }
1558
1559 var errArrayUnderflow = errors.New("too few array elements")
1560 var errArrayOverflow = errors.New("too many array elements")
1561
1562 func makeArrayArshaler(t reflect.Type) *arshaler {
1563 var fncs arshaler
1564 var (
1565 once sync.Once
1566 valFncs *arshaler
1567 )
1568 init := func() {
1569 valFncs = lookupArshaler(t.Elem())
1570 }
1571 n := t.Len()
1572 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
1573 xe := export.Encoder(enc)
1574 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
1575 return newInvalidFormatError(enc, t)
1576 }
1577 once.Do(init)
1578 if err := enc.WriteToken(jsontext.BeginArray); err != nil {
1579 return err
1580 }
1581 marshal := valFncs.marshal
1582 if mo.Marshalers != nil {
1583 marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem())
1584 }
1585 for i := range n {
1586 v := addressableValue{va.Index(i), va.forcedAddr}
1587 if err := marshal(enc, v, mo); err != nil {
1588 return err
1589 }
1590 }
1591 if err := enc.WriteToken(jsontext.EndArray); err != nil {
1592 return err
1593 }
1594 return nil
1595 }
1596 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
1597 xd := export.Decoder(dec)
1598 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
1599 return newInvalidFormatError(dec, t)
1600 }
1601 tok, err := dec.ReadToken()
1602 if err != nil {
1603 return err
1604 }
1605 k := tok.Kind()
1606 switch k {
1607 case 'n':
1608 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
1609 va.SetZero()
1610 }
1611 return nil
1612 case '[':
1613 once.Do(init)
1614 unmarshal := valFncs.unmarshal
1615 if uo.Unmarshalers != nil {
1616 unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem())
1617 }
1618 var i int
1619 var errUnmarshal error
1620 for dec.PeekKind() != ']' {
1621 if i >= n {
1622 if err := dec.SkipValue(); err != nil {
1623 return err
1624 }
1625 err = errArrayOverflow
1626 continue
1627 }
1628 v := addressableValue{va.Index(i), va.forcedAddr}
1629 if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
1630 v.SetZero()
1631 }
1632 if err := unmarshal(dec, v, uo); err != nil {
1633 if isFatalError(err, uo.Flags) {
1634 return err
1635 }
1636 errUnmarshal = cmp.Or(errUnmarshal, err)
1637 }
1638 i++
1639 }
1640 for ; i < n; i++ {
1641 va.Index(i).SetZero()
1642 err = errArrayUnderflow
1643 }
1644 if _, err := dec.ReadToken(); err != nil {
1645 return err
1646 }
1647 if err != nil && !uo.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) {
1648 return newUnmarshalErrorAfter(dec, t, err)
1649 }
1650 return errUnmarshal
1651 }
1652 return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
1653 }
1654 return &fncs
1655 }
1656
1657 func makePointerArshaler(t reflect.Type) *arshaler {
1658 var fncs arshaler
1659 var (
1660 once sync.Once
1661 valFncs *arshaler
1662 )
1663 init := func() {
1664 valFncs = lookupArshaler(t.Elem())
1665 }
1666 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
1667
1668 xe := export.Encoder(enc)
1669 if xe.Tokens.Depth() > startDetectingCyclesAfter {
1670 if err := visitPointer(&xe.SeenPointers, va.Value); err != nil {
1671 return newMarshalErrorBefore(enc, t, err)
1672 }
1673 defer leavePointer(&xe.SeenPointers, va.Value)
1674 }
1675
1676
1677 if va.IsNil() {
1678 return enc.WriteToken(jsontext.Null)
1679 }
1680 once.Do(init)
1681 marshal := valFncs.marshal
1682 if mo.Marshalers != nil {
1683 marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem())
1684 }
1685 v := addressableValue{va.Elem(), false}
1686 return marshal(enc, v, mo)
1687 }
1688 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
1689
1690 if dec.PeekKind() == 'n' {
1691 if _, err := dec.ReadToken(); err != nil {
1692 return err
1693 }
1694 va.SetZero()
1695 return nil
1696 }
1697 once.Do(init)
1698 unmarshal := valFncs.unmarshal
1699 if uo.Unmarshalers != nil {
1700 unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem())
1701 }
1702 if va.IsNil() {
1703 va.Set(reflect.New(t.Elem()))
1704 }
1705 v := addressableValue{va.Elem(), false}
1706 if err := unmarshal(dec, v, uo); err != nil {
1707 return err
1708 }
1709 if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) &&
1710 uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringifyBoolsAndStrings) {
1711
1712
1713
1714
1715
1716
1717 if string(export.Decoder(dec).PreviousTokenOrValue()) == `"null"` {
1718 va.SetZero()
1719 }
1720 }
1721 return nil
1722 }
1723 return &fncs
1724 }
1725
1726 func makeInterfaceArshaler(t reflect.Type) *arshaler {
1727
1728
1729
1730
1731 var fncs arshaler
1732 var whichMarshaler reflect.Type
1733 for _, iface := range allMarshalerTypes {
1734 if t.Implements(iface) {
1735 whichMarshaler = t
1736 break
1737 }
1738 }
1739 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
1740 xe := export.Encoder(enc)
1741 if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() {
1742 return newInvalidFormatError(enc, t)
1743 }
1744 if va.IsNil() {
1745 return enc.WriteToken(jsontext.Null)
1746 } else if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && whichMarshaler != nil {
1747
1748
1749
1750 if va.Elem().Kind() == reflect.Pointer && va.Elem().IsNil() {
1751 v2 := newAddressableValue(whichMarshaler)
1752 switch whichMarshaler {
1753 case jsonMarshalerToType:
1754 v2.Set(reflect.ValueOf(struct{ MarshalerTo }{va.Elem().Interface().(MarshalerTo)}))
1755 case jsonMarshalerType:
1756 v2.Set(reflect.ValueOf(struct{ Marshaler }{va.Elem().Interface().(Marshaler)}))
1757 case textAppenderType:
1758 v2.Set(reflect.ValueOf(struct{ encoding.TextAppender }{va.Elem().Interface().(encoding.TextAppender)}))
1759 case textMarshalerType:
1760 v2.Set(reflect.ValueOf(struct{ encoding.TextMarshaler }{va.Elem().Interface().(encoding.TextMarshaler)}))
1761 }
1762 va = v2
1763 }
1764 }
1765 v := newAddressableValue(va.Elem().Type())
1766 v.Set(va.Elem())
1767 marshal := lookupArshaler(v.Type()).marshal
1768 if mo.Marshalers != nil {
1769 marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, v.Type())
1770 }
1771
1772 if optimizeCommon &&
1773 t == anyType && !mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringifyBoolsAndStrings) && mo.Format == "" &&
1774 (mo.Marshalers == nil || !mo.Marshalers.(*Marshalers).fromAny) {
1775 return marshalValueAny(enc, va.Elem().Interface(), mo)
1776 }
1777 return marshal(enc, v, mo)
1778 }
1779 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
1780 xd := export.Decoder(dec)
1781 if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() {
1782 return newInvalidFormatError(dec, t)
1783 }
1784 if uo.Flags.Get(jsonflags.MergeWithLegacySemantics) && !va.IsNil() {
1785
1786
1787
1788
1789
1790 e := va.Elem()
1791 if e.Kind() == reflect.Pointer && !e.IsNil() {
1792 if dec.PeekKind() == 'n' && e.Elem().Kind() == reflect.Pointer {
1793 if _, err := dec.ReadToken(); err != nil {
1794 return err
1795 }
1796 va.Elem().Elem().SetZero()
1797 return nil
1798 }
1799 } else {
1800 va.SetZero()
1801 }
1802 }
1803 if dec.PeekKind() == 'n' {
1804 if _, err := dec.ReadToken(); err != nil {
1805 return err
1806 }
1807 va.SetZero()
1808 return nil
1809 }
1810 var v addressableValue
1811 if va.IsNil() {
1812
1813
1814
1815
1816
1817 if optimizeCommon &&
1818 t == anyType && !uo.Flags.Get(jsonflags.AllowDuplicateNames) && uo.Format == "" &&
1819 (uo.Unmarshalers == nil || !uo.Unmarshalers.(*Unmarshalers).fromAny) {
1820 v, err := unmarshalValueAny(dec, uo)
1821
1822
1823 if v != nil {
1824 va.Set(reflect.ValueOf(v))
1825 }
1826 return err
1827 }
1828
1829 k := dec.PeekKind()
1830 if !isAnyType(t) {
1831 return newUnmarshalErrorBeforeWithSkipping(dec, t, internal.ErrNilInterface)
1832 }
1833 switch k {
1834 case 'f', 't':
1835 v = newAddressableValue(boolType)
1836 case '"':
1837 v = newAddressableValue(stringType)
1838 case '0':
1839 if uo.Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) {
1840 v = addressableValue{reflect.ValueOf(internal.NewRawNumber()).Elem(), true}
1841 } else {
1842 v = newAddressableValue(float64Type)
1843 }
1844 case '{':
1845 v = newAddressableValue(mapStringAnyType)
1846 case '[':
1847 v = newAddressableValue(sliceAnyType)
1848 default:
1849
1850
1851
1852
1853 _, err := dec.ReadValue()
1854 return err
1855 }
1856 } else {
1857
1858
1859
1860 v = newAddressableValue(va.Elem().Type())
1861 v.Set(va.Elem())
1862 }
1863 unmarshal := lookupArshaler(v.Type()).unmarshal
1864 if uo.Unmarshalers != nil {
1865 unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, v.Type())
1866 }
1867 err := unmarshal(dec, v, uo)
1868 va.Set(v.Value)
1869 return err
1870 }
1871 return &fncs
1872 }
1873
1874
1875 func isAnyType(t reflect.Type) bool {
1876
1877
1878
1879
1880 return t == anyType || anyType.Implements(t)
1881 }
1882
1883 func makeInvalidArshaler(t reflect.Type) *arshaler {
1884 var fncs arshaler
1885 fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
1886 return newMarshalErrorBefore(enc, t, nil)
1887 }
1888 fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
1889 return newUnmarshalErrorBefore(dec, t, nil)
1890 }
1891 return &fncs
1892 }
1893
1894 func stringOrNumberKind(isString bool) jsontext.Kind {
1895 if isString {
1896 return '"'
1897 } else {
1898 return '0'
1899 }
1900 }
1901
1902 type uintSet64 uint64
1903
1904 func (s uintSet64) has(i uint) bool { return s&(1<<i) > 0 }
1905 func (s *uintSet64) set(i uint) { *s |= 1 << i }
1906
1907
1908
1909 type uintSet struct {
1910 lo uintSet64
1911 hi []uintSet64
1912 }
1913
1914
1915 func (s *uintSet) has(i uint) bool {
1916 if i < 64 {
1917 return s.lo.has(i)
1918 } else {
1919 i -= 64
1920 iHi, iLo := int(i/64), i%64
1921 return iHi < len(s.hi) && s.hi[iHi].has(iLo)
1922 }
1923 }
1924
1925
1926 func (s *uintSet) insert(i uint) bool {
1927
1928 if i < 64 {
1929 has := s.lo.has(i)
1930 s.lo.set(i)
1931 return !has
1932 } else {
1933 i -= 64
1934 iHi, iLo := int(i/64), i%64
1935 if iHi >= len(s.hi) {
1936 s.hi = append(s.hi, make([]uintSet64, iHi+1-len(s.hi))...)
1937 s.hi = s.hi[:cap(s.hi)]
1938 }
1939 has := s.hi[iHi].has(iLo)
1940 s.hi[iHi].set(iLo)
1941 return !has
1942 }
1943 }
1944
View as plain text