// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build goexperiment.jsonv2

package json

import (
	
	
	
	
	
	
	
	
	
	
	
	
	
	

	
	
	
	
	
)

// optimizeCommon specifies whether to use optimizations targeted for certain
// common patterns, rather than using the slower, but more general logic.
// All tests should pass regardless of whether this is true or not.
const optimizeCommon = true

var (
	// Most natural Go type that correspond with each JSON type.
	anyType          = reflect.TypeFor[any]()            // JSON value
	boolType         = reflect.TypeFor[bool]()           // JSON bool
	stringType       = reflect.TypeFor[string]()         // JSON string
	float64Type      = reflect.TypeFor[float64]()        // JSON number
	mapStringAnyType = reflect.TypeFor[map[string]any]() // JSON object
	sliceAnyType     = reflect.TypeFor[[]any]()          // JSON array

	bytesType       = reflect.TypeFor[[]byte]()
	emptyStructType = reflect.TypeFor[struct{}]()
)

const startDetectingCyclesAfter = 1000

type seenPointers = map[any]struct{}

type typedPointer struct {
	typ reflect.Type
	ptr any // always stores unsafe.Pointer, but avoids depending on unsafe
	len int // remember slice length to avoid false positives
}

// visitPointer visits pointer p of type t, reporting an error if seen before.
// If successfully visited, then the caller must eventually call leave.
func visitPointer( *seenPointers,  reflect.Value) error {
	 := typedPointer{.Type(), .UnsafePointer(), sliceLen()}
	if ,  := (*)[];  {
		return internal.ErrCycle
	}
	if * == nil {
		* = make(seenPointers)
	}
	(*)[] = struct{}{}
	return nil
}
func leavePointer( *seenPointers,  reflect.Value) {
	 := typedPointer{.Type(), .UnsafePointer(), sliceLen()}
	delete(*, )
}

func sliceLen( reflect.Value) int {
	if .Kind() == reflect.Slice {
		return .Len()
	}
	return 0
}

func len64[ ~[]byte | ~string]( ) int64 {
	return int64(len())
}

func makeDefaultArshaler( reflect.Type) *arshaler {
	switch .Kind() {
	case reflect.Bool:
		return makeBoolArshaler()
	case reflect.String:
		return makeStringArshaler()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return makeIntArshaler()
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return makeUintArshaler()
	case reflect.Float32, reflect.Float64:
		return makeFloatArshaler()
	case reflect.Map:
		return makeMapArshaler()
	case reflect.Struct:
		return makeStructArshaler()
	case reflect.Slice:
		 := makeSliceArshaler()
		if .Elem().Kind() == reflect.Uint8 {
			return makeBytesArshaler(, )
		}
		return 
	case reflect.Array:
		 := makeArrayArshaler()
		if .Elem().Kind() == reflect.Uint8 {
			return makeBytesArshaler(, )
		}
		return 
	case reflect.Pointer:
		return makePointerArshaler()
	case reflect.Interface:
		return makeInterfaceArshaler()
	default:
		return makeInvalidArshaler()
	}
}

func makeBoolArshaler( reflect.Type) *arshaler {
	var  arshaler
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Encoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}

		// Optimize for marshaling without preceding whitespace.
		if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyBoolsAndStrings) && !.Tokens.Last.NeedObjectName() {
			.Buf = strconv.AppendBool(.Tokens.MayAppendDelim(.Buf, 't'), .Bool())
			.Tokens.Last.Increment()
			if .NeedFlush() {
				return .Flush()
			}
			return nil
		}

		if .Flags.Get(jsonflags.StringifyBoolsAndStrings) {
			if .Bool() {
				return .WriteToken(jsontext.String("true"))
			} else {
				return .WriteToken(jsontext.String("false"))
			}
		}
		return .WriteToken(jsontext.Bool(.Bool()))
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		,  := .ReadToken()
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
				.SetBool(false)
			}
			return nil
		case 't', 'f':
			if !.Flags.Get(jsonflags.StringifyBoolsAndStrings) {
				.SetBool(.Bool())
				return nil
			}
		case '"':
			if .Flags.Get(jsonflags.StringifyBoolsAndStrings) {
				switch .String() {
				case "true":
					.SetBool(true)
				case "false":
					.SetBool(false)
				default:
					if .Flags.Get(jsonflags.StringifyWithLegacySemantics) && .String() == "null" {
						if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
							.SetBool(false)
						}
						return nil
					}
					return newUnmarshalErrorAfterWithValue(, , strconv.ErrSyntax)
				}
				return nil
			}
		}
		return newUnmarshalErrorAfterWithSkipping(, , , nil)
	}
	return &
}

func makeStringArshaler( reflect.Type) *arshaler {
	var  arshaler
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Encoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}

		// Optimize for marshaling without preceding whitespace.
		 := .String()
		if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyBoolsAndStrings) && !.Tokens.Last.NeedObjectName() {
			 := .Buf
			 = .Tokens.MayAppendDelim(, '"')
			,  := jsonwire.AppendQuote(, , &.Flags)
			if  == nil {
				.Buf = 
				.Tokens.Last.Increment()
				if .NeedFlush() {
					return .Flush()
				}
				return nil
			}
			// Otherwise, the string contains invalid UTF-8,
			// so let the logic below construct the proper error.
		}

		if .Flags.Get(jsonflags.StringifyBoolsAndStrings) {
			,  := jsonwire.AppendQuote(nil, , &.Flags)
			if  != nil {
				return newMarshalErrorBefore(, , &jsontext.SyntacticError{Err: })
			}
			,  := jsontext.AppendQuote(nil, )
			if  != nil {
				panic("BUG: second AppendQuote should never fail: " + .Error())
			}
			return .WriteValue()
		}
		return .WriteToken(jsontext.String())
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		var  jsonwire.ValueFlags
		,  := .ReadValue(&)
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
				.SetString("")
			}
			return nil
		case '"':
			 = jsonwire.UnquoteMayCopy(, .IsVerbatim())
			if .Flags.Get(jsonflags.StringifyBoolsAndStrings) {
				,  = jsontext.AppendUnquote(nil, )
				if  != nil {
					return newUnmarshalErrorAfter(, , )
				}
				if .Flags.Get(jsonflags.StringifyWithLegacySemantics) && string() == "null" {
					if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
						.SetString("")
					}
					return nil
				}
			}
			if .StringCache == nil {
				.StringCache = new(stringCache)
			}
			 := makeString(.StringCache, )
			.SetString()
			return nil
		}
		return newUnmarshalErrorAfter(, , nil)
	}
	return &
}

