Source file src/encoding/json/v2/arshal_default.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build goexperiment.jsonv2
     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  // optimizeCommon specifies whether to use optimizations targeted for certain
    33  // common patterns, rather than using the slower, but more general logic.
    34  // All tests should pass regardless of whether this is true or not.
    35  const optimizeCommon = true
    36  
    37  var (
    38  	// Most natural Go type that correspond with each JSON type.
    39  	anyType          = reflect.TypeFor[any]()            // JSON value
    40  	boolType         = reflect.TypeFor[bool]()           // JSON bool
    41  	stringType       = reflect.TypeFor[string]()         // JSON string
    42  	float64Type      = reflect.TypeFor[float64]()        // JSON number
    43  	mapStringAnyType = reflect.TypeFor[map[string]any]() // JSON object
    44  	sliceAnyType     = reflect.TypeFor[[]any]()          // JSON array
    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 // always stores unsafe.Pointer, but avoids depending on unsafe
    57  	len int // remember slice length to avoid false positives
    58  }
    59  
    60  // visitPointer visits pointer p of type t, reporting an error if seen before.
    61  // If successfully visited, then the caller must eventually call leave.
    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  		// Optimize for marshaling without preceding whitespace.
   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  		// Optimize for marshaling without preceding whitespace.
   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  			// Otherwise, the string contains invalid UTF-8,
   221  			// so let the logic below construct the proper error.
   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  	// NOTE: This handles both []~byte and [N]~byte.
   300  	// The v2 default is to treat a []namedByte as equivalent to []T
   301  	// since being able to convert []namedByte to []byte relies on
   302  	// dubious Go reflection behavior (see https://go.dev/issue/24746).
   303  	// For v1 emulation, we use jsonflags.FormatBytesWithLegacySemantics
   304  	// to forcibly treat []namedByte as a []byte.
   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) // treat as []T or [N]T
   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  			// TODO: Provide a "emitempty" format override?
   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) // treat as []T or [N]T
   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  			// NOTE: The v2 default is to strictly comply with RFC 4648.
   389  			// Section 3.2 specifies that padding is required.
   390  			// Section 3.3 specifies that non-alphabet characters
   391  			// (e.g., '\r' or '\n') must be rejected.
   392  			// Section 3.5 specifies that unnecessary non-zero bits in
   393  			// the last quantum may be rejected. Since this is optional,
   394  			// we do not reject such inputs.
   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  				// TODO(https://go.dev/issue/53845): RFC 4648, section 3.3,
   402  				// specifies that non-alphabet characters must be rejected.
   403  				// Unfortunately, the "base32" and "base64" packages allow
   404  				// '\r' and '\n' characters by default.
   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):]) // noop if len(b) <= len(dst)
   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  		// Optimize for marshaling without preceding whitespace or string escaping.
   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  				// For historical reasons, v1 parsed a quoted number
   479  				// according to the Go syntax and permitted a quoted null.
   480  				// See https://go.dev/issue/75619
   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  		// Optimize for marshaling without preceding whitespace or string escaping.
   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  				// For historical reasons, v1 parsed a quoted number
   577  				// according to the Go syntax and permitted a quoted null.
   578  				// See https://go.dev/issue/75619
   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  		// Optimize for marshaling without preceding whitespace or string escaping.
   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  				// For historical reasons, v1 parsed a quoted number
   698  				// according to the Go syntax and permitted a quoted null.
   699  				// See https://go.dev/issue/75619
   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  	// NOTE: The logic below disables namespaces for tracking duplicate names
   735  	// when handling map keys with a unique representation.
   736  
   737  	// NOTE: Values retrieved from a map are not addressable,
   738  	// so we shallow copy the values to make them addressable and
   739  	// store them back into the map afterwards.
   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  		// Check for cycles.
   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  		// Handle empty maps.
   778  		n := va.Len()
   779  		if n == 0 {
   780  			if emitNull && va.IsNil() {
   781  				return enc.WriteToken(jsontext.Null)
   782  			}
   783  			// Optimize for marshaling an empty map without any preceding whitespace.
   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  			// A Go map guarantees that each entry has a unique key.
   812  			// As such, disable the expensive duplicate name check if we know
   813  			// that every Go key will serialize as a unique JSON string.
   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  					// TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf.
   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 // unquoted name
   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  					// Marshal the member name.
   870  					k := addressableValue{keys.Index(i), true} // indexed slice element is always addressable
   871  					k.SetIterKey(iter)
   872  					v := addressableValue{vals.Index(i), true} // indexed slice element is always addressable
   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  				// TODO: If AllowDuplicateNames is enabled, then sort according
   891  				// to reflect.Value as well if the names are equal.
   892  				// See internal/fmtsort.
   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 = "" // only relevant for marshaling
   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  			// Manually check for duplicate entries by virtue of whether the
   949  			// unmarshaled key already exists in the destination Go map.
   950  			// Consequently, syntactically different names (e.g., "0" and "-0")
   951  			// will be rejected as duplicates since they semantically refer
   952  			// to the same Go value. This is an unusual interaction
   953  			// between syntax and semantics, but is more correct.
   954  			if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), uo.Flags.Get(jsonflags.AllowInvalidUTF8)) {
   955  				xd.Tokens.Last.DisableNamespace()
   956  			}
   957  
   958  			// In the rare case where the map is not already empty,
   959  			// then we need to manually track which keys we already saw
   960  			// since existing presence alone is insufficient to indicate
   961  			// whether the input had a duplicate name.
   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  				// Unmarshal the map entry key.
   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  				// Check if a pre-existing map entry value exists for this key.
   995  				if v2 := va.MapIndex(k.Value); v2.IsValid() {
   996  					if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && (!seen.IsValid() || seen.MapIndex(k.Value).IsValid()) {
   997  						// TODO: Unread the object name.
   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  				// Unmarshal the map entry value.
  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  // mapKeyWithUniqueRepresentation reports whether all possible values of k
  1034  // marshal to a different JSON value, and whether all possible JSON values
  1035  // that can unmarshal into k unmarshal to different Go values.
  1036  // In other words, the representation must be a bijective.
  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  		// For strings, we have to be careful since names with invalid UTF-8
  1045  		// maybe unescape to the same Go string value.
  1046  		return !allowInvalidUTF8
  1047  	default:
  1048  		// Floating-point kinds are not listed above since NaNs
  1049  		// can appear multiple times and all serialize as "NaN".
  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  	// NOTE: The logic below disables namespaces for tracking duplicate names
  1058  	// and does the tracking locally with an efficient bit-set based on which
  1059  	// Go struct fields were seen.
  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() // we manually ensure unique names below
  1085  		for i := range fields.flattened {
  1086  			f := &fields.flattened[i]
  1087  			v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable
  1088  			if len(f.index) > 0 {
  1089  				v = v.fieldByIndex(f.index, false)
  1090  				if !v.IsValid() {
  1091  					continue // implies a nil inlined field
  1092  				}
  1093  			}
  1094  
  1095  			// OmitZero skips the field if the Go value is zero,
  1096  			// which we can determine up front without calling the marshaler.
  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  			// Check for the legacy definition of omitempty.
  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  			// OmitEmpty skips the field if the marshaled JSON value is empty,
  1116  			// which we can know up front if there are no custom marshalers,
  1117  			// otherwise we must marshal the value and unwrite it if empty.
  1118  			if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) &&
  1119  				!nonDefault && f.isEmpty != nil && f.isEmpty(v) {
  1120  				continue // fast path for omitempty
  1121  			}
  1122  
  1123  			// Write the object member name.
  1124  			//
  1125  			// The logic below is semantically equivalent to:
  1126  			//	enc.WriteToken(String(f.name))
  1127  			// but specialized and simplified because:
  1128  			//	1. The Encoder must be expecting an object name.
  1129  			//	2. The object namespace is guaranteed to be disabled.
  1130  			//	3. The object name is guaranteed to be valid and pre-escaped.
  1131  			//	4. There is no need to flush the buffer (for unwrite purposes).
  1132  			//	5. There is no possibility of an error occurring.
  1133  			if optimizeCommon {
  1134  				// Append any delimiters or optional whitespace.
  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  				// Append the token to the output and to the state machine.
  1147  				n0 := len(b) // offset before calling AppendQuote
  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  			// Write the object member value.
  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  			// Try unwriting the member if empty (slow path for omitempty).
  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  			// Remember the previous written object member.
  1194  			// The set of seen fields only needs to be updated to detect
  1195  			// duplicate names with those from the inlined fallback.
  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  					// Check that the name from inlined fallback does not match
  1206  					// one of the previously marshaled names from known fields.
  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  					// Check that the name does not match any other name
  1219  					// previously marshaled from the inlined fallback.
  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  				// Process the object member name.
  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  							// TODO: Unread the object name.
  1282  							return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val))
  1283  						}
  1284  
  1285  						if fields.inlinedFallback == nil {
  1286  							// Skip unknown value since we have no place to store it.
  1287  							if err := dec.SkipValue(); err != nil {
  1288  								return err
  1289  							}
  1290  						} else {
  1291  							// Marshal into value capable of storing arbitrary object members.
  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  					// TODO: Unread the object name.
  1304  					return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val))
  1305  				}
  1306  
  1307  				// Process the object member value.
  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} // addressable if struct value is addressable
  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} // addressable if struct value is addressable
  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} // dereferenced pointer is always addressable
  1378  	}
  1379  	return va
  1380  }
  1381  
  1382  // isLegacyEmpty reports whether a value is empty according to the v1 definition.
  1383  func isLegacyEmpty(v addressableValue) bool {
  1384  	// Equivalent to encoding/json.isEmptyValue@v1.21.0.
  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  // canLegacyStringify reports whether t can be stringified according to v1,
  1403  // where t is a bool, string, or number (or unnamed pointer to such).
  1404  // In v1, the `string` option does not apply recursively to nested types within
  1405  // a composite Go type (e.g., an array, slice, struct, map, or interface).
  1406  func canLegacyStringify(t reflect.Type) bool {
  1407  	// Based on encoding/json.typeFields#L1126-L1143@v1.23.0
  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  		// Check for cycles.
  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  		// Handle empty slices.
  1455  		n := va.Len()
  1456  		if n == 0 {
  1457  			if emitNull && va.IsNil() {
  1458  				return enc.WriteToken(jsontext.Null)
  1459  			}
  1460  			// Optimize for marshaling an empty slice without any preceding whitespace.
  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} // indexed slice element is always addressable
  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 = "" // only relevant for marshaling
  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 // we do not know the cleanliness of unused capacity
  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 // reflect.Value.Grow ensures new capacity is zero-initialized
  1530  				}
  1531  				v := addressableValue{va.Index(i), false} // indexed slice element is always addressable
  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} // indexed array element is addressable if array is addressable
  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} // indexed array element is addressable if array is addressable
  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  		// Check for cycles.
  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  		// NOTE: Struct.Format is forwarded to underlying marshal.
  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} // dereferenced pointer is always addressable
  1686  		return marshal(enc, v, mo)
  1687  	}
  1688  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
  1689  		// NOTE: Struct.Format is forwarded to underlying unmarshal.
  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} // dereferenced pointer is always addressable
  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  			// A JSON null quoted within a JSON string should take effect
  1712  			// within the pointer value, rather than the indirect value.
  1713  			//
  1714  			// TODO: This does not correctly handle escaped nulls
  1715  			// (e.g., "\u006e\u0075\u006c\u006c"), but is good enough
  1716  			// for such an esoteric use case of the `string` option.
  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  	// NOTE: Values retrieved from an interface are not addressable,
  1728  	// so we shallow copy the values to make them addressable and
  1729  	// store them back into the interface afterwards.
  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  			// The marshaler for a pointer never calls the method on a nil receiver.
  1748  			// Wrap the nil pointer within a struct type so that marshal
  1749  			// instead appears on a value receiver and may be called.
  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  		// Optimize for the any type if there are no special options.
  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  			// Legacy merge behavior is difficult to explain.
  1786  			// In general, it only merges for non-nil pointer kinds.
  1787  			// As a special case, unmarshaling a JSON null into a pointer
  1788  			// sets a concrete nil pointer of the underlying type
  1789  			// (rather than setting the interface value itself to nil).
  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  			// Optimize for the any type if there are no special options.
  1813  			// We do not care about stringified numbers since JSON strings
  1814  			// are always unmarshaled into an any value as Go strings.
  1815  			// Duplicate name check must be enforced since unmarshalValueAny
  1816  			// does not implement merge semantics.
  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  				// We must check for nil interface values up front.
  1822  				// See https://go.dev/issue/52310.
  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  				// If k is invalid (e.g., due to an I/O or syntax error), then
  1850  				// that will be cached by PeekKind and returned by ReadValue.
  1851  				// If k is '}' or ']', then ReadValue must error since
  1852  				// those are invalid kinds at the start of a JSON value.
  1853  				_, err := dec.ReadValue()
  1854  				return err
  1855  			}
  1856  		} else {
  1857  			// Shallow copy the existing value to keep it addressable.
  1858  			// Any mutations at the top-level of the value will be observable
  1859  			// since we always store this value back into the interface value.
  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  // isAnyType reports wether t is equivalent to the any interface type.
  1875  func isAnyType(t reflect.Type) bool {
  1876  	// This is forward compatible if the Go language permits type sets within
  1877  	// ordinary interfaces where an interface with zero methods does not
  1878  	// necessarily mean it can hold every possible Go type.
  1879  	// See https://go.dev/issue/45346.
  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  // uintSet is a set of unsigned integers.
  1908  // It is optimized for most integers being close to zero.
  1909  type uintSet struct {
  1910  	lo uintSet64
  1911  	hi []uintSet64
  1912  }
  1913  
  1914  // has reports whether i is in the set.
  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  // insert inserts i into the set and reports whether it was the first insertion.
  1926  func (s *uintSet) insert(i uint) bool {
  1927  	// TODO: Make this inlinable at least for the lower 64-bit case.
  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