var (
	appendEncodeBase16    = hex.AppendEncode
	appendEncodeBase32    = base32.StdEncoding.AppendEncode
	appendEncodeBase32Hex = base32.HexEncoding.AppendEncode
	appendEncodeBase64    = base64.StdEncoding.AppendEncode
	appendEncodeBase64URL = base64.URLEncoding.AppendEncode
	encodedLenBase16      = hex.EncodedLen
	encodedLenBase32      = base32.StdEncoding.EncodedLen
	encodedLenBase32Hex   = base32.HexEncoding.EncodedLen
	encodedLenBase64      = base64.StdEncoding.EncodedLen
	encodedLenBase64URL   = base64.URLEncoding.EncodedLen
	appendDecodeBase16    = hex.AppendDecode
	appendDecodeBase32    = base32.StdEncoding.AppendDecode
	appendDecodeBase32Hex = base32.HexEncoding.AppendDecode
	appendDecodeBase64    = base64.StdEncoding.AppendDecode
	appendDecodeBase64URL = base64.URLEncoding.AppendDecode
)

func makeBytesArshaler( reflect.Type,  *arshaler) *arshaler {
	// NOTE: This handles both []~byte and [N]~byte.
	// The v2 default is to treat a []namedByte as equivalent to []T
	// since being able to convert []namedByte to []byte relies on
	// dubious Go reflection behavior (see https://go.dev/issue/24746).
	// For v1 emulation, we use jsonflags.FormatBytesWithLegacySemantics
	// to forcibly treat []namedByte as a []byte.
	 := .marshal
	 := .Elem().PkgPath() != ""
	 := implementsAny(.Elem(), allMarshalerTypes...)
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		if !.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) &&  {
			return (, , ) // treat as []T or [N]T
		}
		 := export.Encoder()
		 := appendEncodeBase64
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			switch .Format {
			case "base64":
				 = appendEncodeBase64
			case "base64url":
				 = appendEncodeBase64URL
			case "base32":
				 = appendEncodeBase32
			case "base32hex":
				 = appendEncodeBase32Hex
			case "base16", "hex":
				 = appendEncodeBase16
			case "array":
				.Format = ""
				return (, , )
			default:
				return newInvalidFormatError(, , )
			}
		} else if .Flags.Get(jsonflags.FormatBytesWithLegacySemantics) &&
			(.Kind() == reflect.Array || ) {
			return (, , )
		}
		if .Flags.Get(jsonflags.FormatNilSliceAsNull) && .Kind() == reflect.Slice && .IsNil() {
			// TODO: Provide a "emitempty" format override?
			return .WriteToken(jsontext.Null)
		}
		return .AppendRaw('"', true, func( []byte) ([]byte, error) {
			return (, .Bytes()), nil
		})
	}
	 := .unmarshal
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		if !.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) &&  {
			return (, , ) // treat as []T or [N]T
		}
		 := export.Decoder()
		,  := appendDecodeBase64, encodedLenBase64
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			switch .Format {
			case "base64":
				,  = appendDecodeBase64, encodedLenBase64
			case "base64url":
				,  = appendDecodeBase64URL, encodedLenBase64URL
			case "base32":
				,  = appendDecodeBase32, encodedLenBase32
			case "base32hex":
				,  = appendDecodeBase32Hex, encodedLenBase32Hex
			case "base16", "hex":
				,  = appendDecodeBase16, encodedLenBase16
			case "array":
				.Format = ""
				return (, , )
			default:
				return newInvalidFormatError(, , )
			}
		} else if .Flags.Get(jsonflags.FormatBytesWithLegacySemantics) &&
			(.Kind() == reflect.Array || .PeekKind() == '[') {
			return (, , )
		}
		var  jsonwire.ValueFlags
		,  := .ReadValue(&)
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			if !.Flags.Get(jsonflags.MergeWithLegacySemantics) || .Kind() != reflect.Array {
				.SetZero()
			}
			return nil
		case '"':
			// NOTE: The v2 default is to strictly comply with RFC 4648.
			// Section 3.2 specifies that padding is required.
			// Section 3.3 specifies that non-alphabet characters
			// (e.g., '\r' or '\n') must be rejected.
			// Section 3.5 specifies that unnecessary non-zero bits in
			// the last quantum may be rejected. Since this is optional,
			// we do not reject such inputs.
			 = jsonwire.UnquoteMayCopy(, .IsVerbatim())
			,  := (.Bytes()[:0], )
			if  != nil {
				return newUnmarshalErrorAfter(, , )
			}
			if len() != (len()) && !.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) {
				// TODO(https://go.dev/issue/53845): RFC 4648, section 3.3,
				// specifies that non-alphabet characters must be rejected.
				// Unfortunately, the "base32" and "base64" packages allow
				// '\r' and '\n' characters by default.
				 := bytes.IndexAny(, "\r\n")
				 := fmt.Errorf("illegal character %s at offset %d", jsonwire.QuoteRune([:]), )
				return newUnmarshalErrorAfter(, , )
			}

			if .Kind() == reflect.Array {
				 := .Bytes()
				clear([copy(, ):]) // noop if len(b) <= len(dst)
				if len() != len() && !.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) {
					 := fmt.Errorf("decoded length of %d mismatches array length of %d", len(), len())
					return newUnmarshalErrorAfter(, , )
				}
			} else {
				if  == nil {
					 = []byte{}
				}
				.SetBytes()
			}
			return nil
		}
		return newUnmarshalErrorAfter(, , nil)
	}
	return 
}

func makeIntArshaler( reflect.Type) *arshaler {
	var  arshaler
	 := .Bits()
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Encoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}

		// Optimize for marshaling without preceding whitespace or string escaping.
		if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !.Tokens.Last.NeedObjectName() {
			.Buf = strconv.AppendInt(.Tokens.MayAppendDelim(.Buf, '0'), .Int(), 10)
			.Tokens.Last.Increment()
			if .NeedFlush() {
				return .Flush()
			}
			return nil
		}

		 := stringOrNumberKind(.Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers))
		return .AppendRaw(, true, func( []byte) ([]byte, error) {
			return strconv.AppendInt(, .Int(), 10), nil
		})
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		 := .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers)
		var  jsonwire.ValueFlags
		,  := .ReadValue(&)
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
				.SetInt(0)
			}
			return nil
		case '"':
			if ! {
				break
			}
			 = jsonwire.UnquoteMayCopy(, .IsVerbatim())
			if .Flags.Get(jsonflags.StringifyWithLegacySemantics) && string() == "null" {
				if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
					.SetInt(0)
				}
				return nil
			}
			fallthrough
		case '0':
			if  &&  == '0' {
				break
			}
			var  int
			 := len() > 0 && [0] == '-'
			if  {
				 = 1
			}
			,  := jsonwire.ParseUint([:])
			 := uint64(1) << ( - 1)
			 := ( &&  > ) || (! &&  > -1)
			if ! {
				if  != math.MaxUint64 {
					return newUnmarshalErrorAfterWithValue(, , strconv.ErrSyntax)
				}
				 = true
			}
			if  {
				return newUnmarshalErrorAfterWithValue(, , strconv.ErrRange)
			}
			if  {
				.SetInt(int64(-))
			} else {
				.SetInt(int64(+))
			}
			return nil
		}
		return newUnmarshalErrorAfter(, , nil)
	}
	return &
}

func makeUintArshaler( reflect.Type) *arshaler {
	var  arshaler
	 := .Bits()
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Encoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}

		// Optimize for marshaling without preceding whitespace or string escaping.
		if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !.Tokens.Last.NeedObjectName() {
			.Buf = strconv.AppendUint(.Tokens.MayAppendDelim(.Buf, '0'), .Uint(), 10)
			.Tokens.Last.Increment()
			if .NeedFlush() {
				return .Flush()
			}
			return nil
		}

		 := stringOrNumberKind(.Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers))
		return .AppendRaw(, true, func( []byte) ([]byte, error) {
			return strconv.AppendUint(, .Uint(), 10), nil
		})
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		 := .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers)
		var  jsonwire.ValueFlags
		,  := .ReadValue(&)
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
				.SetUint(0)
			}
			return nil
		case '"':
			if ! {
				break
			}
			 = jsonwire.UnquoteMayCopy(, .IsVerbatim())
			if .Flags.Get(jsonflags.StringifyWithLegacySemantics) && string() == "null" {
				if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
					.SetUint(0)
				}
				return nil
			}
			fallthrough
		case '0':
			if  &&  == '0' {
				break
			}
			,  := jsonwire.ParseUint()
			 := uint64(1) << 
			 :=  > -1
			if ! {
				if  != math.MaxUint64 {
					return newUnmarshalErrorAfterWithValue(, , strconv.ErrSyntax)
				}
				 = true
			}
			if  {
				return newUnmarshalErrorAfterWithValue(, , strconv.ErrRange)
			}
			.SetUint()
			return nil
		}
		return newUnmarshalErrorAfter(, , nil)
	}
	return &
}

func makeFloatArshaler( reflect.Type) *arshaler {
	var  arshaler
	 := .Bits()
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Encoder()
		var  bool
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			if .Format == "nonfinite" {
				 = true
			} else {
				return newInvalidFormatError(, , )
			}
		}

		 := .Float()
		if math.IsNaN() || math.IsInf(, 0) {
			if ! {
				 := fmt.Errorf("unsupported value: %v", )
				return newMarshalErrorBefore(, , )
			}
			return .WriteToken(jsontext.Float())
		}

		// Optimize for marshaling without preceding whitespace or string escaping.
		if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !.Tokens.Last.NeedObjectName() {
			.Buf = jsonwire.AppendFloat(.Tokens.MayAppendDelim(.Buf, '0'), , )
			.Tokens.Last.Increment()
			if .NeedFlush() {
				return .Flush()
			}
			return nil
		}

		 := stringOrNumberKind(.Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers))
		return .AppendRaw(, true, func( []byte) ([]byte, error) {
			return jsonwire.AppendFloat(, .Float(), ), nil
		})
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		var  bool
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			if .Format == "nonfinite" {
				 = true
			} else {
				return newInvalidFormatError(, , )
			}
		}
		 := .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers)
		var  jsonwire.ValueFlags
		,  := .ReadValue(&)
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
				.SetFloat(0)
			}
			return nil
		case '"':
			 = jsonwire.UnquoteMayCopy(, .IsVerbatim())
			if  {
				switch string() {
				case "NaN":
					.SetFloat(math.NaN())
					return nil
				case "Infinity":
					.SetFloat(math.Inf(+1))
					return nil
				case "-Infinity":
					.SetFloat(math.Inf(-1))
					return nil
				}
			}
			if ! {
				break
			}
			if .Flags.Get(jsonflags.StringifyWithLegacySemantics) && string() == "null" {
				if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
					.SetFloat(0)
				}
				return nil
			}
			if ,  := jsonwire.ConsumeNumber();  != len() ||  != nil {
				return newUnmarshalErrorAfterWithValue(, , strconv.ErrSyntax)
			}
			fallthrough
		case '0':
			if  &&  == '0' {
				break
			}
			,  := jsonwire.ParseFloat(, )
			.SetFloat()
			if ! {
				return newUnmarshalErrorAfterWithValue(, , strconv.ErrRange)
			}
			return nil
		}
		return newUnmarshalErrorAfter(, , nil)
	}
	return &
}

func makeMapArshaler( reflect.Type) *arshaler {
	// NOTE: The logic below disables namespaces for tracking duplicate names
	// when handling map keys with a unique representation.

	// NOTE: Values retrieved from a map are not addressable,
	// so we shallow copy the values to make them addressable and
	// store them back into the map afterwards.

	var  arshaler
	var (
		    sync.Once
		 *arshaler
		 *arshaler
	)
	 := func() {
		 = lookupArshaler(.Key())
		 = lookupArshaler(.Elem())
	}
	 := .Key().Kind() == reflect.Pointer &&
		implementsAny(.Key(), textMarshalerType, textAppenderType)
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		// Check for cycles.
		 := export.Encoder()
		if .Tokens.Depth() > startDetectingCyclesAfter {
			if  := visitPointer(&.SeenPointers, .Value);  != nil {
				return newMarshalErrorBefore(, , )
			}
			defer leavePointer(&.SeenPointers, .Value)
		}

		 := .Flags.Get(jsonflags.FormatNilMapAsNull)
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			switch .Format {
			case "emitnull":
				 = true
				.Format = ""
			case "emitempty":
				 = false
				.Format = ""
			default:
				return newInvalidFormatError(, , )
			}
		}

		// Handle empty maps.
		 := .Len()
		if  == 0 {
			if  && .IsNil() {
				return .WriteToken(jsontext.Null)
			}
			// Optimize for marshaling an empty map without any preceding whitespace.
			if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && !.Tokens.Last.NeedObjectName() {
				.Buf = append(.Tokens.MayAppendDelim(.Buf, '{'), "{}"...)
				.Tokens.Last.Increment()
				if .NeedFlush() {
					return .Flush()
				}
				return nil
			}
		}

		.Do()
		if  := .WriteToken(jsontext.BeginObject);  != nil {
			return 
		}
		if  > 0 {
			 := .nonDefault
			 := .marshal
			 := .marshal
			if .Marshalers != nil {
				var  bool
				,  = .Marshalers.(*Marshalers).lookup(, .Key())
				, _ = .Marshalers.(*Marshalers).lookup(, .Elem())
				 =  || 
			}
			 := newAddressableValue(.Key())
			 := newAddressableValue(.Elem())

			// A Go map guarantees that each entry has a unique key.
			// As such, disable the expensive duplicate name check if we know
			// that every Go key will serialize as a unique JSON string.
			if ! && mapKeyWithUniqueRepresentation(.Kind(), .Flags.Get(jsonflags.AllowInvalidUTF8)) {
				.Tokens.Last.DisableNamespace()
			}

			switch {
			case !.Flags.Get(jsonflags.Deterministic) ||  <= 1:
				for  := .Value.MapRange(); .Next(); {
					.SetIterKey()
					 := (, , )
					if  != nil {
						if .Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&
							errors.Is(, jsontext.ErrNonStringName) &&  && .IsNil() {
							 = .WriteToken(jsontext.String(""))
						}
						if  != nil {
							if ,  := .(*jsontext.SyntacticError);  && .Err == jsontext.ErrNonStringName {
								 = newMarshalErrorBefore(, .Type(), )
							}
							return 
						}
					}
					.SetIterValue()
					if  := (, , );  != nil {
						return 
					}
				}
			case ! && .Key().Kind() == reflect.String:
				 := getStrings()
				for ,  := 0, .Value.MapRange();  <  && .Next(); ++ {
					.SetIterKey()
					(*)[] = .String()
				}
				.Sort()
				for ,  := range * {
					if  := .WriteToken(jsontext.String());  != nil {
						return 
					}
					// TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf.
					.SetString()
					.Set(.MapIndex(.Value))
					if  := (, , );  != nil {
						return 
					}
				}
				putStrings()
			default:
				type  struct {
					 string // unquoted name
					  addressableValue
					  addressableValue
				}
				 := make([], )
				 := reflect.MakeSlice(reflect.SliceOf(.Key()), , )
				 := reflect.MakeSlice(reflect.SliceOf(.Elem()), , )
				for ,  := 0, .Value.MapRange();  <  && .Next(); ++ {
					// Marshal the member name.
					 := addressableValue{.Index(), true} // indexed slice element is always addressable
					.SetIterKey()
					 := addressableValue{.Index(), true} // indexed slice element is always addressable
					.SetIterValue()
					 := (, , )
					if  != nil {
						if .Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&
							errors.Is(, jsontext.ErrNonStringName) &&  && .IsNil() {
							 = .WriteToken(jsontext.String(""))
						}
						if  != nil {
							if ,  := .(*jsontext.SyntacticError);  && .Err == jsontext.ErrNonStringName {
								 = newMarshalErrorBefore(, .Type(), )
							}
							return 
						}
					}
					 := .UnwriteOnlyObjectMemberName()
					[] = {, , }
				}
				// TODO: If AllowDuplicateNames is enabled, then sort according
				// to reflect.Value as well if the names are equal.
				// See internal/fmtsort.
				slices.SortFunc(, func(,  ) int {
					return strings.Compare(., .)
				})
				for ,  := range  {
					if  := .WriteToken(jsontext.String(.));  != nil {
						return 
					}
					if  := (, ., );  != nil {
						return 
					}
				}
			}
		}
		if  := .WriteToken(jsontext.EndObject);  != nil {
			return 
		}
		return nil
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			switch .Format {
			case "emitnull", "emitempty":
				.Format = "" // only relevant for marshaling
			default:
				return newInvalidFormatError(, , )
			}
		}
		,  := .ReadToken()
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			.SetZero()
			return nil
		case '{':
			.Do()
			if .IsNil() {
				.Set(reflect.MakeMap())
			}

			 := .nonDefault
			 := .unmarshal
			 := .unmarshal
			if .Unmarshalers != nil {
				var  bool
				,  = .Unmarshalers.(*Unmarshalers).lookup(, .Key())
				, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Elem())
				 =  || 
			}
			 := newAddressableValue(.Key())
			 := newAddressableValue(.Elem())

			// Manually check for duplicate entries by virtue of whether the
			// unmarshaled key already exists in the destination Go map.
			// Consequently, syntactically different names (e.g., "0" and "-0")
			// will be rejected as duplicates since they semantically refer
			// to the same Go value. This is an unusual interaction
			// between syntax and semantics, but is more correct.
			if ! && mapKeyWithUniqueRepresentation(.Kind(), .Flags.Get(jsonflags.AllowInvalidUTF8)) {
				.Tokens.Last.DisableNamespace()
			}

			// In the rare case where the map is not already empty,
			// then we need to manually track which keys we already saw
			// since existing presence alone is insufficient to indicate
			// whether the input had a duplicate name.
			var  reflect.Value
			if !.Flags.Get(jsonflags.AllowDuplicateNames) && .Len() > 0 {
				 = reflect.MakeMap(reflect.MapOf(.Type(), emptyStructType))
			}

			var  error
			for .PeekKind() != '}' {
				// Unmarshal the map entry key.
				.SetZero()
				 := (, , )
				if  != nil {
					if isFatalError(, .Flags) {
						return 
					}
					if  := .SkipValue();  != nil {
						return 
					}
					 = cmp.Or(, )
					continue
				}
				if .Kind() == reflect.Interface && !.IsNil() && !.Elem().Type().Comparable() {
					 := newUnmarshalErrorAfter(, , fmt.Errorf("invalid incomparable key type %v", .Elem().Type()))
					if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
						return 
					}
					if  := .SkipValue();  != nil {
						return 
					}
					 = cmp.Or(, )
					continue
				}

				// Check if a pre-existing map entry value exists for this key.
				if  := .MapIndex(.Value); .IsValid() {
					if !.Flags.Get(jsonflags.AllowDuplicateNames) && (!.IsValid() || .MapIndex(.Value).IsValid()) {
						// TODO: Unread the object name.
						 := .PreviousTokenOrValue()
						return newDuplicateNameError(.StackPointer(), nil, .InputOffset()-len64())
					}
					if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
						.Set()
					} else {
						.SetZero()
					}
				} else {
					.SetZero()
				}

				// Unmarshal the map entry value.
				 = (, , )
				.SetMapIndex(.Value, .Value)
				if .IsValid() {
					.SetMapIndex(.Value, reflect.Zero(emptyStructType))
				}
				if  != nil {
					if isFatalError(, .Flags) {
						return 
					}
					 = cmp.Or(, )
				}
			}
			if ,  := .ReadToken();  != nil {
				return 
			}
			return 
		}
		return newUnmarshalErrorAfterWithSkipping(, , , nil)
	}
	return &
}

// mapKeyWithUniqueRepresentation reports whether all possible values of k
// marshal to a different JSON value, and whether all possible JSON values
// that can unmarshal into k unmarshal to different Go values.
// In other words, the representation must be a bijective.
func mapKeyWithUniqueRepresentation( reflect.Kind,  bool) bool {
	switch  {
	case reflect.Bool,
		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return true
	case reflect.String:
		// For strings, we have to be careful since names with invalid UTF-8
		// maybe unescape to the same Go string value.
		return !
	default:
		// Floating-point kinds are not listed above since NaNs
		// can appear multiple times and all serialize as "NaN".
		return false
	}
}

var errNilField = errors.New("cannot set embedded pointer to unexported struct type")

func makeStructArshaler( reflect.Type) *arshaler {
	// NOTE: The logic below disables namespaces for tracking duplicate names
	// and does the tracking locally with an efficient bit-set based on which
	// Go struct fields were seen.

	var  arshaler
	var (
		    sync.Once
		  structFields
		 *SemanticError
	)
	 := func() {
		,  = makeStructFields()
	}
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Encoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		.Do()
		if  != nil && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
			return newMarshalErrorBefore(, .GoType, .Err)
		}
		if  := .WriteToken(jsontext.BeginObject);  != nil {
			return 
		}
		var  uintSet
		 := -1
		.Tokens.Last.DisableNamespace() // we manually ensure unique names below
		for  := range .flattened {
			 := &.flattened[]
			 := addressableValue{.Field(.index0), .forcedAddr} // addressable if struct value is addressable
			if len(.index) > 0 {
				 = .fieldByIndex(.index, false)
				if !.IsValid() {
					continue // implies a nil inlined field
				}
			}

			// OmitZero skips the field if the Go value is zero,
			// which we can determine up front without calling the marshaler.
			if (.omitzero || .Flags.Get(jsonflags.OmitZeroStructFields)) &&
				((.isZero == nil && .IsZero()) || (.isZero != nil && .isZero())) {
				continue
			}

			// Check for the legacy definition of omitempty.
			if .omitempty && .Flags.Get(jsonflags.OmitEmptyWithLegacyDefinition) && isLegacyEmpty() {
				continue
			}

			 := .fncs.marshal
			 := .fncs.nonDefault
			if .Marshalers != nil {
				var  bool
				,  = .Marshalers.(*Marshalers).lookup(, .typ)
				 =  || 
			}

			// OmitEmpty skips the field if the marshaled JSON value is empty,
			// which we can know up front if there are no custom marshalers,
			// otherwise we must marshal the value and unwrite it if empty.
			if .omitempty && !.Flags.Get(jsonflags.OmitEmptyWithLegacyDefinition) &&
				! && .isEmpty != nil && .isEmpty() {
				continue // fast path for omitempty
			}

			// Write the object member name.
			//
			// The logic below is semantically equivalent to:
			//	enc.WriteToken(String(f.name))
			// but specialized and simplified because:
			//	1. The Encoder must be expecting an object name.
			//	2. The object namespace is guaranteed to be disabled.
			//	3. The object name is guaranteed to be valid and pre-escaped.
			//	4. There is no need to flush the buffer (for unwrite purposes).
			//	5. There is no possibility of an error occurring.
			if optimizeCommon {
				// Append any delimiters or optional whitespace.
				 := .Buf
				if .Tokens.Last.Length() > 0 {
					 = append(, ',')
					if .Flags.Get(jsonflags.SpaceAfterComma) {
						 = append(, ' ')
					}
				}
				if .Flags.Get(jsonflags.Multiline) {
					 = .AppendIndent(, .Tokens.NeedIndent('"'))
				}

				// Append the token to the output and to the state machine.
				 := len() // offset before calling AppendQuote
				if !.nameNeedEscape {
					 = append(, .quotedName...)
				} else {
					, _ = jsonwire.AppendQuote(, .name, &.Flags)
				}
				.Buf = 
				.Names.ReplaceLastQuotedOffset()
				.Tokens.Last.Increment()
			} else {
				if  := .WriteToken(jsontext.String(.name));  != nil {
					return 
				}
			}

			// Write the object member value.
			 := .Flags
			if .string {
				if !.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
					.Flags.Set(jsonflags.StringifyNumbers | 1)
				} else if canLegacyStringify(.typ) {
					.Flags.Set(jsonflags.StringifyNumbers | jsonflags.StringifyBoolsAndStrings | 1)
				}
			}
			if .format != "" {
				.FormatDepth = .Tokens.Depth()
				.Format = .format
			}
			 := (, , )
			.Flags = 
			.Format = ""
			if  != nil {
				return 
			}

			// Try unwriting the member if empty (slow path for omitempty).
			if .omitempty && !.Flags.Get(jsonflags.OmitEmptyWithLegacyDefinition) {
				var  *string
				if  >= 0 {
					 = &.flattened[].name
				}
				if .UnwriteEmptyObjectMember() {
					continue
				}
			}

			// Remember the previous written object member.
			// The set of seen fields only needs to be updated to detect
			// duplicate names with those from the inlined fallback.
			if !.Flags.Get(jsonflags.AllowDuplicateNames) && .inlinedFallback != nil {
				.insert(uint(.id))
			}
			 = .id
		}
		if .inlinedFallback != nil && !(.Flags.Get(jsonflags.DiscardUnknownMembers) && .inlinedFallback.unknown) {
			var  func([]byte) bool
			if !.Flags.Get(jsonflags.AllowDuplicateNames) {
				 = func( []byte) bool {
					// Check that the name from inlined fallback does not match
					// one of the previously marshaled names from known fields.
					if  := .lookupByFoldedName(); len() > 0 {
						if  := .byActualName[string()];  != nil {
							return .insert(uint(.id))
						}
						for ,  := range  {
							if .matchFoldedName(, &.Flags) {
								return .insert(uint(.id))
							}
						}
					}

					// Check that the name does not match any other name
					// previously marshaled from the inlined fallback.
					return .Namespaces.Last().InsertUnquoted()
				}
			}
			if  := marshalInlinedFallbackAll(, , , .inlinedFallback, );  != nil {
				return 
			}
		}
		if  := .WriteToken(jsontext.EndObject);  != nil {
			return 
		}
		return nil
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		,  := .ReadToken()
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
				.SetZero()
			}
			return nil
		case '{':
			.Do()
			if  != nil && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
				return newUnmarshalErrorAfter(, .GoType, .Err)
			}
			var  uintSet
			.Tokens.Last.DisableNamespace()
			var  error
			for .PeekKind() != '}' {
				// Process the object member name.
				var  jsonwire.ValueFlags
				,  := .ReadValue(&)
				if  != nil {
					return 
				}
				 := jsonwire.UnquoteMayCopy(, .IsVerbatim())
				 := .byActualName[string()]
				if  == nil {
					for ,  := range .lookupByFoldedName() {
						if .matchFoldedName(, &.Flags) {
							 = 
							break
						}
					}
					if  == nil {
						if .Flags.Get(jsonflags.RejectUnknownMembers) && (.inlinedFallback == nil || .inlinedFallback.unknown) {
							 := newUnmarshalErrorAfter(, , ErrUnknownName)
							if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
								return 
							}
							 = cmp.Or(, )
						}
						if !.Flags.Get(jsonflags.AllowDuplicateNames) && !.Namespaces.Last().InsertUnquoted() {
							// TODO: Unread the object name.
							return newDuplicateNameError(.StackPointer(), nil, .InputOffset()-len64())
						}

						if .inlinedFallback == nil {
							// Skip unknown value since we have no place to store it.
							if  := .SkipValue();  != nil {
								return 
							}
						} else {
							// Marshal into value capable of storing arbitrary object members.
							if  := unmarshalInlinedFallbackNext(, , , .inlinedFallback, , );  != nil {
								if isFatalError(, .Flags) {
									return 
								}
								 = cmp.Or(, )
							}
						}
						continue
					}
				}
				if !.Flags.Get(jsonflags.AllowDuplicateNames) && !.insert(uint(.id)) {
					// TODO: Unread the object name.
					return newDuplicateNameError(.StackPointer(), nil, .InputOffset()-len64())
				}

				// Process the object member value.
				 := .fncs.unmarshal
				if .Unmarshalers != nil {
					, _ = .Unmarshalers.(*Unmarshalers).lookup(, .typ)
				}
				 := .Flags
				if .string {
					if !.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
						.Flags.Set(jsonflags.StringifyNumbers | 1)
					} else if canLegacyStringify(.typ) {
						.Flags.Set(jsonflags.StringifyNumbers | jsonflags.StringifyBoolsAndStrings | 1)
					}
				}
				if .format != "" {
					.FormatDepth = .Tokens.Depth()
					.Format = .format
				}
				 := addressableValue{.Field(.index0), .forcedAddr} // addressable if struct value is addressable
				if len(.index) > 0 {
					 = .fieldByIndex(.index, true)
					if !.IsValid() {
						 := newUnmarshalErrorBefore(, , errNilField)
						if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
							return 
						}
						 = cmp.Or(, )
						 = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
							return .SkipValue()
						}
					}
				}
				 = (, , )
				.Flags = 
				.Format = ""
				if  != nil {
					if isFatalError(, .Flags) {
						return 
					}
					 = cmp.Or(, )
				}
			}
			if ,  := .ReadToken();  != nil {
				return 
			}
			return 
		}
		return newUnmarshalErrorAfterWithSkipping(, , , nil)
	}
	return &
}

func ( addressableValue) ( []int,  bool) addressableValue {
	for ,  := range  {
		 = .indirect()
		if !.IsValid() {
			return 
		}
		 = addressableValue{.Field(), .forcedAddr} // addressable if struct value is addressable
	}
	return 
}

func ( addressableValue) ( bool) addressableValue {
	if .Kind() == reflect.Pointer {
		if .IsNil() {
			if ! || !.CanSet() {
				return addressableValue{}
			}
			.Set(reflect.New(.Type().Elem()))
		}
		 = addressableValue{.Elem(), false} // dereferenced pointer is always addressable
	}
	return 
}

// isLegacyEmpty reports whether a value is empty according to the v1 definition.
func isLegacyEmpty( addressableValue) bool {
	// Equivalent to encoding/json.isEmptyValue@v1.21.0.
	switch .Kind() {
	case reflect.Bool:
		return .Bool() == false
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return .Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return .Uint() == 0
	case reflect.Float32, reflect.Float64:
		return .Float() == 0
	case reflect.String, reflect.Map, reflect.Slice, reflect.Array:
		return .Len() == 0
	case reflect.Pointer, reflect.Interface:
		return .IsNil()
	}
	return false
}

// canLegacyStringify reports whether t can be stringified according to v1,
// where t is a bool, string, or number (or unnamed pointer to such).
// In v1, the `string` option does not apply recursively to nested types within
// a composite Go type (e.g., an array, slice, struct, map, or interface).
func canLegacyStringify( reflect.Type) bool {
	// Based on encoding/json.typeFields#L1126-L1143@v1.23.0
	if .Name() == "" && .Kind() == reflect.Ptr {
		 = .Elem()
	}
	switch .Kind() {
	case reflect.Bool, reflect.String,
		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
		reflect.Float32, reflect.Float64:
		return true
	}
	return false
}

func makeSliceArshaler( reflect.Type) *arshaler {
	var  arshaler
	var (
		    sync.Once
		 *arshaler
	)
	 := func() {
		 = lookupArshaler(.Elem())
	}
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		// Check for cycles.
		 := export.Encoder()
		if .Tokens.Depth() > startDetectingCyclesAfter {
			if  := visitPointer(&.SeenPointers, .Value);  != nil {
				return newMarshalErrorBefore(, , )
			}
			defer leavePointer(&.SeenPointers, .Value)
		}

		 := .Flags.Get(jsonflags.FormatNilSliceAsNull)
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			switch .Format {
			case "emitnull":
				 = true
				.Format = ""
			case "emitempty":
				 = false
				.Format = ""
			default:
				return newInvalidFormatError(, , )
			}
		}

		// Handle empty slices.
		 := .Len()
		if  == 0 {
			if  && .IsNil() {
				return .WriteToken(jsontext.Null)
			}
			// Optimize for marshaling an empty slice without any preceding whitespace.
			if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && !.Tokens.Last.NeedObjectName() {
				.Buf = append(.Tokens.MayAppendDelim(.Buf, '['), "[]"...)
				.Tokens.Last.Increment()
				if .NeedFlush() {
					return .Flush()
				}
				return nil
			}
		}

		.Do()
		if  := .WriteToken(jsontext.BeginArray);  != nil {
			return 
		}
		 := .marshal
		if .Marshalers != nil {
			, _ = .Marshalers.(*Marshalers).lookup(, .Elem())
		}
		for  := range  {
			 := addressableValue{.Index(), false} // indexed slice element is always addressable
			if  := (, , );  != nil {
				return 
			}
		}
		if  := .WriteToken(jsontext.EndArray);  != nil {
			return 
		}
		return nil
	}
	 := reflect.MakeSlice(, 0, 0)
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			switch .Format {
			case "emitnull", "emitempty":
				.Format = "" // only relevant for marshaling
			default:
				return newInvalidFormatError(, , )
			}
		}

		,  := .ReadToken()
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			.SetZero()
			return nil
		case '[':
			.Do()
			 := .unmarshal
			if .Unmarshalers != nil {
				, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Elem())
			}
			 := true // we do not know the cleanliness of unused capacity
			 := .Cap()
			if  > 0 {
				.SetLen()
			}
			var  int
			var  error
			for .PeekKind() != ']' {
				if  ==  {
					.Value.Grow(1)
					 = .Cap()
					.SetLen()
					 = false // reflect.Value.Grow ensures new capacity is zero-initialized
				}
				 := addressableValue{.Index(), false} // indexed slice element is always addressable
				++
				if  && !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
					.SetZero()
				}
				if  := (, , );  != nil {
					if isFatalError(, .Flags) {
						.SetLen()
						return 
					}
					 = cmp.Or(, )
				}
			}
			if  == 0 {
				.Set()
			} else {
				.SetLen()
			}
			if ,  := .ReadToken();  != nil {
				return 
			}
			return 
		}
		return newUnmarshalErrorAfterWithSkipping(, , , nil)
	}
	return &
}

var errArrayUnderflow = errors.New("too few array elements")
var errArrayOverflow = errors.New("too many array elements")

func makeArrayArshaler( reflect.Type) *arshaler {
	var  arshaler
	var (
		    sync.Once
		 *arshaler
	)
	 := func() {
		 = lookupArshaler(.Elem())
	}
	 := .Len()
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Encoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		.Do()
		if  := .WriteToken(jsontext.BeginArray);  != nil {
			return 
		}
		 := .marshal
		if .Marshalers != nil {
			, _ = .Marshalers.(*Marshalers).lookup(, .Elem())
		}
		for  := range  {
			 := addressableValue{.Index(), .forcedAddr} // indexed array element is addressable if array is addressable
			if  := (, , );  != nil {
				return 
			}
		}
		if  := .WriteToken(jsontext.EndArray);  != nil {
			return 
		}
		return nil
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		,  := .ReadToken()
		if  != nil {
			return 
		}
		 := .Kind()
		switch  {
		case 'n':
			if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
				.SetZero()
			}
			return nil
		case '[':
			.Do()
			 := .unmarshal
			if .Unmarshalers != nil {
				, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Elem())
			}
			var  int
			var  error
			for .PeekKind() != ']' {
				if  >=  {
					if  := .SkipValue();  != nil {
						return 
					}
					 = errArrayOverflow
					continue
				}
				 := addressableValue{.Index(), .forcedAddr} // indexed array element is addressable if array is addressable
				if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
					.SetZero()
				}
				if  := (, , );  != nil {
					if isFatalError(, .Flags) {
						return 
					}
					 = cmp.Or(, )
				}
				++
			}
			for ;  < ; ++ {
				.Index().SetZero()
				 = errArrayUnderflow
			}
			if ,  := .ReadToken();  != nil {
				return 
			}
			if  != nil && !.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) {
				return newUnmarshalErrorAfter(, , )
			}
			return 
		}
		return newUnmarshalErrorAfterWithSkipping(, , , nil)
	}
	return &
}

func makePointerArshaler( reflect.Type) *arshaler {
	var  arshaler
	var (
		    sync.Once
		 *arshaler
	)
	 := func() {
		 = lookupArshaler(.Elem())
	}
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		// Check for cycles.
		 := export.Encoder()
		if .Tokens.Depth() > startDetectingCyclesAfter {
			if  := visitPointer(&.SeenPointers, .Value);  != nil {
				return newMarshalErrorBefore(, , )
			}
			defer leavePointer(&.SeenPointers, .Value)
		}

		// NOTE: Struct.Format is forwarded to underlying marshal.
		if .IsNil() {
			return .WriteToken(jsontext.Null)
		}
		.Do()
		 := .marshal
		if .Marshalers != nil {
			, _ = .Marshalers.(*Marshalers).lookup(, .Elem())
		}
		 := addressableValue{.Elem(), false} // dereferenced pointer is always addressable
		return (, , )
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		// NOTE: Struct.Format is forwarded to underlying unmarshal.
		if .PeekKind() == 'n' {
			if ,  := .ReadToken();  != nil {
				return 
			}
			.SetZero()
			return nil
		}
		.Do()
		 := .unmarshal
		if .Unmarshalers != nil {
			, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Elem())
		}
		if .IsNil() {
			.Set(reflect.New(.Elem()))
		}
		 := addressableValue{.Elem(), false} // dereferenced pointer is always addressable
		if  := (, , );  != nil {
			return 
		}
		if .Flags.Get(jsonflags.StringifyWithLegacySemantics) &&
			.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringifyBoolsAndStrings) {
			// A JSON null quoted within a JSON string should take effect
			// within the pointer value, rather than the indirect value.
			//
			// TODO: This does not correctly handle escaped nulls
			// (e.g., "\u006e\u0075\u006c\u006c"), but is good enough
			// for such an esoteric use case of the `string` option.
			if string(export.Decoder().PreviousTokenOrValue()) == `"null"` {
				.SetZero()
			}
		}
		return nil
	}
	return &
}

var errNilInterface = errors.New("cannot derive concrete type for nil interface with finite type set")

func makeInterfaceArshaler( reflect.Type) *arshaler {
	// NOTE: Values retrieved from an interface are not addressable,
	// so we shallow copy the values to make them addressable and
	// store them back into the interface afterwards.

	var  arshaler
	var  reflect.Type
	for ,  := range allMarshalerTypes {
		if .Implements() {
			 = 
			break
		}
	}
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Encoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		if .IsNil() {
			return .WriteToken(jsontext.Null)
		} else if .Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&  != nil {
			// The marshaler for a pointer never calls the method on a nil receiver.
			// Wrap the nil pointer within a struct type so that marshal
			// instead appears on a value receiver and may be called.
			if .Elem().Kind() == reflect.Pointer && .Elem().IsNil() {
				 := newAddressableValue()
				switch  {
				case jsonMarshalerToType:
					.Set(reflect.ValueOf(struct{ MarshalerTo }{.Elem().Interface().(MarshalerTo)}))
				case jsonMarshalerType:
					.Set(reflect.ValueOf(struct{ Marshaler }{.Elem().Interface().(Marshaler)}))
				case textAppenderType:
					.Set(reflect.ValueOf(struct{ encoding.TextAppender }{.Elem().Interface().(encoding.TextAppender)}))
				case textMarshalerType:
					.Set(reflect.ValueOf(struct{ encoding.TextMarshaler }{.Elem().Interface().(encoding.TextMarshaler)}))
				}
				 = 
			}
		}
		 := newAddressableValue(.Elem().Type())
		.Set(.Elem())
		 := lookupArshaler(.Type()).marshal
		if .Marshalers != nil {
			, _ = .Marshalers.(*Marshalers).lookup(, .Type())
		}
		// Optimize for the any type if there are no special options.
		if optimizeCommon &&
			 == anyType && !.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringifyBoolsAndStrings) && .Format == "" &&
			(.Marshalers == nil || !.Marshalers.(*Marshalers).fromAny) {
			return marshalValueAny(, .Elem().Interface(), )
		}
		return (, , )
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		 := export.Decoder()
		if .Format != "" && .FormatDepth == .Tokens.Depth() {
			return newInvalidFormatError(, , )
		}
		if .Flags.Get(jsonflags.MergeWithLegacySemantics) && !.IsNil() {
			// Legacy merge behavior is difficult to explain.
			// In general, it only merges for non-nil pointer kinds.
			// As a special case, unmarshaling a JSON null into a pointer
			// sets a concrete nil pointer of the underlying type
			// (rather than setting the interface value itself to nil).
			 := .Elem()
			if .Kind() == reflect.Pointer && !.IsNil() {
				if .PeekKind() == 'n' && .Elem().Kind() == reflect.Pointer {
					if ,  := .ReadToken();  != nil {
						return 
					}
					.Elem().Elem().SetZero()
					return nil
				}
			} else {
				.SetZero()
			}
		}
		if .PeekKind() == 'n' {
			if ,  := .ReadToken();  != nil {
				return 
			}
			.SetZero()
			return nil
		}
		var  addressableValue
		if .IsNil() {
			// Optimize for the any type if there are no special options.
			// We do not care about stringified numbers since JSON strings
			// are always unmarshaled into an any value as Go strings.
			// Duplicate name check must be enforced since unmarshalValueAny
			// does not implement merge semantics.
			if optimizeCommon &&
				 == anyType && !.Flags.Get(jsonflags.AllowDuplicateNames) && .Format == "" &&
				(.Unmarshalers == nil || !.Unmarshalers.(*Unmarshalers).fromAny) {
				,  := unmarshalValueAny(, )
				// We must check for nil interface values up front.
				// See https://go.dev/issue/52310.
				if  != nil {
					.Set(reflect.ValueOf())
				}
				return 
			}

			 := .PeekKind()
			if !isAnyType() {
				return newUnmarshalErrorBeforeWithSkipping(, , , errNilInterface)
			}
			switch  {
			case 'f', 't':
				 = newAddressableValue(boolType)
			case '"':
				 = newAddressableValue(stringType)
			case '0':
				if .Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) {
					 = addressableValue{reflect.ValueOf(internal.NewRawNumber()).Elem(), true}
				} else {
					 = newAddressableValue(float64Type)
				}
			case '{':
				 = newAddressableValue(mapStringAnyType)
			case '[':
				 = newAddressableValue(sliceAnyType)
			default:
				// If k is invalid (e.g., due to an I/O or syntax error), then
				// that will be cached by PeekKind and returned by ReadValue.
				// If k is '}' or ']', then ReadValue must error since
				// those are invalid kinds at the start of a JSON value.
				,  := .ReadValue()
				return 
			}
		} else {
			// Shallow copy the existing value to keep it addressable.
			// Any mutations at the top-level of the value will be observable
			// since we always store this value back into the interface value.
			 = newAddressableValue(.Elem().Type())
			.Set(.Elem())
		}
		 := lookupArshaler(.Type()).unmarshal
		if .Unmarshalers != nil {
			, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Type())
		}
		 := (, , )
		.Set(.Value)
		return 
	}
	return &
}

// isAnyType reports wether t is equivalent to the any interface type.
func isAnyType( reflect.Type) bool {
	// This is forward compatible if the Go language permits type sets within
	// ordinary interfaces where an interface with zero methods does not
	// necessarily mean it can hold every possible Go type.
	// See https://go.dev/issue/45346.
	return  == anyType || anyType.Implements()
}

func makeInvalidArshaler( reflect.Type) *arshaler {
	var  arshaler
	.marshal = func( *jsontext.Encoder,  addressableValue,  *jsonopts.Struct) error {
		return newMarshalErrorBefore(, , nil)
	}
	.unmarshal = func( *jsontext.Decoder,  addressableValue,  *jsonopts.Struct) error {
		return newUnmarshalErrorBefore(, , nil)
	}
	return &
}

func stringOrNumberKind( bool) jsontext.Kind {
	if  {
		return '"'
	} else {
		return '0'
	}
}

type uintSet64 uint64

func ( uintSet64) ( uint) bool { return &(1<<) > 0 }
func ( *uintSet64) ( uint)     { * |= 1 <<  }

// uintSet is a set of unsigned integers.
// It is optimized for most integers being close to zero.
type uintSet struct {
	lo uintSet64
	hi []uintSet64
}

// has reports whether i is in the set.
func ( *uintSet) ( uint) bool {
	if  < 64 {
		return .lo.has()
	} else {
		 -= 64
		,  := int(/64), %64
		return  < len(.hi) && .hi[].has()
	}
}

// insert inserts i into the set and reports whether it was the first insertion.
func ( *uintSet) ( uint) bool {
	// TODO: Make this inlinable at least for the lower 64-bit case.
	if  < 64 {
		 := .lo.has()
		.lo.set()
		return !
	} else {
		 -= 64
		,  := int(/64), %64
		if  >= len(.hi) {
			.hi = append(.hi, make([]uintSet64, +1-len(.hi))...)
			.hi = .hi[:cap(.hi)]
		}
		 := .hi[].has()
		.hi[].set()
		return !
	}
}