Source file src/encoding/json/v2/arshal_test.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  	"encoding"
    12  	"encoding/base32"
    13  	"encoding/base64"
    14  	"encoding/hex"
    15  	"errors"
    16  	"fmt"
    17  	"io"
    18  	"math"
    19  	"net"
    20  	"net/netip"
    21  	"reflect"
    22  	"strconv"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"encoding/json/internal"
    28  	"encoding/json/internal/jsonflags"
    29  	"encoding/json/internal/jsonopts"
    30  	"encoding/json/internal/jsontest"
    31  	"encoding/json/internal/jsonwire"
    32  	"encoding/json/jsontext"
    33  )
    34  
    35  func newNonStringNameError(offset int64, pointer jsontext.Pointer) error {
    36  	return &jsontext.SyntacticError{ByteOffset: offset, JSONPointer: pointer, Err: jsontext.ErrNonStringName}
    37  }
    38  
    39  func newInvalidCharacterError(prefix, where string, offset int64, pointer jsontext.Pointer) error {
    40  	return &jsontext.SyntacticError{ByteOffset: offset, JSONPointer: pointer, Err: jsonwire.NewInvalidCharacterError(prefix, where)}
    41  }
    42  
    43  func newInvalidUTF8Error(offset int64, pointer jsontext.Pointer) error {
    44  	return &jsontext.SyntacticError{ByteOffset: offset, JSONPointer: pointer, Err: jsonwire.ErrInvalidUTF8}
    45  }
    46  
    47  func newParseTimeError(layout, value, layoutElem, valueElem, message string) error {
    48  	return &time.ParseError{Layout: layout, Value: value, LayoutElem: layoutElem, ValueElem: valueElem, Message: message}
    49  }
    50  
    51  func EM(err error) *SemanticError {
    52  	return &SemanticError{action: "marshal", Err: err}
    53  }
    54  
    55  func EU(err error) *SemanticError {
    56  	return &SemanticError{action: "unmarshal", Err: err}
    57  }
    58  
    59  func (e *SemanticError) withVal(val string) *SemanticError {
    60  	e.JSONValue = jsontext.Value(val)
    61  	return e
    62  }
    63  
    64  func (e *SemanticError) withPos(prefix string, pointer jsontext.Pointer) *SemanticError {
    65  	e.ByteOffset = int64(len(prefix))
    66  	e.JSONPointer = pointer
    67  	return e
    68  }
    69  
    70  func (e *SemanticError) withType(k jsontext.Kind, t reflect.Type) *SemanticError {
    71  	e.JSONKind = k
    72  	e.GoType = t
    73  	return e
    74  }
    75  
    76  var (
    77  	errInvalidFormatFlag = errors.New(`invalid format flag "invalid"`)
    78  	errSomeError         = errors.New("some error")
    79  	errMustNotCall       = errors.New("must not call")
    80  )
    81  
    82  func T[T any]() reflect.Type { return reflect.TypeFor[T]() }
    83  
    84  type (
    85  	jsonObject = map[string]any
    86  	jsonArray  = []any
    87  
    88  	namedAny     any
    89  	namedBool    bool
    90  	namedString  string
    91  	NamedString  string
    92  	namedBytes   []byte
    93  	namedInt64   int64
    94  	namedUint64  uint64
    95  	namedFloat64 float64
    96  	namedByte    byte
    97  	netipAddr    = netip.Addr
    98  
    99  	recursiveMap     map[string]recursiveMap
   100  	recursiveSlice   []recursiveSlice
   101  	recursivePointer struct{ P *recursivePointer }
   102  
   103  	structEmpty       struct{}
   104  	structConflicting struct {
   105  		A string `json:"conflict"`
   106  		B string `json:"conflict"`
   107  	}
   108  	structNoneExported struct {
   109  		unexported string
   110  	}
   111  	structUnexportedIgnored struct {
   112  		ignored string `json:"-"`
   113  	}
   114  	structMalformedTag struct {
   115  		Malformed string `json:"\""`
   116  	}
   117  	structUnexportedTag struct {
   118  		unexported string `json:"name"`
   119  	}
   120  	structExportedEmbedded struct {
   121  		NamedString
   122  	}
   123  	structExportedEmbeddedTag struct {
   124  		NamedString `json:"name"`
   125  	}
   126  	structUnexportedEmbedded struct {
   127  		namedString
   128  	}
   129  	structUnexportedEmbeddedTag struct {
   130  		namedString `json:"name"`
   131  	}
   132  	structUnexportedEmbeddedMethodTag struct {
   133  		// netipAddr cannot be marshaled since the MarshalText method
   134  		// cannot be called on an unexported field.
   135  		netipAddr `json:"name"`
   136  
   137  		// Bogus MarshalText and AppendText methods are declared on
   138  		// structUnexportedEmbeddedMethodTag to prevent it from
   139  		// implementing those method interfaces.
   140  	}
   141  	structUnexportedEmbeddedStruct struct {
   142  		structOmitZeroAll
   143  		FizzBuzz int
   144  		structNestedAddr
   145  	}
   146  	structUnexportedEmbeddedStructPointer struct {
   147  		*structOmitZeroAll
   148  		FizzBuzz int
   149  		*structNestedAddr
   150  	}
   151  	structNestedAddr struct {
   152  		Addr netip.Addr
   153  	}
   154  	structIgnoredUnexportedEmbedded struct {
   155  		namedString `json:"-"`
   156  	}
   157  	structNoCase struct {
   158  		Aaa  string `json:",case:strict"`
   159  		AA_A string
   160  		AaA  string `json:",case:ignore"`
   161  		AAa  string `json:",case:ignore"`
   162  		AAA  string
   163  	}
   164  	structScalars struct {
   165  		unexported bool
   166  		Ignored    bool `json:"-"`
   167  
   168  		Bool   bool
   169  		String string
   170  		Bytes  []byte
   171  		Int    int64
   172  		Uint   uint64
   173  		Float  float64
   174  	}
   175  	structSlices struct {
   176  		unexported bool
   177  		Ignored    bool `json:"-"`
   178  
   179  		SliceBool   []bool
   180  		SliceString []string
   181  		SliceBytes  [][]byte
   182  		SliceInt    []int64
   183  		SliceUint   []uint64
   184  		SliceFloat  []float64
   185  	}
   186  	structMaps struct {
   187  		unexported bool
   188  		Ignored    bool `json:"-"`
   189  
   190  		MapBool   map[string]bool
   191  		MapString map[string]string
   192  		MapBytes  map[string][]byte
   193  		MapInt    map[string]int64
   194  		MapUint   map[string]uint64
   195  		MapFloat  map[string]float64
   196  	}
   197  	structAll struct {
   198  		Bool          bool
   199  		String        string
   200  		Bytes         []byte
   201  		Int           int64
   202  		Uint          uint64
   203  		Float         float64
   204  		Map           map[string]string
   205  		StructScalars structScalars
   206  		StructMaps    structMaps
   207  		StructSlices  structSlices
   208  		Slice         []string
   209  		Array         [1]string
   210  		Pointer       *structAll
   211  		Interface     any
   212  	}
   213  	structOmitZeroAll struct {
   214  		Bool          bool               `json:",omitzero"`
   215  		String        string             `json:",omitzero"`
   216  		Bytes         []byte             `json:",omitzero"`
   217  		Int           int64              `json:",omitzero"`
   218  		Uint          uint64             `json:",omitzero"`
   219  		Float         float64            `json:",omitzero"`
   220  		Map           map[string]string  `json:",omitzero"`
   221  		StructScalars structScalars      `json:",omitzero"`
   222  		StructMaps    structMaps         `json:",omitzero"`
   223  		StructSlices  structSlices       `json:",omitzero"`
   224  		Slice         []string           `json:",omitzero"`
   225  		Array         [1]string          `json:",omitzero"`
   226  		Pointer       *structOmitZeroAll `json:",omitzero"`
   227  		Interface     any                `json:",omitzero"`
   228  	}
   229  	structOmitZeroMethodAll struct {
   230  		ValueAlwaysZero                 valueAlwaysZero     `json:",omitzero"`
   231  		ValueNeverZero                  valueNeverZero      `json:",omitzero"`
   232  		PointerAlwaysZero               pointerAlwaysZero   `json:",omitzero"`
   233  		PointerNeverZero                pointerNeverZero    `json:",omitzero"`
   234  		PointerValueAlwaysZero          *valueAlwaysZero    `json:",omitzero"`
   235  		PointerValueNeverZero           *valueNeverZero     `json:",omitzero"`
   236  		PointerPointerAlwaysZero        *pointerAlwaysZero  `json:",omitzero"`
   237  		PointerPointerNeverZero         *pointerNeverZero   `json:",omitzero"`
   238  		PointerPointerValueAlwaysZero   **valueAlwaysZero   `json:",omitzero"`
   239  		PointerPointerValueNeverZero    **valueNeverZero    `json:",omitzero"`
   240  		PointerPointerPointerAlwaysZero **pointerAlwaysZero `json:",omitzero"`
   241  		PointerPointerPointerNeverZero  **pointerNeverZero  `json:",omitzero"`
   242  	}
   243  	structOmitZeroMethodInterfaceAll struct {
   244  		ValueAlwaysZero          isZeroer `json:",omitzero"`
   245  		ValueNeverZero           isZeroer `json:",omitzero"`
   246  		PointerValueAlwaysZero   isZeroer `json:",omitzero"`
   247  		PointerValueNeverZero    isZeroer `json:",omitzero"`
   248  		PointerPointerAlwaysZero isZeroer `json:",omitzero"`
   249  		PointerPointerNeverZero  isZeroer `json:",omitzero"`
   250  	}
   251  	structOmitEmptyAll struct {
   252  		Bool                  bool                    `json:",omitempty"`
   253  		PointerBool           *bool                   `json:",omitempty"`
   254  		String                string                  `json:",omitempty"`
   255  		StringEmpty           stringMarshalEmpty      `json:",omitempty"`
   256  		StringNonEmpty        stringMarshalNonEmpty   `json:",omitempty"`
   257  		PointerString         *string                 `json:",omitempty"`
   258  		PointerStringEmpty    *stringMarshalEmpty     `json:",omitempty"`
   259  		PointerStringNonEmpty *stringMarshalNonEmpty  `json:",omitempty"`
   260  		Bytes                 []byte                  `json:",omitempty"`
   261  		BytesEmpty            bytesMarshalEmpty       `json:",omitempty"`
   262  		BytesNonEmpty         bytesMarshalNonEmpty    `json:",omitempty"`
   263  		PointerBytes          *[]byte                 `json:",omitempty"`
   264  		PointerBytesEmpty     *bytesMarshalEmpty      `json:",omitempty"`
   265  		PointerBytesNonEmpty  *bytesMarshalNonEmpty   `json:",omitempty"`
   266  		Float                 float64                 `json:",omitempty"`
   267  		PointerFloat          *float64                `json:",omitempty"`
   268  		Map                   map[string]string       `json:",omitempty"`
   269  		MapEmpty              mapMarshalEmpty         `json:",omitempty"`
   270  		MapNonEmpty           mapMarshalNonEmpty      `json:",omitempty"`
   271  		PointerMap            *map[string]string      `json:",omitempty"`
   272  		PointerMapEmpty       *mapMarshalEmpty        `json:",omitempty"`
   273  		PointerMapNonEmpty    *mapMarshalNonEmpty     `json:",omitempty"`
   274  		Slice                 []string                `json:",omitempty"`
   275  		SliceEmpty            sliceMarshalEmpty       `json:",omitempty"`
   276  		SliceNonEmpty         sliceMarshalNonEmpty    `json:",omitempty"`
   277  		PointerSlice          *[]string               `json:",omitempty"`
   278  		PointerSliceEmpty     *sliceMarshalEmpty      `json:",omitempty"`
   279  		PointerSliceNonEmpty  *sliceMarshalNonEmpty   `json:",omitempty"`
   280  		Pointer               *structOmitZeroEmptyAll `json:",omitempty"`
   281  		Interface             any                     `json:",omitempty"`
   282  	}
   283  	structOmitZeroEmptyAll struct {
   284  		Bool      bool                    `json:",omitzero,omitempty"`
   285  		String    string                  `json:",omitzero,omitempty"`
   286  		Bytes     []byte                  `json:",omitzero,omitempty"`
   287  		Int       int64                   `json:",omitzero,omitempty"`
   288  		Uint      uint64                  `json:",omitzero,omitempty"`
   289  		Float     float64                 `json:",omitzero,omitempty"`
   290  		Map       map[string]string       `json:",omitzero,omitempty"`
   291  		Slice     []string                `json:",omitzero,omitempty"`
   292  		Array     [1]string               `json:",omitzero,omitempty"`
   293  		Pointer   *structOmitZeroEmptyAll `json:",omitzero,omitempty"`
   294  		Interface any                     `json:",omitzero,omitempty"`
   295  	}
   296  	structStringifiedLegacy struct {
   297  		Bool          bool     `json:",string"`
   298  		String        string   `json:",string"`
   299  		Int           int64    `json:",string"`
   300  		Uint          uint64   `json:",string"`
   301  		Float         float64  `json:",string"`
   302  		PointerBool   *bool    `json:",string"`
   303  		PointerString *string  `json:",string"`
   304  		PointerInt    *int64   `json:",string"`
   305  		PointerUint   *uint64  `json:",string"`
   306  		PointerFloat  *float64 `json:",string"`
   307  	}
   308  	structStringified struct {
   309  		Int          int64    `json:",string"`
   310  		Uint         uint64   `json:",string"`
   311  		Float        float64  `json:",string"`
   312  		PointerInt   *int64   `json:",string"`
   313  		PointerUint  *uint64  `json:",string"`
   314  		PointerFloat *float64 `json:",string"`
   315  	}
   316  	structStringifiedBool struct {
   317  		Bool bool `json:",string"`
   318  	}
   319  	structStringifiedString struct {
   320  		String string `json:",string"`
   321  	}
   322  	structStringifiedBytes struct {
   323  		Bytes []byte `json:",string"`
   324  	}
   325  	structStringifiedMap struct {
   326  		Map map[string]string `json:",string"`
   327  	}
   328  	structStringifiedSlice struct {
   329  		Slice []string `json:",string"`
   330  	}
   331  	structStringifiedArray struct {
   332  		Array [1]string `json:",string"`
   333  	}
   334  	structStringifiedStruct struct {
   335  		Struct structAll `json:",string"`
   336  	}
   337  	structStringifiedPointer struct {
   338  		Pointer *structAll `json:",string"`
   339  	}
   340  	structStringifiedPointerPointerInt struct {
   341  		Pointer **int `json:",string"`
   342  	}
   343  	structStringifiedInterface struct {
   344  		Interface any `json:",string"`
   345  	}
   346  	structFormatBytes struct {
   347  		Base16    []byte `json:",format:base16"`
   348  		Base32    []byte `json:",format:base32"`
   349  		Base32Hex []byte `json:",format:base32hex"`
   350  		Base64    []byte `json:",format:base64"`
   351  		Base64URL []byte `json:",format:base64url"`
   352  		Array     []byte `json:",format:array"`
   353  	}
   354  	structFormatArrayBytes struct {
   355  		Base16    [4]byte `json:",format:base16"`
   356  		Base32    [4]byte `json:",format:base32"`
   357  		Base32Hex [4]byte `json:",format:base32hex"`
   358  		Base64    [4]byte `json:",format:base64"`
   359  		Base64URL [4]byte `json:",format:base64url"`
   360  		Array     [4]byte `json:",format:array"`
   361  		Default   [4]byte
   362  	}
   363  	structFormatFloats struct {
   364  		NonFinite        float64  `json:",format:nonfinite"`
   365  		PointerNonFinite *float64 `json:",format:nonfinite"`
   366  	}
   367  	structFormatMaps struct {
   368  		EmitNull           map[string]string  `json:",format:emitnull"`
   369  		PointerEmitNull    *map[string]string `json:",format:emitnull"`
   370  		EmitEmpty          map[string]string  `json:",format:emitempty"`
   371  		PointerEmitEmpty   *map[string]string `json:",format:emitempty"`
   372  		EmitDefault        map[string]string
   373  		PointerEmitDefault *map[string]string
   374  	}
   375  	structFormatSlices struct {
   376  		EmitNull           []string  `json:",format:emitnull"`
   377  		PointerEmitNull    *[]string `json:",format:emitnull"`
   378  		EmitEmpty          []string  `json:",format:emitempty"`
   379  		PointerEmitEmpty   *[]string `json:",format:emitempty"`
   380  		EmitDefault        []string
   381  		PointerEmitDefault *[]string
   382  	}
   383  	structFormatInvalid struct {
   384  		Bool      bool              `json:",omitzero,format:invalid"`
   385  		String    string            `json:",omitzero,format:invalid"`
   386  		Bytes     []byte            `json:",omitzero,format:invalid"`
   387  		Int       int64             `json:",omitzero,format:invalid"`
   388  		Uint      uint64            `json:",omitzero,format:invalid"`
   389  		Float     float64           `json:",omitzero,format:invalid"`
   390  		Map       map[string]string `json:",omitzero,format:invalid"`
   391  		Struct    structAll         `json:",omitzero,format:invalid"`
   392  		Slice     []string          `json:",omitzero,format:invalid"`
   393  		Array     [1]string         `json:",omitzero,format:invalid"`
   394  		Interface any               `json:",omitzero,format:invalid"`
   395  	}
   396  	structDurationFormat struct {
   397  		D1  time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
   398  		D2  time.Duration `json:",format:units"`
   399  		D3  time.Duration `json:",format:sec"`
   400  		D4  time.Duration `json:",string,format:sec"`
   401  		D5  time.Duration `json:",format:milli"`
   402  		D6  time.Duration `json:",string,format:milli"`
   403  		D7  time.Duration `json:",format:micro"`
   404  		D8  time.Duration `json:",string,format:micro"`
   405  		D9  time.Duration `json:",format:nano"`
   406  		D10 time.Duration `json:",string,format:nano"`
   407  		D11 time.Duration `json:",format:iso8601"`
   408  	}
   409  	structTimeFormat struct {
   410  		T1  time.Time
   411  		T2  time.Time `json:",format:ANSIC"`
   412  		T3  time.Time `json:",format:UnixDate"`
   413  		T4  time.Time `json:",format:RubyDate"`
   414  		T5  time.Time `json:",format:RFC822"`
   415  		T6  time.Time `json:",format:RFC822Z"`
   416  		T7  time.Time `json:",format:RFC850"`
   417  		T8  time.Time `json:",format:RFC1123"`
   418  		T9  time.Time `json:",format:RFC1123Z"`
   419  		T10 time.Time `json:",format:RFC3339"`
   420  		T11 time.Time `json:",format:RFC3339Nano"`
   421  		T12 time.Time `json:",format:Kitchen"`
   422  		T13 time.Time `json:",format:Stamp"`
   423  		T14 time.Time `json:",format:StampMilli"`
   424  		T15 time.Time `json:",format:StampMicro"`
   425  		T16 time.Time `json:",format:StampNano"`
   426  		T17 time.Time `json:",format:DateTime"`
   427  		T18 time.Time `json:",format:DateOnly"`
   428  		T19 time.Time `json:",format:TimeOnly"`
   429  		T20 time.Time `json:",format:'2006-01-02'"`
   430  		T21 time.Time `json:",format:'\"weird\"2006'"`
   431  		T22 time.Time `json:",format:unix"`
   432  		T23 time.Time `json:",string,format:unix"`
   433  		T24 time.Time `json:",format:unixmilli"`
   434  		T25 time.Time `json:",string,format:unixmilli"`
   435  		T26 time.Time `json:",format:unixmicro"`
   436  		T27 time.Time `json:",string,format:unixmicro"`
   437  		T28 time.Time `json:",format:unixnano"`
   438  		T29 time.Time `json:",string,format:unixnano"`
   439  	}
   440  	structTimeFormatStringInvalid struct {
   441  		T time.Time `json:",string,format:RFC3339"`
   442  	}
   443  	structEmbedded struct {
   444  		X             structEmbeddedL1 `json:",embed"`
   445  		*StructEmbed2                  // implicit embed
   446  	}
   447  	structEmbeddedL1 struct {
   448  		X            *structEmbeddedL2 `json:",embed"`
   449  		StructEmbed1 `json:",embed"`
   450  	}
   451  	structEmbeddedL2     struct{ A, B, C string }
   452  	StructEmbed1         struct{ C, D, E string }
   453  	StructEmbed2         struct{ E, F, G string }
   454  	structEmbedTextValue struct {
   455  		A int            `json:",omitzero"`
   456  		X jsontext.Value `json:",embed"`
   457  		B int            `json:",omitzero"`
   458  	}
   459  	structEmbedPointerTextValue struct {
   460  		A int             `json:",omitzero"`
   461  		X *jsontext.Value `json:",embed"`
   462  		B int             `json:",omitzero"`
   463  	}
   464  	structEmbedPointerEmbedTextValue struct {
   465  		X *struct {
   466  			A int
   467  			X jsontext.Value `json:",embed"`
   468  		} `json:",embed"`
   469  	}
   470  	structEmbedEmbedPointerTextValue struct {
   471  		X struct {
   472  			X *jsontext.Value `json:",embed"`
   473  		} `json:",embed"`
   474  	}
   475  	structEmbedMapStringAny struct {
   476  		A int        `json:",omitzero"`
   477  		X jsonObject `json:",embed"`
   478  		B int        `json:",omitzero"`
   479  	}
   480  	structEmbedPointerMapStringAny struct {
   481  		A int         `json:",omitzero"`
   482  		X *jsonObject `json:",embed"`
   483  		B int         `json:",omitzero"`
   484  	}
   485  	structEmbedPointerEmbedMapStringAny struct {
   486  		X *struct {
   487  			A int
   488  			X jsonObject `json:",embed"`
   489  		} `json:",embed"`
   490  	}
   491  	structEmbedEmbedPointerMapStringAny struct {
   492  		X struct {
   493  			X *jsonObject `json:",embed"`
   494  		} `json:",embed"`
   495  	}
   496  	structEmbedMapStringInt struct {
   497  		X map[string]int `json:",embed"`
   498  	}
   499  	structEmbedMapNamedStringInt struct {
   500  		X map[namedString]int `json:",embed"`
   501  	}
   502  	structEmbedMapNamedStringAny struct {
   503  		A int                 `json:",omitzero"`
   504  		X map[namedString]any `json:",embed"`
   505  		B int                 `json:",omitzero"`
   506  	}
   507  	structNoCaseEmbedTextValue struct {
   508  		AAA  string         `json:",omitempty,case:strict"`
   509  		AA_b string         `json:",omitempty"`
   510  		AaA  string         `json:",omitempty,case:ignore"`
   511  		AAa  string         `json:",omitempty,case:ignore"`
   512  		Aaa  string         `json:",omitempty"`
   513  		X    jsontext.Value `json:",embed"`
   514  	}
   515  	structNoCaseEmbedMapStringAny struct {
   516  		AAA string     `json:",omitempty"`
   517  		AaA string     `json:",omitempty,case:ignore"`
   518  		AAa string     `json:",omitempty,case:ignore"`
   519  		Aaa string     `json:",omitempty"`
   520  		X   jsonObject `json:",embed"`
   521  	}
   522  
   523  	allMethods struct {
   524  		method string // the method that was called
   525  		value  []byte // the raw value to provide or store
   526  	}
   527  	allMethodsExceptJSONv2 struct {
   528  		allMethods
   529  		MarshalJSONTo     struct{} // cancel out MarshalJSONTo method with collision
   530  		UnmarshalJSONFrom struct{} // cancel out UnmarshalJSONFrom method with collision
   531  	}
   532  	allMethodsExceptJSONv1 struct {
   533  		allMethods
   534  		MarshalJSON   struct{} // cancel out MarshalJSON method with collision
   535  		UnmarshalJSON struct{} // cancel out UnmarshalJSON method with collision
   536  	}
   537  	allMethodsExceptText struct {
   538  		allMethods
   539  		MarshalText   struct{} // cancel out MarshalText method with collision
   540  		UnmarshalText struct{} // cancel out UnmarshalText method with collision
   541  	}
   542  	onlyMethodJSONv2 struct {
   543  		allMethods
   544  		MarshalJSON   struct{} // cancel out MarshalJSON method with collision
   545  		UnmarshalJSON struct{} // cancel out UnmarshalJSON method with collision
   546  		MarshalText   struct{} // cancel out MarshalText method with collision
   547  		UnmarshalText struct{} // cancel out UnmarshalText method with collision
   548  	}
   549  	onlyMethodJSONv1 struct {
   550  		allMethods
   551  		MarshalJSONTo     struct{} // cancel out MarshalJSONTo method with collision
   552  		UnmarshalJSONFrom struct{} // cancel out UnmarshalJSONFrom method with collision
   553  		MarshalText       struct{} // cancel out MarshalText method with collision
   554  		UnmarshalText     struct{} // cancel out UnmarshalText method with collision
   555  	}
   556  	onlyMethodText struct {
   557  		allMethods
   558  		MarshalJSONTo     struct{} // cancel out MarshalJSONTo method with collision
   559  		UnmarshalJSONFrom struct{} // cancel out UnmarshalJSONFrom method with collision
   560  		MarshalJSON       struct{} // cancel out MarshalJSON method with collision
   561  		UnmarshalJSON     struct{} // cancel out UnmarshalJSON method with collision
   562  	}
   563  
   564  	unsupportedMethodJSONv2 map[string]int
   565  
   566  	structMethodJSONv2 struct{ value string }
   567  	structMethodJSONv1 struct{ value string }
   568  	structMethodText   struct{ value string }
   569  
   570  	marshalJSONv2Func   func(*jsontext.Encoder) error
   571  	marshalJSONv1Func   func() ([]byte, error)
   572  	appendTextFunc      func([]byte) ([]byte, error)
   573  	marshalTextFunc     func() ([]byte, error)
   574  	unmarshalJSONv2Func func(*jsontext.Decoder) error
   575  	unmarshalJSONv1Func func([]byte) error
   576  	unmarshalTextFunc   func([]byte) error
   577  
   578  	nocaseString string
   579  
   580  	stringMarshalEmpty    string
   581  	stringMarshalNonEmpty string
   582  	bytesMarshalEmpty     []byte
   583  	bytesMarshalNonEmpty  []byte
   584  	mapMarshalEmpty       map[string]string
   585  	mapMarshalNonEmpty    map[string]string
   586  	sliceMarshalEmpty     []string
   587  	sliceMarshalNonEmpty  []string
   588  
   589  	valueAlwaysZero   string
   590  	valueNeverZero    string
   591  	pointerAlwaysZero string
   592  	pointerNeverZero  string
   593  
   594  	valueStringer   struct{}
   595  	pointerStringer struct{}
   596  
   597  	cyclicA struct {
   598  		B1 cyclicB `json:",embed"`
   599  		B2 cyclicB `json:",embed"`
   600  	}
   601  	cyclicB struct {
   602  		F int
   603  		A *cyclicA `json:",embed"`
   604  	}
   605  )
   606  
   607  func (structUnexportedEmbeddedMethodTag) MarshalText() {}
   608  func (structUnexportedEmbeddedMethodTag) AppendText()  {}
   609  
   610  func (p *allMethods) MarshalJSONTo(enc *jsontext.Encoder) error {
   611  	if got, want := "MarshalJSONTo", p.method; got != want {
   612  		return fmt.Errorf("called wrong method: got %v, want %v", got, want)
   613  	}
   614  	return enc.WriteValue(p.value)
   615  }
   616  func (p *allMethods) MarshalJSON() ([]byte, error) {
   617  	if got, want := "MarshalJSON", p.method; got != want {
   618  		return nil, fmt.Errorf("called wrong method: got %v, want %v", got, want)
   619  	}
   620  	return p.value, nil
   621  }
   622  func (p *allMethods) MarshalText() ([]byte, error) {
   623  	if got, want := "MarshalText", p.method; got != want {
   624  		return nil, fmt.Errorf("called wrong method: got %v, want %v", got, want)
   625  	}
   626  	return p.value, nil
   627  }
   628  
   629  func (p *allMethods) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
   630  	p.method = "UnmarshalJSONFrom"
   631  	val, err := dec.ReadValue()
   632  	p.value = val
   633  	return err
   634  }
   635  func (p *allMethods) UnmarshalJSON(val []byte) error {
   636  	p.method = "UnmarshalJSON"
   637  	p.value = val
   638  	return nil
   639  }
   640  func (p *allMethods) UnmarshalText(val []byte) error {
   641  	p.method = "UnmarshalText"
   642  	p.value = val
   643  	return nil
   644  }
   645  
   646  func (s *unsupportedMethodJSONv2) MarshalJSONTo(enc *jsontext.Encoder) error {
   647  	(*s)["called"] += 1
   648  	return errors.ErrUnsupported
   649  }
   650  func (s *unsupportedMethodJSONv2) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
   651  	(*s)["called"] += 1
   652  	return errors.ErrUnsupported
   653  }
   654  
   655  func (s structMethodJSONv2) MarshalJSONTo(enc *jsontext.Encoder) error {
   656  	return enc.WriteToken(jsontext.String(s.value))
   657  }
   658  func (s *structMethodJSONv2) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
   659  	tok, err := dec.ReadToken()
   660  	if err != nil {
   661  		return err
   662  	}
   663  	if k := tok.Kind(); k != '"' {
   664  		return EU(nil).withType(k, T[structMethodJSONv2]())
   665  	}
   666  	s.value = tok.String()
   667  	return nil
   668  }
   669  
   670  func (s structMethodJSONv1) MarshalJSON() ([]byte, error) {
   671  	return jsontext.AppendQuote(nil, s.value)
   672  }
   673  func (s *structMethodJSONv1) UnmarshalJSON(b []byte) error {
   674  	if k := jsontext.Value(b).Kind(); k != '"' {
   675  		return EU(nil).withType(k, T[structMethodJSONv1]())
   676  	}
   677  	b, _ = jsontext.AppendUnquote(nil, b)
   678  	s.value = string(b)
   679  	return nil
   680  }
   681  
   682  func (s structMethodText) MarshalText() ([]byte, error) {
   683  	return []byte(s.value), nil
   684  }
   685  func (s *structMethodText) UnmarshalText(b []byte) error {
   686  	s.value = string(b)
   687  	return nil
   688  }
   689  
   690  func (f marshalJSONv2Func) MarshalJSONTo(enc *jsontext.Encoder) error {
   691  	return f(enc)
   692  }
   693  func (f marshalJSONv1Func) MarshalJSON() ([]byte, error) {
   694  	return f()
   695  }
   696  func (f appendTextFunc) AppendText(b []byte) ([]byte, error) {
   697  	return f(b)
   698  }
   699  func (f marshalTextFunc) MarshalText() ([]byte, error) {
   700  	return f()
   701  }
   702  func (f unmarshalJSONv2Func) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
   703  	return f(dec)
   704  }
   705  func (f unmarshalJSONv1Func) UnmarshalJSON(b []byte) error {
   706  	return f(b)
   707  }
   708  func (f unmarshalTextFunc) UnmarshalText(b []byte) error {
   709  	return f(b)
   710  }
   711  
   712  func (k nocaseString) MarshalText() ([]byte, error) {
   713  	return []byte(strings.ToLower(string(k))), nil
   714  }
   715  func (k *nocaseString) UnmarshalText(b []byte) error {
   716  	*k = nocaseString(strings.ToLower(string(b)))
   717  	return nil
   718  }
   719  
   720  func (stringMarshalEmpty) MarshalJSON() ([]byte, error)    { return []byte(`""`), nil }
   721  func (stringMarshalNonEmpty) MarshalJSON() ([]byte, error) { return []byte(`"value"`), nil }
   722  func (bytesMarshalEmpty) MarshalJSON() ([]byte, error)     { return []byte(`[]`), nil }
   723  func (bytesMarshalNonEmpty) MarshalJSON() ([]byte, error)  { return []byte(`["value"]`), nil }
   724  func (mapMarshalEmpty) MarshalJSON() ([]byte, error)       { return []byte(`{}`), nil }
   725  func (mapMarshalNonEmpty) MarshalJSON() ([]byte, error)    { return []byte(`{"key":"value"}`), nil }
   726  func (sliceMarshalEmpty) MarshalJSON() ([]byte, error)     { return []byte(`[]`), nil }
   727  func (sliceMarshalNonEmpty) MarshalJSON() ([]byte, error)  { return []byte(`["value"]`), nil }
   728  
   729  func (valueAlwaysZero) IsZero() bool    { return true }
   730  func (valueNeverZero) IsZero() bool     { return false }
   731  func (*pointerAlwaysZero) IsZero() bool { return true }
   732  func (*pointerNeverZero) IsZero() bool  { return false }
   733  
   734  func (valueStringer) String() string    { return "" }
   735  func (*pointerStringer) String() string { return "" }
   736  
   737  func addr[T any](v T) *T {
   738  	return &v
   739  }
   740  
   741  func mustParseTime(layout, value string) time.Time {
   742  	t, err := time.Parse(layout, value)
   743  	if err != nil {
   744  		panic(err)
   745  	}
   746  	return t
   747  }
   748  
   749  // invalidFormatOption is an option where the Format field is set,
   750  // but jsonflags.FormatTag has been cleared. In such a case,
   751  // the Format field should be ignored.
   752  var invalidFormatOption = &jsonopts.Struct{
   753  	ArshalValues: jsonopts.ArshalValues{Format: "invalid"},
   754  }
   755  
   756  func TestMarshal(t *testing.T) {
   757  	tests := []struct {
   758  		name    jsontest.CaseName
   759  		opts    []Options
   760  		in      any
   761  		want    string
   762  		wantErr error
   763  
   764  		canonicalize bool // canonicalize the output before comparing?
   765  		useWriter    bool // call MarshalWrite instead of Marshal
   766  	}{{
   767  		name: jsontest.Name("Nil"),
   768  		in:   nil,
   769  		want: `null`,
   770  	}, {
   771  		name: jsontest.Name("Bools"),
   772  		in:   []bool{false, true},
   773  		want: `[false,true]`,
   774  	}, {
   775  		name: jsontest.Name("Bools/Named"),
   776  		in:   []namedBool{false, true},
   777  		want: `[false,true]`,
   778  	}, {
   779  		name: jsontest.Name("Bools/NotStringified"),
   780  		opts: []Options{StringifyNumbers(true)},
   781  		in:   []bool{false, true},
   782  		want: `[false,true]`,
   783  	}, {
   784  		name: jsontest.Name("Bools/StringifiedBool/False"),
   785  		opts: []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
   786  		in:   false,
   787  		want: `"false"`,
   788  	}, {
   789  		name: jsontest.Name("Bools/StringifiedBool/True"),
   790  		opts: []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
   791  		in:   true,
   792  		want: `"true"`,
   793  	}, {
   794  		name: jsontest.Name("Bools/IgnoreInvalidFormat"),
   795  		opts: []Options{invalidFormatOption},
   796  		in:   true,
   797  		want: `true`,
   798  	}, {
   799  		name: jsontest.Name("Strings"),
   800  		in:   []string{"", "hello", "世界"},
   801  		want: `["","hello","世界"]`,
   802  	}, {
   803  		name: jsontest.Name("Strings/Named"),
   804  		in:   []namedString{"", "hello", "世界"},
   805  		want: `["","hello","世界"]`,
   806  	}, {
   807  		name: jsontest.Name("Strings/StringifiedString"),
   808  		opts: []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
   809  		in:   "hello",
   810  		want: `"\"hello\""`,
   811  	}, {
   812  		name: jsontest.Name("Strings/IgnoreInvalidFormat"),
   813  		opts: []Options{invalidFormatOption},
   814  		in:   "string",
   815  		want: `"string"`,
   816  	}, {
   817  		name: jsontest.Name("Bytes"),
   818  		in:   [][]byte{nil, {}, {1}, {1, 2}, {1, 2, 3}},
   819  		want: `["","","AQ==","AQI=","AQID"]`,
   820  	}, {
   821  		name: jsontest.Name("Bytes/FormatNilSliceAsNull"),
   822  		opts: []Options{FormatNilSliceAsNull(true)},
   823  		in:   [][]byte{nil, {}},
   824  		want: `[null,""]`,
   825  	}, {
   826  		name: jsontest.Name("Bytes/Large"),
   827  		in:   []byte("the quick brown fox jumped over the lazy dog and ate the homework that I spent so much time on."),
   828  		want: `"dGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cgYW5kIGF0ZSB0aGUgaG9tZXdvcmsgdGhhdCBJIHNwZW50IHNvIG11Y2ggdGltZSBvbi4="`,
   829  	}, {
   830  		name: jsontest.Name("Bytes/Named"),
   831  		in:   []namedBytes{nil, {}, {1}, {1, 2}, {1, 2, 3}},
   832  		want: `["","","AQ==","AQI=","AQID"]`,
   833  	}, {
   834  		name: jsontest.Name("Bytes/NotStringified"),
   835  		opts: []Options{StringifyNumbers(true)},
   836  		in:   [][]byte{nil, {}, {1}, {1, 2}, {1, 2, 3}},
   837  		want: `["","","AQ==","AQI=","AQID"]`,
   838  	}, {
   839  		// NOTE: []namedByte is not assignable to []byte,
   840  		// so the following should be treated as a slice of uints.
   841  		name: jsontest.Name("Bytes/Invariant"),
   842  		in:   [][]namedByte{nil, {}, {1}, {1, 2}, {1, 2, 3}},
   843  		want: `[[],[],[1],[1,2],[1,2,3]]`,
   844  	}, {
   845  		// NOTE: This differs in behavior from v1,
   846  		// but keeps the representation of slices and arrays more consistent.
   847  		name: jsontest.Name("Bytes/ByteArray"),
   848  		in:   [5]byte{'h', 'e', 'l', 'l', 'o'},
   849  		want: `"aGVsbG8="`,
   850  	}, {
   851  		// NOTE: []namedByte is not assignable to []byte,
   852  		// so the following should be treated as an array of uints.
   853  		name: jsontest.Name("Bytes/NamedByteArray"),
   854  		in:   [5]namedByte{'h', 'e', 'l', 'l', 'o'},
   855  		want: `[104,101,108,108,111]`,
   856  	}, {
   857  		name: jsontest.Name("Bytes/IgnoreInvalidFormat"),
   858  		opts: []Options{invalidFormatOption},
   859  		in:   []byte("hello"),
   860  		want: `"aGVsbG8="`,
   861  	}, {
   862  		name: jsontest.Name("Ints"),
   863  		in: []any{
   864  			int(0), int8(math.MinInt8), int16(math.MinInt16), int32(math.MinInt32), int64(math.MinInt64), namedInt64(-6464),
   865  		},
   866  		want: `[0,-128,-32768,-2147483648,-9223372036854775808,-6464]`,
   867  	}, {
   868  		name: jsontest.Name("Ints/Stringified"),
   869  		opts: []Options{StringifyNumbers(true)},
   870  		in: []any{
   871  			int(0), int8(math.MinInt8), int16(math.MinInt16), int32(math.MinInt32), int64(math.MinInt64), namedInt64(-6464),
   872  		},
   873  		want: `["0","-128","-32768","-2147483648","-9223372036854775808","-6464"]`,
   874  	}, {
   875  		name: jsontest.Name("Ints/IgnoreInvalidFormat"),
   876  		opts: []Options{invalidFormatOption},
   877  		in:   int(0),
   878  		want: `0`,
   879  	}, {
   880  		name: jsontest.Name("Uints"),
   881  		in: []any{
   882  			uint(0), uint8(math.MaxUint8), uint16(math.MaxUint16), uint32(math.MaxUint32), uint64(math.MaxUint64), namedUint64(6464), uintptr(1234),
   883  		},
   884  		want: `[0,255,65535,4294967295,18446744073709551615,6464,1234]`,
   885  	}, {
   886  		name: jsontest.Name("Uints/Stringified"),
   887  		opts: []Options{StringifyNumbers(true)},
   888  		in: []any{
   889  			uint(0), uint8(math.MaxUint8), uint16(math.MaxUint16), uint32(math.MaxUint32), uint64(math.MaxUint64), namedUint64(6464),
   890  		},
   891  		want: `["0","255","65535","4294967295","18446744073709551615","6464"]`,
   892  	}, {
   893  		name: jsontest.Name("Uints/IgnoreInvalidFormat"),
   894  		opts: []Options{invalidFormatOption},
   895  		in:   uint(0),
   896  		want: `0`,
   897  	}, {
   898  		name: jsontest.Name("Floats"),
   899  		in: []any{
   900  			float32(math.MaxFloat32), float64(math.MaxFloat64), namedFloat64(64.64),
   901  		},
   902  		want: `[3.4028235e+38,1.7976931348623157e+308,64.64]`,
   903  	}, {
   904  		name: jsontest.Name("Floats/Stringified"),
   905  		opts: []Options{StringifyNumbers(true)},
   906  		in: []any{
   907  			float32(math.MaxFloat32), float64(math.MaxFloat64), namedFloat64(64.64),
   908  		},
   909  		want: `["3.4028235e+38","1.7976931348623157e+308","64.64"]`,
   910  	}, {
   911  		name:    jsontest.Name("Floats/Invalid/NaN"),
   912  		opts:    []Options{StringifyNumbers(true)},
   913  		in:      math.NaN(),
   914  		wantErr: EM(fmt.Errorf("unsupported value: %v", math.NaN())).withType(0, float64Type),
   915  	}, {
   916  		name:    jsontest.Name("Floats/Invalid/PositiveInfinity"),
   917  		in:      math.Inf(+1),
   918  		wantErr: EM(fmt.Errorf("unsupported value: %v", math.Inf(+1))).withType(0, float64Type),
   919  	}, {
   920  		name:    jsontest.Name("Floats/Invalid/NegativeInfinity"),
   921  		in:      math.Inf(-1),
   922  		wantErr: EM(fmt.Errorf("unsupported value: %v", math.Inf(-1))).withType(0, float64Type),
   923  	}, {
   924  		name: jsontest.Name("Floats/IgnoreInvalidFormat"),
   925  		opts: []Options{invalidFormatOption},
   926  		in:   float64(0),
   927  		want: `0`,
   928  	}, {
   929  		name:    jsontest.Name("Maps/InvalidKey/Bool"),
   930  		in:      map[bool]string{false: "value"},
   931  		want:    `{`,
   932  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, boolType),
   933  	}, {
   934  		name:    jsontest.Name("Maps/InvalidKey/NamedBool"),
   935  		in:      map[namedBool]string{false: "value"},
   936  		want:    `{`,
   937  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, T[namedBool]()),
   938  	}, {
   939  		name:    jsontest.Name("Maps/InvalidKey/Array"),
   940  		in:      map[[1]string]string{{"key"}: "value"},
   941  		want:    `{`,
   942  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, T[[1]string]()),
   943  	}, {
   944  		name:    jsontest.Name("Maps/InvalidKey/Channel"),
   945  		in:      map[chan string]string{make(chan string): "value"},
   946  		want:    `{`,
   947  		wantErr: EM(nil).withPos(`{`, "").withType(0, T[chan string]()),
   948  	}, {
   949  		name:         jsontest.Name("Maps/ValidKey/Int"),
   950  		in:           map[int64]string{math.MinInt64: "MinInt64", 0: "Zero", math.MaxInt64: "MaxInt64"},
   951  		canonicalize: true,
   952  		want:         `{"-9223372036854775808":"MinInt64","0":"Zero","9223372036854775807":"MaxInt64"}`,
   953  	}, {
   954  		name:         jsontest.Name("Maps/ValidKey/PointerInt"),
   955  		in:           map[*int64]string{addr(int64(math.MinInt64)): "MinInt64", addr(int64(0)): "Zero", addr(int64(math.MaxInt64)): "MaxInt64"},
   956  		canonicalize: true,
   957  		want:         `{"-9223372036854775808":"MinInt64","0":"Zero","9223372036854775807":"MaxInt64"}`,
   958  	}, {
   959  		name:         jsontest.Name("Maps/DuplicateName/PointerInt"),
   960  		in:           map[*int64]string{addr(int64(0)): "0", addr(int64(0)): "0"},
   961  		canonicalize: true,
   962  		want:         `{"0":"0"`,
   963  		wantErr:      newDuplicateNameError("", []byte(`"0"`), len64(`{"0":"0",`)),
   964  	}, {
   965  		name:         jsontest.Name("Maps/ValidKey/NamedInt"),
   966  		in:           map[namedInt64]string{math.MinInt64: "MinInt64", 0: "Zero", math.MaxInt64: "MaxInt64"},
   967  		canonicalize: true,
   968  		want:         `{"-9223372036854775808":"MinInt64","0":"Zero","9223372036854775807":"MaxInt64"}`,
   969  	}, {
   970  		name:         jsontest.Name("Maps/ValidKey/Uint"),
   971  		in:           map[uint64]string{0: "Zero", math.MaxUint64: "MaxUint64"},
   972  		canonicalize: true,
   973  		want:         `{"0":"Zero","18446744073709551615":"MaxUint64"}`,
   974  	}, {
   975  		name:         jsontest.Name("Maps/ValidKey/NamedUint"),
   976  		in:           map[namedUint64]string{0: "Zero", math.MaxUint64: "MaxUint64"},
   977  		canonicalize: true,
   978  		want:         `{"0":"Zero","18446744073709551615":"MaxUint64"}`,
   979  	}, {
   980  		name: jsontest.Name("Maps/ValidKey/Float"),
   981  		in:   map[float64]string{3.14159: "value"},
   982  		want: `{"3.14159":"value"}`,
   983  	}, {
   984  		name:    jsontest.Name("Maps/InvalidKey/Float/NaN"),
   985  		in:      map[float64]string{math.NaN(): "NaN", math.NaN(): "NaN"},
   986  		want:    `{`,
   987  		wantErr: EM(errors.New("unsupported value: NaN")).withPos(`{`, "").withType(0, float64Type),
   988  	}, {
   989  		name: jsontest.Name("Maps/ValidKey/Interface"),
   990  		in: map[any]any{
   991  			"key":               "key",
   992  			namedInt64(-64):     int32(-32),
   993  			namedUint64(+64):    uint32(+32),
   994  			namedFloat64(64.64): float32(32.32),
   995  		},
   996  		canonicalize: true,
   997  		want:         `{"-64":-32,"64":32,"64.64":32.32,"key":"key"}`,
   998  	}, {
   999  		name: jsontest.Name("Maps/DuplicateName/String/AllowInvalidUTF8+AllowDuplicateNames"),
  1000  		opts: []Options{jsontext.AllowInvalidUTF8(true), jsontext.AllowDuplicateNames(true)},
  1001  		in:   map[string]string{"\x80": "", "\x81": ""},
  1002  		want: `{"�":"","�":""}`,
  1003  	}, {
  1004  		name:    jsontest.Name("Maps/DuplicateName/String/AllowInvalidUTF8"),
  1005  		opts:    []Options{jsontext.AllowInvalidUTF8(true)},
  1006  		in:      map[string]string{"\x80": "", "\x81": ""},
  1007  		want:    `{"�":""`,
  1008  		wantErr: newDuplicateNameError("", []byte(`"�"`), len64(`{"�":"",`)),
  1009  	}, {
  1010  		name: jsontest.Name("Maps/DuplicateName/NoCaseString/AllowDuplicateNames"),
  1011  		opts: []Options{jsontext.AllowDuplicateNames(true)},
  1012  		in:   map[nocaseString]string{"hello": "", "HELLO": ""},
  1013  		want: `{"hello":"","hello":""}`,
  1014  	}, {
  1015  		name:    jsontest.Name("Maps/DuplicateName/NoCaseString"),
  1016  		in:      map[nocaseString]string{"hello": "", "HELLO": ""},
  1017  		want:    `{"hello":""`,
  1018  		wantErr: EM(newDuplicateNameError("", []byte(`"hello"`), len64(`{"hello":"",`))).withPos(`{"hello":"",`, "").withType(0, T[nocaseString]()),
  1019  	}, {
  1020  		name: jsontest.Name("Maps/DuplicateName/NaNs/Deterministic+AllowDuplicateNames"),
  1021  		opts: []Options{
  1022  			WithMarshalers(
  1023  				MarshalFunc(func(v float64) ([]byte, error) { return []byte(`"NaN"`), nil }),
  1024  			),
  1025  			Deterministic(true),
  1026  			jsontext.AllowDuplicateNames(true),
  1027  		},
  1028  		in:   map[float64]string{math.NaN(): "NaN", math.NaN(): "NaN"},
  1029  		want: `{"NaN":"NaN","NaN":"NaN"}`,
  1030  	}, {
  1031  		name: jsontest.Name("Maps/InvalidValue/Channel"),
  1032  		in: map[string]chan string{
  1033  			"key": nil,
  1034  		},
  1035  		want:    `{"key"`,
  1036  		wantErr: EM(nil).withPos(`{"key":`, "/key").withType(0, T[chan string]()),
  1037  	}, {
  1038  		name: jsontest.Name("Maps/String/Deterministic"),
  1039  		opts: []Options{Deterministic(true)},
  1040  		in:   map[string]int{"a": 0, "b": 1, "c": 2},
  1041  		want: `{"a":0,"b":1,"c":2}`,
  1042  	}, {
  1043  		name: jsontest.Name("Maps/String/Deterministic+AllowInvalidUTF8+RejectDuplicateNames"),
  1044  		opts: []Options{
  1045  			Deterministic(true),
  1046  			jsontext.AllowInvalidUTF8(true),
  1047  			jsontext.AllowDuplicateNames(false),
  1048  		},
  1049  		in:      map[string]int{"\xff": 0, "\xfe": 1},
  1050  		want:    `{"�":1`,
  1051  		wantErr: newDuplicateNameError("", []byte(`"�"`), len64(`{"�":1,`)),
  1052  	}, {
  1053  		name: jsontest.Name("Maps/String/Deterministic+AllowInvalidUTF8+AllowDuplicateNames"),
  1054  		opts: []Options{
  1055  			Deterministic(true),
  1056  			jsontext.AllowInvalidUTF8(true),
  1057  			jsontext.AllowDuplicateNames(true),
  1058  		},
  1059  		in:   map[string]int{"\xff": 0, "\xfe": 1},
  1060  		want: `{"�":1,"�":0}`,
  1061  	}, {
  1062  		name: jsontest.Name("Maps/String/Deterministic+MarshalFuncs"),
  1063  		opts: []Options{
  1064  			Deterministic(true),
  1065  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v string) error {
  1066  				if p := enc.StackPointer(); p != "/X" {
  1067  					return fmt.Errorf("invalid stack pointer: got %s, want /X", p)
  1068  				}
  1069  				switch v {
  1070  				case "a":
  1071  					return enc.WriteToken(jsontext.String("b"))
  1072  				case "b":
  1073  					return enc.WriteToken(jsontext.String("a"))
  1074  				default:
  1075  					return fmt.Errorf("invalid value: %q", v)
  1076  				}
  1077  			})),
  1078  		},
  1079  		in:   map[namedString]map[string]int{"X": {"a": -1, "b": 1}},
  1080  		want: `{"X":{"a":1,"b":-1}}`,
  1081  	}, {
  1082  		name: jsontest.Name("Maps/String/Deterministic+MarshalFuncs+RejectDuplicateNames"),
  1083  		opts: []Options{
  1084  			Deterministic(true),
  1085  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v string) error {
  1086  				if p := enc.StackPointer(); p != "/X" {
  1087  					return fmt.Errorf("invalid stack pointer: got %s, want /X", p)
  1088  				}
  1089  				switch v {
  1090  				case "a", "b":
  1091  					return enc.WriteToken(jsontext.String("x"))
  1092  				default:
  1093  					return fmt.Errorf("invalid value: %q", v)
  1094  				}
  1095  			})),
  1096  			jsontext.AllowDuplicateNames(false),
  1097  		},
  1098  		in:      map[namedString]map[string]int{"X": {"a": 1, "b": 1}},
  1099  		want:    `{"X":{"x":1`,
  1100  		wantErr: newDuplicateNameError("/X/x", nil, len64(`{"X":{"x":1,`)),
  1101  	}, {
  1102  		name: jsontest.Name("Maps/String/Deterministic+MarshalFuncs+AllowDuplicateNames"),
  1103  		opts: []Options{
  1104  			Deterministic(true),
  1105  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v string) error {
  1106  				if p := enc.StackPointer(); p != "/X" {
  1107  					return fmt.Errorf("invalid stack pointer: got %s, want /0", p)
  1108  				}
  1109  				switch v {
  1110  				case "a", "b":
  1111  					return enc.WriteToken(jsontext.String("x"))
  1112  				default:
  1113  					return fmt.Errorf("invalid value: %q", v)
  1114  				}
  1115  			})),
  1116  			jsontext.AllowDuplicateNames(true),
  1117  		},
  1118  		in: map[namedString]map[string]int{"X": {"a": 1, "b": 1}},
  1119  		// NOTE: Since the names are identical, the exact values may be
  1120  		// non-deterministic since sort cannot distinguish between members.
  1121  		want: `{"X":{"x":1,"x":1}}`,
  1122  	}, {
  1123  		name: jsontest.Name("Maps/RecursiveMap"),
  1124  		in: recursiveMap{
  1125  			"fizz": {
  1126  				"foo": {},
  1127  				"bar": nil,
  1128  			},
  1129  			"buzz": nil,
  1130  		},
  1131  		canonicalize: true,
  1132  		want:         `{"buzz":{},"fizz":{"bar":{},"foo":{}}}`,
  1133  	}, {
  1134  		name: jsontest.Name("Maps/CyclicMap"),
  1135  		in: func() recursiveMap {
  1136  			m := recursiveMap{"k": nil}
  1137  			m["k"] = m
  1138  			return m
  1139  		}(),
  1140  		want:    strings.Repeat(`{"k":`, startDetectingCyclesAfter) + `{"k"`,
  1141  		wantErr: EM(internal.ErrCycle).withPos(strings.Repeat(`{"k":`, startDetectingCyclesAfter+1), jsontext.Pointer(strings.Repeat("/k", startDetectingCyclesAfter+1))).withType(0, T[recursiveMap]()),
  1142  	}, {
  1143  		name: jsontest.Name("Maps/IgnoreInvalidFormat"),
  1144  		opts: []Options{invalidFormatOption},
  1145  		in:   map[string]string{},
  1146  		want: `{}`,
  1147  	}, {
  1148  		name: jsontest.Name("Structs/Empty"),
  1149  		in:   structEmpty{},
  1150  		want: `{}`,
  1151  	}, {
  1152  		name: jsontest.Name("Structs/UnexportedIgnored"),
  1153  		in:   structUnexportedIgnored{ignored: "ignored"},
  1154  		want: `{}`,
  1155  	}, {
  1156  		name: jsontest.Name("Structs/IgnoredUnexportedEmbedded"),
  1157  		in:   structIgnoredUnexportedEmbedded{namedString: "ignored"},
  1158  		want: `{}`,
  1159  	}, {
  1160  		name: jsontest.Name("Structs/NoCase"),
  1161  		in:   structNoCase{AaA: "AaA", AAa: "AAa", Aaa: "Aaa", AAA: "AAA", AA_A: "AA_A"},
  1162  		want: `{"Aaa":"Aaa","AA_A":"AA_A","AaA":"AaA","AAa":"AAa","AAA":"AAA"}`,
  1163  	}, {
  1164  		name: jsontest.Name("Structs/NoCase/MatchCaseInsensitiveNames"),
  1165  		opts: []Options{MatchCaseInsensitiveNames(true)},
  1166  		in:   structNoCase{AaA: "AaA", AAa: "AAa", Aaa: "Aaa", AAA: "AAA", AA_A: "AA_A"},
  1167  		want: `{"Aaa":"Aaa","AA_A":"AA_A","AaA":"AaA","AAa":"AAa","AAA":"AAA"}`,
  1168  	}, {
  1169  		name: jsontest.Name("Structs/NoCase/MatchCaseInsensitiveNames+MatchCaseSensitiveDelimiter"),
  1170  		opts: []Options{MatchCaseInsensitiveNames(true), jsonflags.MatchCaseSensitiveDelimiter | 1},
  1171  		in:   structNoCase{AaA: "AaA", AAa: "AAa", Aaa: "Aaa", AAA: "AAA", AA_A: "AA_A"},
  1172  		want: `{"Aaa":"Aaa","AA_A":"AA_A","AaA":"AaA","AAa":"AAa","AAA":"AAA"}`,
  1173  	}, {
  1174  		name: jsontest.Name("Structs/Normal"),
  1175  		opts: []Options{jsontext.Multiline(true)},
  1176  		in: structAll{
  1177  			Bool:   true,
  1178  			String: "hello",
  1179  			Bytes:  []byte{1, 2, 3},
  1180  			Int:    -64,
  1181  			Uint:   +64,
  1182  			Float:  3.14159,
  1183  			Map:    map[string]string{"key": "value"},
  1184  			StructScalars: structScalars{
  1185  				Bool:   true,
  1186  				String: "hello",
  1187  				Bytes:  []byte{1, 2, 3},
  1188  				Int:    -64,
  1189  				Uint:   +64,
  1190  				Float:  3.14159,
  1191  			},
  1192  			StructMaps: structMaps{
  1193  				MapBool:   map[string]bool{"": true},
  1194  				MapString: map[string]string{"": "hello"},
  1195  				MapBytes:  map[string][]byte{"": {1, 2, 3}},
  1196  				MapInt:    map[string]int64{"": -64},
  1197  				MapUint:   map[string]uint64{"": +64},
  1198  				MapFloat:  map[string]float64{"": 3.14159},
  1199  			},
  1200  			StructSlices: structSlices{
  1201  				SliceBool:   []bool{true},
  1202  				SliceString: []string{"hello"},
  1203  				SliceBytes:  [][]byte{{1, 2, 3}},
  1204  				SliceInt:    []int64{-64},
  1205  				SliceUint:   []uint64{+64},
  1206  				SliceFloat:  []float64{3.14159},
  1207  			},
  1208  			Slice:     []string{"fizz", "buzz"},
  1209  			Array:     [1]string{"goodbye"},
  1210  			Pointer:   new(structAll),
  1211  			Interface: (*structAll)(nil),
  1212  		},
  1213  		want: `{
  1214  	"Bool": true,
  1215  	"String": "hello",
  1216  	"Bytes": "AQID",
  1217  	"Int": -64,
  1218  	"Uint": 64,
  1219  	"Float": 3.14159,
  1220  	"Map": {
  1221  		"key": "value"
  1222  	},
  1223  	"StructScalars": {
  1224  		"Bool": true,
  1225  		"String": "hello",
  1226  		"Bytes": "AQID",
  1227  		"Int": -64,
  1228  		"Uint": 64,
  1229  		"Float": 3.14159
  1230  	},
  1231  	"StructMaps": {
  1232  		"MapBool": {
  1233  			"": true
  1234  		},
  1235  		"MapString": {
  1236  			"": "hello"
  1237  		},
  1238  		"MapBytes": {
  1239  			"": "AQID"
  1240  		},
  1241  		"MapInt": {
  1242  			"": -64
  1243  		},
  1244  		"MapUint": {
  1245  			"": 64
  1246  		},
  1247  		"MapFloat": {
  1248  			"": 3.14159
  1249  		}
  1250  	},
  1251  	"StructSlices": {
  1252  		"SliceBool": [
  1253  			true
  1254  		],
  1255  		"SliceString": [
  1256  			"hello"
  1257  		],
  1258  		"SliceBytes": [
  1259  			"AQID"
  1260  		],
  1261  		"SliceInt": [
  1262  			-64
  1263  		],
  1264  		"SliceUint": [
  1265  			64
  1266  		],
  1267  		"SliceFloat": [
  1268  			3.14159
  1269  		]
  1270  	},
  1271  	"Slice": [
  1272  		"fizz",
  1273  		"buzz"
  1274  	],
  1275  	"Array": [
  1276  		"goodbye"
  1277  	],
  1278  	"Pointer": {
  1279  		"Bool": false,
  1280  		"String": "",
  1281  		"Bytes": "",
  1282  		"Int": 0,
  1283  		"Uint": 0,
  1284  		"Float": 0,
  1285  		"Map": {},
  1286  		"StructScalars": {
  1287  			"Bool": false,
  1288  			"String": "",
  1289  			"Bytes": "",
  1290  			"Int": 0,
  1291  			"Uint": 0,
  1292  			"Float": 0
  1293  		},
  1294  		"StructMaps": {
  1295  			"MapBool": {},
  1296  			"MapString": {},
  1297  			"MapBytes": {},
  1298  			"MapInt": {},
  1299  			"MapUint": {},
  1300  			"MapFloat": {}
  1301  		},
  1302  		"StructSlices": {
  1303  			"SliceBool": [],
  1304  			"SliceString": [],
  1305  			"SliceBytes": [],
  1306  			"SliceInt": [],
  1307  			"SliceUint": [],
  1308  			"SliceFloat": []
  1309  		},
  1310  		"Slice": [],
  1311  		"Array": [
  1312  			""
  1313  		],
  1314  		"Pointer": null,
  1315  		"Interface": null
  1316  	},
  1317  	"Interface": null
  1318  }`,
  1319  	}, {
  1320  		name: jsontest.Name("Structs/SpaceAfterColonAndComma"),
  1321  		opts: []Options{jsontext.SpaceAfterColon(true), jsontext.SpaceAfterComma(true)},
  1322  		in:   structOmitZeroAll{Int: 1, Uint: 1},
  1323  		want: `{"Int": 1, "Uint": 1}`,
  1324  	}, {
  1325  		name: jsontest.Name("Structs/SpaceAfterColon"),
  1326  		opts: []Options{jsontext.SpaceAfterColon(true)},
  1327  		in:   structOmitZeroAll{Int: 1, Uint: 1},
  1328  		want: `{"Int": 1,"Uint": 1}`,
  1329  	}, {
  1330  		name: jsontest.Name("Structs/SpaceAfterComma"),
  1331  		opts: []Options{jsontext.SpaceAfterComma(true)},
  1332  		in:   structOmitZeroAll{Int: 1, Uint: 1, Slice: []string{"a", "b"}},
  1333  		want: `{"Int":1, "Uint":1, "Slice":["a", "b"]}`,
  1334  	}, {
  1335  		name: jsontest.Name("Structs/Stringified"),
  1336  		opts: []Options{jsontext.Multiline(true)},
  1337  		in: structStringified{
  1338  			Int:          -64,
  1339  			Uint:         +64,
  1340  			Float:        3.14159,
  1341  			PointerInt:   new(int64(-64)),
  1342  			PointerUint:  new(uint64(+64)),
  1343  			PointerFloat: new(float64(3.14159)),
  1344  		},
  1345  		want: `{
  1346  	"Int": "-64",
  1347  	"Uint": "64",
  1348  	"Float": "3.14159",
  1349  	"PointerInt": "-64",
  1350  	"PointerUint": "64",
  1351  	"PointerFloat": "3.14159"
  1352  }`,
  1353  	}, {
  1354  		name: jsontest.Name("Structs/LegacyStringified"),
  1355  		opts: []Options{jsontext.Multiline(true), jsonflags.StringifyWithLegacySemantics | 1},
  1356  		in: structStringifiedLegacy{
  1357  			Bool:          true,
  1358  			String:        "hello",
  1359  			Int:           -64,
  1360  			Uint:          +64,
  1361  			Float:         3.14159,
  1362  			PointerBool:   new(true),
  1363  			PointerString: new("hello"),
  1364  			PointerInt:    new(int64(-64)),
  1365  			PointerUint:   new(uint64(+64)),
  1366  			PointerFloat:  new(float64(3.14159)),
  1367  		},
  1368  		want: `{
  1369  	"Bool": "true",
  1370  	"String": "\"hello\"",
  1371  	"Int": "-64",
  1372  	"Uint": "64",
  1373  	"Float": "3.14159",
  1374  	"PointerBool": "true",
  1375  	"PointerString": "\"hello\"",
  1376  	"PointerInt": "-64",
  1377  	"PointerUint": "64",
  1378  	"PointerFloat": "3.14159"
  1379  }`,
  1380  	}, {
  1381  		name:    jsontest.Name("Structs/Stringified/Invalid/Bool"),
  1382  		in:      structStringifiedBool{},
  1383  		want:    `{"Bool"`,
  1384  		wantErr: EM(errInvalidStringTag).withPos(`{"Bool":`, "/Bool").withType(0, boolType),
  1385  	}, {
  1386  		name: jsontest.Name("Structs/Stringified/Ignored/Bool"),
  1387  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  1388  		in:   structStringifiedBool{},
  1389  		want: `{"Bool":false}`,
  1390  	}, {
  1391  		name:    jsontest.Name("Structs/Stringified/Invalid/String"),
  1392  		in:      structStringifiedString{},
  1393  		want:    `{"String"`,
  1394  		wantErr: EM(errInvalidStringTag).withPos(`{"String":`, "/String").withType(0, stringType),
  1395  	}, {
  1396  		name: jsontest.Name("Structs/Stringified/Ignored/String"),
  1397  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  1398  		in:   structStringifiedString{},
  1399  		want: `{"String":""}`,
  1400  	}, {
  1401  		name:    jsontest.Name("Structs/Stringified/Invalid/Bytes"),
  1402  		in:      structStringifiedBytes{},
  1403  		want:    `{"Bytes"`,
  1404  		wantErr: EM(errInvalidStringTag).withPos(`{"Bytes":`, "/Bytes").withType(0, bytesType),
  1405  	}, {
  1406  		name: jsontest.Name("Structs/Stringified/Ignored/Bytes"),
  1407  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  1408  		in:   structStringifiedBytes{},
  1409  		want: `{"Bytes":""}`,
  1410  	}, {
  1411  		name:    jsontest.Name("Structs/Stringified/Invalid/Map"),
  1412  		in:      structStringifiedMap{},
  1413  		want:    `{"Map"`,
  1414  		wantErr: EM(errInvalidStringTag).withPos(`{"Map":`, "/Map").withType(0, reflect.TypeFor[map[string]string]()),
  1415  	}, {
  1416  		name: jsontest.Name("Structs/Stringified/Ignored/Map"),
  1417  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  1418  		in:   structStringifiedMap{},
  1419  		want: `{"Map":{}}`,
  1420  	}, {
  1421  		name:    jsontest.Name("Structs/Stringified/Invalid/Slice"),
  1422  		in:      structStringifiedSlice{},
  1423  		want:    `{"Slice"`,
  1424  		wantErr: EM(errInvalidStringTag).withPos(`{"Slice":`, "/Slice").withType(0, reflect.TypeFor[[]string]()),
  1425  	}, {
  1426  		name: jsontest.Name("Structs/Stringified/Ignored/Slice"),
  1427  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  1428  		in:   structStringifiedSlice{},
  1429  		want: `{"Slice":[]}`,
  1430  	}, {
  1431  		name:    jsontest.Name("Structs/Stringified/Invalid/Array"),
  1432  		in:      structStringifiedArray{},
  1433  		want:    `{"Array"`,
  1434  		wantErr: EM(errInvalidStringTag).withPos(`{"Array":`, "/Array").withType(0, reflect.TypeFor[[1]string]()),
  1435  	}, {
  1436  		name: jsontest.Name("Structs/Stringified/Ignored/Array"),
  1437  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  1438  		in:   structStringifiedArray{},
  1439  		want: `{"Array":[""]}`,
  1440  	}, {
  1441  		name:    jsontest.Name("Structs/Stringified/Invalid/Struct"),
  1442  		in:      structStringifiedStruct{},
  1443  		want:    `{"Struct"`,
  1444  		wantErr: EM(errInvalidStringTag).withPos(`{"Struct":`, "/Struct").withType(0, reflect.TypeFor[structAll]()),
  1445  	}, {
  1446  		name: jsontest.Name("Structs/Stringified/Ignored/Struct"),
  1447  		opts: []Options{jsontext.Multiline(true), jsonflags.ReportErrorsWithLegacySemantics | 1},
  1448  		in:   structStringifiedStruct{},
  1449  		want: `{
  1450  	"Struct": {
  1451  		"Bool": false,
  1452  		"String": "",
  1453  		"Bytes": "",
  1454  		"Int": 0,
  1455  		"Uint": 0,
  1456  		"Float": 0,
  1457  		"Map": {},
  1458  		"StructScalars": {
  1459  			"Bool": false,
  1460  			"String": "",
  1461  			"Bytes": "",
  1462  			"Int": 0,
  1463  			"Uint": 0,
  1464  			"Float": 0
  1465  		},
  1466  		"StructMaps": {
  1467  			"MapBool": {},
  1468  			"MapString": {},
  1469  			"MapBytes": {},
  1470  			"MapInt": {},
  1471  			"MapUint": {},
  1472  			"MapFloat": {}
  1473  		},
  1474  		"StructSlices": {
  1475  			"SliceBool": [],
  1476  			"SliceString": [],
  1477  			"SliceBytes": [],
  1478  			"SliceInt": [],
  1479  			"SliceUint": [],
  1480  			"SliceFloat": []
  1481  		},
  1482  		"Slice": [],
  1483  		"Array": [
  1484  			""
  1485  		],
  1486  		"Pointer": null,
  1487  		"Interface": null
  1488  	}
  1489  }`,
  1490  	}, {
  1491  		name: jsontest.Name("Structs/Stringified/Invalid/Pointer"),
  1492  		in:   structStringifiedPointer{},
  1493  		want: `{"Pointer":null}`,
  1494  	}, {
  1495  		name: jsontest.Name("Structs/Stringified/Ignored/Pointer"),
  1496  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  1497  		in:   structStringifiedPointer{},
  1498  		want: `{"Pointer":null}`,
  1499  	}, {
  1500  		name: jsontest.Name("Structs/Stringified/PointerPointerInt"),
  1501  		in:   structStringifiedPointerPointerInt{Pointer: new(new(5))},
  1502  		want: `{"Pointer":"5"}`,
  1503  	}, {
  1504  		name:    jsontest.Name("Structs/Stringified/Invalid/Interface"),
  1505  		in:      structStringifiedInterface{Interface: 1000},
  1506  		want:    `{"Interface"`,
  1507  		wantErr: EM(errInvalidStringTag).withPos(`{"Interface":`, "/Interface").withType(0, anyType),
  1508  	}, {
  1509  		name: jsontest.Name("Structs/Stringified/Ignored/Interface"),
  1510  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  1511  		in:   structStringifiedInterface{Interface: 1000},
  1512  		want: `{"Interface":"1000"}`,
  1513  	}, {
  1514  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Bytes"),
  1515  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  1516  		want:    `{"Bytes"`,
  1517  		wantErr: EM(errInvalidStringTag).withPos(`{"Bytes":`, "/Bytes").withType(0, bytesType),
  1518  		in:      structStringifiedBytes{},
  1519  	}, {
  1520  		name: jsontest.Name("Structs/LegacyStringified/Ignored/Bytes"),
  1521  		opts: []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  1522  		in:   structStringifiedBytes{},
  1523  		want: `{"Bytes":""}`,
  1524  	}, {
  1525  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Map"),
  1526  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  1527  		in:      structStringifiedMap{},
  1528  		want:    `{"Map"`,
  1529  		wantErr: EM(errInvalidStringTag).withPos(`{"Map":`, "/Map").withType(0, reflect.TypeFor[map[string]string]()),
  1530  	}, {
  1531  		name: jsontest.Name("Structs/LegacyStringified/Ignored/Map"),
  1532  		opts: []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  1533  		in:   structStringifiedMap{},
  1534  		want: `{"Map":{}}`,
  1535  	}, {
  1536  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Slice"),
  1537  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  1538  		in:      structStringifiedSlice{},
  1539  		want:    `{"Slice"`,
  1540  		wantErr: EM(errInvalidStringTag).withPos(`{"Slice":`, "/Slice").withType(0, reflect.TypeFor[[]string]()),
  1541  	}, {
  1542  		name: jsontest.Name("Structs/LegacyStringified/Ignored/Slice"),
  1543  		opts: []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  1544  		in:   structStringifiedSlice{},
  1545  		want: `{"Slice":[]}`,
  1546  	}, {
  1547  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Array"),
  1548  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  1549  		in:      structStringifiedArray{},
  1550  		want:    `{"Array"`,
  1551  		wantErr: EM(errInvalidStringTag).withPos(`{"Array":`, "/Array").withType(0, reflect.TypeFor[[1]string]()),
  1552  	}, {
  1553  		name: jsontest.Name("Structs/LegacyStringified/Ignored/Array"),
  1554  		opts: []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  1555  		in:   structStringifiedArray{},
  1556  		want: `{"Array":[""]}`,
  1557  	}, {
  1558  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Struct"),
  1559  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  1560  		in:      structStringifiedStruct{},
  1561  		want:    `{"Struct"`,
  1562  		wantErr: EM(errInvalidStringTag).withPos(`{"Struct":`, "/Struct").withType(0, reflect.TypeFor[structAll]()),
  1563  	}, {
  1564  		name: jsontest.Name("Structs/LegacyStringified/Ignored/Struct"),
  1565  		opts: []Options{jsontext.Multiline(true), jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  1566  		in:   structStringifiedStruct{},
  1567  		want: `{
  1568  	"Struct": {
  1569  		"Bool": false,
  1570  		"String": "",
  1571  		"Bytes": "",
  1572  		"Int": 0,
  1573  		"Uint": 0,
  1574  		"Float": 0,
  1575  		"Map": {},
  1576  		"StructScalars": {
  1577  			"Bool": false,
  1578  			"String": "",
  1579  			"Bytes": "",
  1580  			"Int": 0,
  1581  			"Uint": 0,
  1582  			"Float": 0
  1583  		},
  1584  		"StructMaps": {
  1585  			"MapBool": {},
  1586  			"MapString": {},
  1587  			"MapBytes": {},
  1588  			"MapInt": {},
  1589  			"MapUint": {},
  1590  			"MapFloat": {}
  1591  		},
  1592  		"StructSlices": {
  1593  			"SliceBool": [],
  1594  			"SliceString": [],
  1595  			"SliceBytes": [],
  1596  			"SliceInt": [],
  1597  			"SliceUint": [],
  1598  			"SliceFloat": []
  1599  		},
  1600  		"Slice": [],
  1601  		"Array": [
  1602  			""
  1603  		],
  1604  		"Pointer": null,
  1605  		"Interface": null
  1606  	}
  1607  }`,
  1608  	}, {
  1609  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Pointer"),
  1610  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  1611  		in:      structStringifiedPointer{Pointer: new(structAll)},
  1612  		want:    `{"Pointer"`,
  1613  		wantErr: EM(errInvalidStringTag).withPos(`{"Pointer":`, "/Pointer").withType(0, reflect.TypeFor[structAll]()),
  1614  	}, {
  1615  		name: jsontest.Name("Structs/LegacyStringified/Ignored/Pointer"),
  1616  		opts: []Options{jsontext.Multiline(true), jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  1617  		in:   structStringifiedPointer{Pointer: new(structAll)},
  1618  		want: `{
  1619  	"Pointer": {
  1620  		"Bool": false,
  1621  		"String": "",
  1622  		"Bytes": "",
  1623  		"Int": 0,
  1624  		"Uint": 0,
  1625  		"Float": 0,
  1626  		"Map": {},
  1627  		"StructScalars": {
  1628  			"Bool": false,
  1629  			"String": "",
  1630  			"Bytes": "",
  1631  			"Int": 0,
  1632  			"Uint": 0,
  1633  			"Float": 0
  1634  		},
  1635  		"StructMaps": {
  1636  			"MapBool": {},
  1637  			"MapString": {},
  1638  			"MapBytes": {},
  1639  			"MapInt": {},
  1640  			"MapUint": {},
  1641  			"MapFloat": {}
  1642  		},
  1643  		"StructSlices": {
  1644  			"SliceBool": [],
  1645  			"SliceString": [],
  1646  			"SliceBytes": [],
  1647  			"SliceInt": [],
  1648  			"SliceUint": [],
  1649  			"SliceFloat": []
  1650  		},
  1651  		"Slice": [],
  1652  		"Array": [
  1653  			""
  1654  		],
  1655  		"Pointer": null,
  1656  		"Interface": null
  1657  	}
  1658  }`,
  1659  	}, {
  1660  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/PointerPointerInt"),
  1661  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  1662  		in:      structStringifiedPointerPointerInt{Pointer: new(new(5))},
  1663  		want:    `{"Pointer"`,
  1664  		wantErr: EM(errInvalidStringTag).withPos(`{"Pointer":`, "/Pointer").withType(0, reflect.TypeFor[**int]()),
  1665  	}, {
  1666  		name: jsontest.Name("Structs/LegacyStringified/Ignored/PointerPointerInt"),
  1667  		opts: []Options{jsonflags.StringifyWithLegacySemantics | jsonflags.ReportErrorsWithLegacySemantics | 1},
  1668  		in:   structStringifiedPointerPointerInt{Pointer: new(new(5))},
  1669  		want: `{"Pointer":5}`,
  1670  	}, {
  1671  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Interface"),
  1672  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  1673  		in:      structStringifiedInterface{},
  1674  		want:    `{"Interface"`,
  1675  		wantErr: EM(errInvalidStringTag).withPos(`{"Interface":`, "/Interface").withType(0, anyType),
  1676  	}, {
  1677  		name: jsontest.Name("Structs/LegacyStringified/Ignored/Interface"),
  1678  		opts: []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  1679  		in:   structStringifiedInterface{Interface: 1000},
  1680  		want: `{"Interface":1000}`,
  1681  	}, {
  1682  		name: jsontest.Name("Structs/OmitZero/Zero"),
  1683  		in:   structOmitZeroAll{},
  1684  		want: `{}`,
  1685  	}, {
  1686  		name: jsontest.Name("Structs/OmitZeroOption/Zero"),
  1687  		opts: []Options{OmitZeroStructFields(true)},
  1688  		in:   structAll{},
  1689  		want: `{}`,
  1690  	}, {
  1691  		name: jsontest.Name("Structs/OmitZero/NonZero"),
  1692  		opts: []Options{jsontext.Multiline(true)},
  1693  		in: structOmitZeroAll{
  1694  			Bool:          true,                                   // not omitted since true is non-zero
  1695  			String:        " ",                                    // not omitted since non-empty string is non-zero
  1696  			Bytes:         []byte{},                               // not omitted since allocated slice is non-zero
  1697  			Int:           1,                                      // not omitted since 1 is non-zero
  1698  			Uint:          1,                                      // not omitted since 1 is non-zero
  1699  			Float:         math.SmallestNonzeroFloat64,            // not omitted since still slightly above zero
  1700  			Map:           map[string]string{},                    // not omitted since allocated map is non-zero
  1701  			StructScalars: structScalars{unexported: true},        // not omitted since unexported is non-zero
  1702  			StructSlices:  structSlices{Ignored: true},            // not omitted since Ignored is non-zero
  1703  			StructMaps:    structMaps{MapBool: map[string]bool{}}, // not omitted since MapBool is non-zero
  1704  			Slice:         []string{},                             // not omitted since allocated slice is non-zero
  1705  			Array:         [1]string{" "},                         // not omitted since single array element is non-zero
  1706  			Pointer:       new(structOmitZeroAll),                 // not omitted since pointer is non-zero (even if all fields of the struct value are zero)
  1707  			Interface:     (*structOmitZeroAll)(nil),              // not omitted since interface value is non-zero (even if interface value is a nil pointer)
  1708  		},
  1709  		want: `{
  1710  	"Bool": true,
  1711  	"String": " ",
  1712  	"Bytes": "",
  1713  	"Int": 1,
  1714  	"Uint": 1,
  1715  	"Float": 5e-324,
  1716  	"Map": {},
  1717  	"StructScalars": {
  1718  		"Bool": false,
  1719  		"String": "",
  1720  		"Bytes": "",
  1721  		"Int": 0,
  1722  		"Uint": 0,
  1723  		"Float": 0
  1724  	},
  1725  	"StructMaps": {
  1726  		"MapBool": {},
  1727  		"MapString": {},
  1728  		"MapBytes": {},
  1729  		"MapInt": {},
  1730  		"MapUint": {},
  1731  		"MapFloat": {}
  1732  	},
  1733  	"StructSlices": {
  1734  		"SliceBool": [],
  1735  		"SliceString": [],
  1736  		"SliceBytes": [],
  1737  		"SliceInt": [],
  1738  		"SliceUint": [],
  1739  		"SliceFloat": []
  1740  	},
  1741  	"Slice": [],
  1742  	"Array": [
  1743  		" "
  1744  	],
  1745  	"Pointer": {},
  1746  	"Interface": null
  1747  }`,
  1748  	}, {
  1749  		name: jsontest.Name("Structs/OmitZeroOption/NonZero"),
  1750  		opts: []Options{OmitZeroStructFields(true), jsontext.Multiline(true)},
  1751  		in: structAll{
  1752  			Bool:          true,
  1753  			String:        " ",
  1754  			Bytes:         []byte{},
  1755  			Int:           1,
  1756  			Uint:          1,
  1757  			Float:         math.SmallestNonzeroFloat64,
  1758  			Map:           map[string]string{},
  1759  			StructScalars: structScalars{unexported: true},
  1760  			StructSlices:  structSlices{Ignored: true},
  1761  			StructMaps:    structMaps{MapBool: map[string]bool{}},
  1762  			Slice:         []string{},
  1763  			Array:         [1]string{" "},
  1764  			Pointer:       new(structAll),
  1765  			Interface:     (*structAll)(nil),
  1766  		},
  1767  		want: `{
  1768  	"Bool": true,
  1769  	"String": " ",
  1770  	"Bytes": "",
  1771  	"Int": 1,
  1772  	"Uint": 1,
  1773  	"Float": 5e-324,
  1774  	"Map": {},
  1775  	"StructScalars": {},
  1776  	"StructMaps": {
  1777  		"MapBool": {}
  1778  	},
  1779  	"StructSlices": {},
  1780  	"Slice": [],
  1781  	"Array": [
  1782  		" "
  1783  	],
  1784  	"Pointer": {},
  1785  	"Interface": null
  1786  }`,
  1787  	}, {
  1788  		name: jsontest.Name("Structs/OmitZeroMethod/Zero"),
  1789  		in:   structOmitZeroMethodAll{},
  1790  		want: `{"ValueNeverZero":"","PointerNeverZero":""}`,
  1791  	}, {
  1792  		name: jsontest.Name("Structs/OmitZeroMethod/NonZero"),
  1793  		opts: []Options{jsontext.Multiline(true)},
  1794  		in: structOmitZeroMethodAll{
  1795  			ValueAlwaysZero:                 valueAlwaysZero("nonzero"),
  1796  			ValueNeverZero:                  valueNeverZero("nonzero"),
  1797  			PointerAlwaysZero:               pointerAlwaysZero("nonzero"),
  1798  			PointerNeverZero:                pointerNeverZero("nonzero"),
  1799  			PointerValueAlwaysZero:          addr(valueAlwaysZero("nonzero")),
  1800  			PointerValueNeverZero:           addr(valueNeverZero("nonzero")),
  1801  			PointerPointerAlwaysZero:        addr(pointerAlwaysZero("nonzero")),
  1802  			PointerPointerNeverZero:         addr(pointerNeverZero("nonzero")),
  1803  			PointerPointerValueAlwaysZero:   addr(addr(valueAlwaysZero("nonzero"))), // marshaled since **valueAlwaysZero does not implement IsZero
  1804  			PointerPointerValueNeverZero:    addr(addr(valueNeverZero("nonzero"))),
  1805  			PointerPointerPointerAlwaysZero: addr(addr(pointerAlwaysZero("nonzero"))), // marshaled since **pointerAlwaysZero does not implement IsZero
  1806  			PointerPointerPointerNeverZero:  addr(addr(pointerNeverZero("nonzero"))),
  1807  		},
  1808  		want: `{
  1809  	"ValueNeverZero": "nonzero",
  1810  	"PointerNeverZero": "nonzero",
  1811  	"PointerValueNeverZero": "nonzero",
  1812  	"PointerPointerNeverZero": "nonzero",
  1813  	"PointerPointerValueAlwaysZero": "nonzero",
  1814  	"PointerPointerValueNeverZero": "nonzero",
  1815  	"PointerPointerPointerAlwaysZero": "nonzero",
  1816  	"PointerPointerPointerNeverZero": "nonzero"
  1817  }`,
  1818  	}, {
  1819  		name: jsontest.Name("Structs/OmitZeroMethod/Interface/Zero"),
  1820  		opts: []Options{jsontext.Multiline(true)},
  1821  		in:   structOmitZeroMethodInterfaceAll{},
  1822  		want: `{}`,
  1823  	}, {
  1824  		name: jsontest.Name("Structs/OmitZeroMethod/Interface/PartialZero"),
  1825  		opts: []Options{jsontext.Multiline(true)},
  1826  		in: structOmitZeroMethodInterfaceAll{
  1827  			ValueAlwaysZero:          valueAlwaysZero(""),
  1828  			ValueNeverZero:           valueNeverZero(""),
  1829  			PointerValueAlwaysZero:   (*valueAlwaysZero)(nil),
  1830  			PointerValueNeverZero:    (*valueNeverZero)(nil), // nil pointer, so method not called
  1831  			PointerPointerAlwaysZero: (*pointerAlwaysZero)(nil),
  1832  			PointerPointerNeverZero:  (*pointerNeverZero)(nil), // nil pointer, so method not called
  1833  		},
  1834  		want: `{
  1835  	"ValueNeverZero": ""
  1836  }`,
  1837  	}, {
  1838  		name: jsontest.Name("Structs/OmitZeroMethod/Interface/NonZero"),
  1839  		opts: []Options{jsontext.Multiline(true)},
  1840  		in: structOmitZeroMethodInterfaceAll{
  1841  			ValueAlwaysZero:          valueAlwaysZero("nonzero"),
  1842  			ValueNeverZero:           valueNeverZero("nonzero"),
  1843  			PointerValueAlwaysZero:   addr(valueAlwaysZero("nonzero")),
  1844  			PointerValueNeverZero:    addr(valueNeverZero("nonzero")),
  1845  			PointerPointerAlwaysZero: addr(pointerAlwaysZero("nonzero")),
  1846  			PointerPointerNeverZero:  addr(pointerNeverZero("nonzero")),
  1847  		},
  1848  		want: `{
  1849  	"ValueNeverZero": "nonzero",
  1850  	"PointerValueNeverZero": "nonzero",
  1851  	"PointerPointerNeverZero": "nonzero"
  1852  }`,
  1853  	}, {
  1854  		name: jsontest.Name("Structs/OmitEmpty/Zero"),
  1855  		opts: []Options{jsontext.Multiline(true)},
  1856  		in:   structOmitEmptyAll{},
  1857  		want: `{
  1858  	"Bool": false,
  1859  	"StringNonEmpty": "value",
  1860  	"BytesNonEmpty": [
  1861  		"value"
  1862  	],
  1863  	"Float": 0,
  1864  	"MapNonEmpty": {
  1865  		"key": "value"
  1866  	},
  1867  	"SliceNonEmpty": [
  1868  		"value"
  1869  	]
  1870  }`,
  1871  	}, {
  1872  		name: jsontest.Name("Structs/OmitEmpty/EmptyNonZero"),
  1873  		opts: []Options{jsontext.Multiline(true)},
  1874  		in: structOmitEmptyAll{
  1875  			String:                string(""),
  1876  			StringEmpty:           stringMarshalEmpty(""),
  1877  			StringNonEmpty:        stringMarshalNonEmpty(""),
  1878  			PointerString:         addr(string("")),
  1879  			PointerStringEmpty:    addr(stringMarshalEmpty("")),
  1880  			PointerStringNonEmpty: addr(stringMarshalNonEmpty("")),
  1881  			Bytes:                 []byte(""),
  1882  			BytesEmpty:            bytesMarshalEmpty([]byte("")),
  1883  			BytesNonEmpty:         bytesMarshalNonEmpty([]byte("")),
  1884  			PointerBytes:          addr([]byte("")),
  1885  			PointerBytesEmpty:     addr(bytesMarshalEmpty([]byte(""))),
  1886  			PointerBytesNonEmpty:  addr(bytesMarshalNonEmpty([]byte(""))),
  1887  			Map:                   map[string]string{},
  1888  			MapEmpty:              mapMarshalEmpty{},
  1889  			MapNonEmpty:           mapMarshalNonEmpty{},
  1890  			PointerMap:            addr(map[string]string{}),
  1891  			PointerMapEmpty:       addr(mapMarshalEmpty{}),
  1892  			PointerMapNonEmpty:    addr(mapMarshalNonEmpty{}),
  1893  			Slice:                 []string{},
  1894  			SliceEmpty:            sliceMarshalEmpty{},
  1895  			SliceNonEmpty:         sliceMarshalNonEmpty{},
  1896  			PointerSlice:          addr([]string{}),
  1897  			PointerSliceEmpty:     addr(sliceMarshalEmpty{}),
  1898  			PointerSliceNonEmpty:  addr(sliceMarshalNonEmpty{}),
  1899  			Pointer:               &structOmitZeroEmptyAll{},
  1900  			Interface:             []string{},
  1901  		},
  1902  		want: `{
  1903  	"Bool": false,
  1904  	"StringNonEmpty": "value",
  1905  	"PointerStringNonEmpty": "value",
  1906  	"BytesNonEmpty": [
  1907  		"value"
  1908  	],
  1909  	"PointerBytesNonEmpty": [
  1910  		"value"
  1911  	],
  1912  	"Float": 0,
  1913  	"MapNonEmpty": {
  1914  		"key": "value"
  1915  	},
  1916  	"PointerMapNonEmpty": {
  1917  		"key": "value"
  1918  	},
  1919  	"SliceNonEmpty": [
  1920  		"value"
  1921  	],
  1922  	"PointerSliceNonEmpty": [
  1923  		"value"
  1924  	]
  1925  }`,
  1926  	}, {
  1927  		name: jsontest.Name("Structs/OmitEmpty/NonEmpty"),
  1928  		opts: []Options{jsontext.Multiline(true)},
  1929  		in: structOmitEmptyAll{
  1930  			Bool:                  true,
  1931  			PointerBool:           addr(true),
  1932  			String:                string("value"),
  1933  			StringEmpty:           stringMarshalEmpty("value"),
  1934  			StringNonEmpty:        stringMarshalNonEmpty("value"),
  1935  			PointerString:         addr(string("value")),
  1936  			PointerStringEmpty:    addr(stringMarshalEmpty("value")),
  1937  			PointerStringNonEmpty: addr(stringMarshalNonEmpty("value")),
  1938  			Bytes:                 []byte("value"),
  1939  			BytesEmpty:            bytesMarshalEmpty([]byte("value")),
  1940  			BytesNonEmpty:         bytesMarshalNonEmpty([]byte("value")),
  1941  			PointerBytes:          addr([]byte("value")),
  1942  			PointerBytesEmpty:     addr(bytesMarshalEmpty([]byte("value"))),
  1943  			PointerBytesNonEmpty:  addr(bytesMarshalNonEmpty([]byte("value"))),
  1944  			Float:                 math.Copysign(0, -1),
  1945  			PointerFloat:          addr(math.Copysign(0, -1)),
  1946  			Map:                   map[string]string{"": ""},
  1947  			MapEmpty:              mapMarshalEmpty{"key": "value"},
  1948  			MapNonEmpty:           mapMarshalNonEmpty{"key": "value"},
  1949  			PointerMap:            addr(map[string]string{"": ""}),
  1950  			PointerMapEmpty:       addr(mapMarshalEmpty{"key": "value"}),
  1951  			PointerMapNonEmpty:    addr(mapMarshalNonEmpty{"key": "value"}),
  1952  			Slice:                 []string{""},
  1953  			SliceEmpty:            sliceMarshalEmpty{"value"},
  1954  			SliceNonEmpty:         sliceMarshalNonEmpty{"value"},
  1955  			PointerSlice:          addr([]string{""}),
  1956  			PointerSliceEmpty:     addr(sliceMarshalEmpty{"value"}),
  1957  			PointerSliceNonEmpty:  addr(sliceMarshalNonEmpty{"value"}),
  1958  			Pointer:               &structOmitZeroEmptyAll{Float: math.SmallestNonzeroFloat64},
  1959  			Interface:             []string{""},
  1960  		},
  1961  		want: `{
  1962  	"Bool": true,
  1963  	"PointerBool": true,
  1964  	"String": "value",
  1965  	"StringNonEmpty": "value",
  1966  	"PointerString": "value",
  1967  	"PointerStringNonEmpty": "value",
  1968  	"Bytes": "dmFsdWU=",
  1969  	"BytesNonEmpty": [
  1970  		"value"
  1971  	],
  1972  	"PointerBytes": "dmFsdWU=",
  1973  	"PointerBytesNonEmpty": [
  1974  		"value"
  1975  	],
  1976  	"Float": -0,
  1977  	"PointerFloat": -0,
  1978  	"Map": {
  1979  		"": ""
  1980  	},
  1981  	"MapNonEmpty": {
  1982  		"key": "value"
  1983  	},
  1984  	"PointerMap": {
  1985  		"": ""
  1986  	},
  1987  	"PointerMapNonEmpty": {
  1988  		"key": "value"
  1989  	},
  1990  	"Slice": [
  1991  		""
  1992  	],
  1993  	"SliceNonEmpty": [
  1994  		"value"
  1995  	],
  1996  	"PointerSlice": [
  1997  		""
  1998  	],
  1999  	"PointerSliceNonEmpty": [
  2000  		"value"
  2001  	],
  2002  	"Pointer": {
  2003  		"Float": 5e-324
  2004  	},
  2005  	"Interface": [
  2006  		""
  2007  	]
  2008  }`,
  2009  	}, {
  2010  		name: jsontest.Name("Structs/OmitEmpty/Legacy/Zero"),
  2011  		opts: []Options{jsonflags.OmitEmptyWithLegacySemantics | 1},
  2012  		in:   structOmitEmptyAll{},
  2013  		want: `{}`,
  2014  	}, {
  2015  		name: jsontest.Name("Structs/OmitEmpty/Legacy/NonEmpty"),
  2016  		opts: []Options{jsontext.Multiline(true), jsonflags.OmitEmptyWithLegacySemantics | 1},
  2017  		in: structOmitEmptyAll{
  2018  			Bool:                  true,
  2019  			PointerBool:           addr(true),
  2020  			String:                string("value"),
  2021  			StringEmpty:           stringMarshalEmpty("value"),
  2022  			StringNonEmpty:        stringMarshalNonEmpty("value"),
  2023  			PointerString:         addr(string("value")),
  2024  			PointerStringEmpty:    addr(stringMarshalEmpty("value")),
  2025  			PointerStringNonEmpty: addr(stringMarshalNonEmpty("value")),
  2026  			Bytes:                 []byte("value"),
  2027  			BytesEmpty:            bytesMarshalEmpty([]byte("value")),
  2028  			BytesNonEmpty:         bytesMarshalNonEmpty([]byte("value")),
  2029  			PointerBytes:          addr([]byte("value")),
  2030  			PointerBytesEmpty:     addr(bytesMarshalEmpty([]byte("value"))),
  2031  			PointerBytesNonEmpty:  addr(bytesMarshalNonEmpty([]byte("value"))),
  2032  			Float:                 math.Copysign(0, -1),
  2033  			PointerFloat:          addr(math.Copysign(0, -1)),
  2034  			Map:                   map[string]string{"": ""},
  2035  			MapEmpty:              mapMarshalEmpty{"key": "value"},
  2036  			MapNonEmpty:           mapMarshalNonEmpty{"key": "value"},
  2037  			PointerMap:            addr(map[string]string{"": ""}),
  2038  			PointerMapEmpty:       addr(mapMarshalEmpty{"key": "value"}),
  2039  			PointerMapNonEmpty:    addr(mapMarshalNonEmpty{"key": "value"}),
  2040  			Slice:                 []string{""},
  2041  			SliceEmpty:            sliceMarshalEmpty{"value"},
  2042  			SliceNonEmpty:         sliceMarshalNonEmpty{"value"},
  2043  			PointerSlice:          addr([]string{""}),
  2044  			PointerSliceEmpty:     addr(sliceMarshalEmpty{"value"}),
  2045  			PointerSliceNonEmpty:  addr(sliceMarshalNonEmpty{"value"}),
  2046  			Pointer:               &structOmitZeroEmptyAll{Float: math.Copysign(0, -1)},
  2047  			Interface:             []string{""},
  2048  		},
  2049  		want: `{
  2050  	"Bool": true,
  2051  	"PointerBool": true,
  2052  	"String": "value",
  2053  	"StringEmpty": "",
  2054  	"StringNonEmpty": "value",
  2055  	"PointerString": "value",
  2056  	"PointerStringEmpty": "",
  2057  	"PointerStringNonEmpty": "value",
  2058  	"Bytes": "dmFsdWU=",
  2059  	"BytesEmpty": [],
  2060  	"BytesNonEmpty": [
  2061  		"value"
  2062  	],
  2063  	"PointerBytes": "dmFsdWU=",
  2064  	"PointerBytesEmpty": [],
  2065  	"PointerBytesNonEmpty": [
  2066  		"value"
  2067  	],
  2068  	"PointerFloat": -0,
  2069  	"Map": {
  2070  		"": ""
  2071  	},
  2072  	"MapEmpty": {},
  2073  	"MapNonEmpty": {
  2074  		"key": "value"
  2075  	},
  2076  	"PointerMap": {
  2077  		"": ""
  2078  	},
  2079  	"PointerMapEmpty": {},
  2080  	"PointerMapNonEmpty": {
  2081  		"key": "value"
  2082  	},
  2083  	"Slice": [
  2084  		""
  2085  	],
  2086  	"SliceEmpty": [],
  2087  	"SliceNonEmpty": [
  2088  		"value"
  2089  	],
  2090  	"PointerSlice": [
  2091  		""
  2092  	],
  2093  	"PointerSliceEmpty": [],
  2094  	"PointerSliceNonEmpty": [
  2095  		"value"
  2096  	],
  2097  	"Pointer": {},
  2098  	"Interface": [
  2099  		""
  2100  	]
  2101  }`,
  2102  	}, {
  2103  		name: jsontest.Name("Structs/OmitEmpty/NonEmptyString"),
  2104  		in: struct {
  2105  			X string `json:",omitempty"`
  2106  		}{`"`},
  2107  		want: `{"X":"\""}`,
  2108  	}, {
  2109  		name: jsontest.Name("Structs/OmitZeroEmpty/Zero"),
  2110  		in:   structOmitZeroEmptyAll{},
  2111  		want: `{}`,
  2112  	}, {
  2113  		name: jsontest.Name("Structs/OmitZeroEmpty/Empty"),
  2114  		in: structOmitZeroEmptyAll{
  2115  			Bytes:     []byte{},
  2116  			Map:       map[string]string{},
  2117  			Slice:     []string{},
  2118  			Pointer:   &structOmitZeroEmptyAll{},
  2119  			Interface: []string{},
  2120  		},
  2121  		want: `{}`,
  2122  	}, {
  2123  		name: jsontest.Name("Structs/OmitEmpty/PathologicalDepth"),
  2124  		in: func() any {
  2125  			type X struct {
  2126  				X *X `json:",omitempty"`
  2127  			}
  2128  			var make func(int) *X
  2129  			make = func(n int) *X {
  2130  				if n == 0 {
  2131  					return nil
  2132  				}
  2133  				return &X{make(n - 1)}
  2134  			}
  2135  			return make(100)
  2136  		}(),
  2137  		want:      `{}`,
  2138  		useWriter: true,
  2139  	}, {
  2140  		name: jsontest.Name("Structs/OmitEmpty/PathologicalBreadth"),
  2141  		in: func() any {
  2142  			var fields []reflect.StructField
  2143  			for i := range 100 {
  2144  				fields = append(fields, reflect.StructField{
  2145  					Name: fmt.Sprintf("X%d", i),
  2146  					Type: T[stringMarshalEmpty](),
  2147  					Tag:  `json:",omitempty"`,
  2148  				})
  2149  			}
  2150  			return reflect.New(reflect.StructOf(fields)).Interface()
  2151  		}(),
  2152  		want:      `{}`,
  2153  		useWriter: true,
  2154  	}, {
  2155  		name: jsontest.Name("Structs/OmitEmpty/PathologicalTree"),
  2156  		in: func() any {
  2157  			type X struct {
  2158  				XL, XR *X `json:",omitempty"`
  2159  			}
  2160  			var make func(int) *X
  2161  			make = func(n int) *X {
  2162  				if n == 0 {
  2163  					return nil
  2164  				}
  2165  				return &X{make(n - 1), make(n - 1)}
  2166  			}
  2167  			return make(8)
  2168  		}(),
  2169  		want:      `{}`,
  2170  		useWriter: true,
  2171  	}, {
  2172  		name: jsontest.Name("Structs/OmitZeroEmpty/NonEmpty"),
  2173  		in: structOmitZeroEmptyAll{
  2174  			Bytes:     []byte("value"),
  2175  			Map:       map[string]string{"": ""},
  2176  			Slice:     []string{""},
  2177  			Pointer:   &structOmitZeroEmptyAll{Bool: true},
  2178  			Interface: []string{""},
  2179  		},
  2180  		want: `{"Bytes":"dmFsdWU=","Map":{"":""},"Slice":[""],"Pointer":{"Bool":true},"Interface":[""]}`,
  2181  	}, {
  2182  		name:    jsontest.Name("Structs/Format/Bytes/Unsupported"),
  2183  		opts:    []Options{jsontext.Multiline(true)},
  2184  		in:      structFormatBytes{},
  2185  		wantErr: EM(errors.New("Go struct field Base16 has unsupported `format` tag option")).withType(0, T[structFormatBytes]()),
  2186  	}, {
  2187  		name: jsontest.Name("Structs/Format/Bytes"),
  2188  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsontext.Multiline(true)},
  2189  		in: structFormatBytes{
  2190  			Base16:    []byte("\x01\x23\x45\x67\x89\xab\xcd\xef"),
  2191  			Base32:    []byte("\x00D2\x14\xc7BT\xb65τe:V\xd7\xc6u\xbew\xdf"),
  2192  			Base32Hex: []byte("\x00D2\x14\xc7BT\xb65τe:V\xd7\xc6u\xbew\xdf"),
  2193  			Base64:    []byte("\x00\x10\x83\x10Q\x87 \x92\x8b0ӏA\x14\x93QU\x97a\x96\x9bqן\x82\x18\xa3\x92Y\xa7\xa2\x9a\xab\xb2ۯ\xc3\x1c\xb3\xd3]\xb7㞻\xf3߿"),
  2194  			Base64URL: []byte("\x00\x10\x83\x10Q\x87 \x92\x8b0ӏA\x14\x93QU\x97a\x96\x9bqן\x82\x18\xa3\x92Y\xa7\xa2\x9a\xab\xb2ۯ\xc3\x1c\xb3\xd3]\xb7㞻\xf3߿"),
  2195  			Array:     []byte{1, 2, 3, 4},
  2196  		},
  2197  		want: `{
  2198  	"Base16": "0123456789abcdef",
  2199  	"Base32": "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
  2200  	"Base32Hex": "0123456789ABCDEFGHIJKLMNOPQRSTUV",
  2201  	"Base64": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  2202  	"Base64URL": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
  2203  	"Array": [
  2204  		1,
  2205  		2,
  2206  		3,
  2207  		4
  2208  	]
  2209  }`,
  2210  	}, {
  2211  		name: jsontest.Name("Structs/Format/ArrayBytes"),
  2212  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsontext.Multiline(true)},
  2213  		in: structFormatArrayBytes{
  2214  			Base16:    [4]byte{1, 2, 3, 4},
  2215  			Base32:    [4]byte{1, 2, 3, 4},
  2216  			Base32Hex: [4]byte{1, 2, 3, 4},
  2217  			Base64:    [4]byte{1, 2, 3, 4},
  2218  			Base64URL: [4]byte{1, 2, 3, 4},
  2219  			Array:     [4]byte{1, 2, 3, 4},
  2220  			Default:   [4]byte{1, 2, 3, 4},
  2221  		},
  2222  		want: `{
  2223  	"Base16": "01020304",
  2224  	"Base32": "AEBAGBA=",
  2225  	"Base32Hex": "0410610=",
  2226  	"Base64": "AQIDBA==",
  2227  	"Base64URL": "AQIDBA==",
  2228  	"Array": [
  2229  		1,
  2230  		2,
  2231  		3,
  2232  		4
  2233  	],
  2234  	"Default": "AQIDBA=="
  2235  }`,
  2236  	}, {
  2237  		name: jsontest.Name("Structs/Format/ArrayBytes/Legacy"),
  2238  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsontext.Multiline(true), jsonflags.FormatByteArrayAsArray | jsonflags.FormatBytesWithLegacySemantics | 1},
  2239  		in: structFormatArrayBytes{
  2240  			Base16:    [4]byte{1, 2, 3, 4},
  2241  			Base32:    [4]byte{1, 2, 3, 4},
  2242  			Base32Hex: [4]byte{1, 2, 3, 4},
  2243  			Base64:    [4]byte{1, 2, 3, 4},
  2244  			Base64URL: [4]byte{1, 2, 3, 4},
  2245  			Array:     [4]byte{1, 2, 3, 4},
  2246  			Default:   [4]byte{1, 2, 3, 4},
  2247  		},
  2248  		want: `{
  2249  	"Base16": "01020304",
  2250  	"Base32": "AEBAGBA=",
  2251  	"Base32Hex": "0410610=",
  2252  	"Base64": "AQIDBA==",
  2253  	"Base64URL": "AQIDBA==",
  2254  	"Array": [
  2255  		1,
  2256  		2,
  2257  		3,
  2258  		4
  2259  	],
  2260  	"Default": [
  2261  		1,
  2262  		2,
  2263  		3,
  2264  		4
  2265  	]
  2266  }`,
  2267  	}, {
  2268  		name: jsontest.Name("Structs/Format/Bytes/Array"),
  2269  		opts: []Options{
  2270  			jsonopts.ExperimentalSupportFormatTag(true),
  2271  			WithMarshalers(MarshalFunc(func(in byte) ([]byte, error) {
  2272  				if in > 3 {
  2273  					return []byte("true"), nil
  2274  				} else {
  2275  					return []byte("false"), nil
  2276  				}
  2277  			})),
  2278  		},
  2279  		in: struct {
  2280  			Array []byte `json:",format:array"`
  2281  		}{
  2282  			Array: []byte{1, 6, 2, 5, 3, 4},
  2283  		},
  2284  		want: `{"Array":[false,true,false,true,false,true]}`,
  2285  	}, {
  2286  		name: jsontest.Name("Structs/Format/Floats"),
  2287  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsontext.Multiline(true)},
  2288  		in: []structFormatFloats{
  2289  			{NonFinite: math.Pi, PointerNonFinite: addr(math.Pi)},
  2290  			{NonFinite: math.NaN(), PointerNonFinite: addr(math.NaN())},
  2291  			{NonFinite: math.Inf(-1), PointerNonFinite: addr(math.Inf(-1))},
  2292  			{NonFinite: math.Inf(+1), PointerNonFinite: addr(math.Inf(+1))},
  2293  		},
  2294  		want: `[
  2295  	{
  2296  		"NonFinite": 3.141592653589793,
  2297  		"PointerNonFinite": 3.141592653589793
  2298  	},
  2299  	{
  2300  		"NonFinite": "NaN",
  2301  		"PointerNonFinite": "NaN"
  2302  	},
  2303  	{
  2304  		"NonFinite": "-Infinity",
  2305  		"PointerNonFinite": "-Infinity"
  2306  	},
  2307  	{
  2308  		"NonFinite": "Infinity",
  2309  		"PointerNonFinite": "Infinity"
  2310  	}
  2311  ]`,
  2312  	}, {
  2313  		name: jsontest.Name("Structs/Format/Maps"),
  2314  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsontext.Multiline(true)},
  2315  		in: []structFormatMaps{{
  2316  			EmitNull: map[string]string(nil), PointerEmitNull: addr(map[string]string(nil)),
  2317  			EmitEmpty: map[string]string(nil), PointerEmitEmpty: addr(map[string]string(nil)),
  2318  			EmitDefault: map[string]string(nil), PointerEmitDefault: addr(map[string]string(nil)),
  2319  		}, {
  2320  			EmitNull: map[string]string{}, PointerEmitNull: addr(map[string]string{}),
  2321  			EmitEmpty: map[string]string{}, PointerEmitEmpty: addr(map[string]string{}),
  2322  			EmitDefault: map[string]string{}, PointerEmitDefault: addr(map[string]string{}),
  2323  		}, {
  2324  			EmitNull: map[string]string{"k": "v"}, PointerEmitNull: addr(map[string]string{"k": "v"}),
  2325  			EmitEmpty: map[string]string{"k": "v"}, PointerEmitEmpty: addr(map[string]string{"k": "v"}),
  2326  			EmitDefault: map[string]string{"k": "v"}, PointerEmitDefault: addr(map[string]string{"k": "v"}),
  2327  		}},
  2328  		want: `[
  2329  	{
  2330  		"EmitNull": null,
  2331  		"PointerEmitNull": null,
  2332  		"EmitEmpty": {},
  2333  		"PointerEmitEmpty": {},
  2334  		"EmitDefault": {},
  2335  		"PointerEmitDefault": {}
  2336  	},
  2337  	{
  2338  		"EmitNull": {},
  2339  		"PointerEmitNull": {},
  2340  		"EmitEmpty": {},
  2341  		"PointerEmitEmpty": {},
  2342  		"EmitDefault": {},
  2343  		"PointerEmitDefault": {}
  2344  	},
  2345  	{
  2346  		"EmitNull": {
  2347  			"k": "v"
  2348  		},
  2349  		"PointerEmitNull": {
  2350  			"k": "v"
  2351  		},
  2352  		"EmitEmpty": {
  2353  			"k": "v"
  2354  		},
  2355  		"PointerEmitEmpty": {
  2356  			"k": "v"
  2357  		},
  2358  		"EmitDefault": {
  2359  			"k": "v"
  2360  		},
  2361  		"PointerEmitDefault": {
  2362  			"k": "v"
  2363  		}
  2364  	}
  2365  ]`,
  2366  	}, {
  2367  		name: jsontest.Name("Structs/Format/Maps/FormatNilMapAsNull"),
  2368  		opts: []Options{
  2369  			jsonopts.ExperimentalSupportFormatTag(true),
  2370  			FormatNilMapAsNull(true),
  2371  			jsontext.Multiline(true),
  2372  		},
  2373  		in: []structFormatMaps{{
  2374  			EmitNull: map[string]string(nil), PointerEmitNull: addr(map[string]string(nil)),
  2375  			EmitEmpty: map[string]string(nil), PointerEmitEmpty: addr(map[string]string(nil)),
  2376  			EmitDefault: map[string]string(nil), PointerEmitDefault: addr(map[string]string(nil)),
  2377  		}, {
  2378  			EmitNull: map[string]string{}, PointerEmitNull: addr(map[string]string{}),
  2379  			EmitEmpty: map[string]string{}, PointerEmitEmpty: addr(map[string]string{}),
  2380  			EmitDefault: map[string]string{}, PointerEmitDefault: addr(map[string]string{}),
  2381  		}, {
  2382  			EmitNull: map[string]string{"k": "v"}, PointerEmitNull: addr(map[string]string{"k": "v"}),
  2383  			EmitEmpty: map[string]string{"k": "v"}, PointerEmitEmpty: addr(map[string]string{"k": "v"}),
  2384  			EmitDefault: map[string]string{"k": "v"}, PointerEmitDefault: addr(map[string]string{"k": "v"}),
  2385  		}},
  2386  		want: `[
  2387  	{
  2388  		"EmitNull": null,
  2389  		"PointerEmitNull": null,
  2390  		"EmitEmpty": {},
  2391  		"PointerEmitEmpty": {},
  2392  		"EmitDefault": null,
  2393  		"PointerEmitDefault": null
  2394  	},
  2395  	{
  2396  		"EmitNull": {},
  2397  		"PointerEmitNull": {},
  2398  		"EmitEmpty": {},
  2399  		"PointerEmitEmpty": {},
  2400  		"EmitDefault": {},
  2401  		"PointerEmitDefault": {}
  2402  	},
  2403  	{
  2404  		"EmitNull": {
  2405  			"k": "v"
  2406  		},
  2407  		"PointerEmitNull": {
  2408  			"k": "v"
  2409  		},
  2410  		"EmitEmpty": {
  2411  			"k": "v"
  2412  		},
  2413  		"PointerEmitEmpty": {
  2414  			"k": "v"
  2415  		},
  2416  		"EmitDefault": {
  2417  			"k": "v"
  2418  		},
  2419  		"PointerEmitDefault": {
  2420  			"k": "v"
  2421  		}
  2422  	}
  2423  ]`,
  2424  	}, {
  2425  		name: jsontest.Name("Structs/Format/Slices"),
  2426  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsontext.Multiline(true)},
  2427  		in: []structFormatSlices{{
  2428  			EmitNull: []string(nil), PointerEmitNull: addr([]string(nil)),
  2429  			EmitEmpty: []string(nil), PointerEmitEmpty: addr([]string(nil)),
  2430  			EmitDefault: []string(nil), PointerEmitDefault: addr([]string(nil)),
  2431  		}, {
  2432  			EmitNull: []string{}, PointerEmitNull: addr([]string{}),
  2433  			EmitEmpty: []string{}, PointerEmitEmpty: addr([]string{}),
  2434  			EmitDefault: []string{}, PointerEmitDefault: addr([]string{}),
  2435  		}, {
  2436  			EmitNull: []string{"v"}, PointerEmitNull: addr([]string{"v"}),
  2437  			EmitEmpty: []string{"v"}, PointerEmitEmpty: addr([]string{"v"}),
  2438  			EmitDefault: []string{"v"}, PointerEmitDefault: addr([]string{"v"}),
  2439  		}},
  2440  		want: `[
  2441  	{
  2442  		"EmitNull": null,
  2443  		"PointerEmitNull": null,
  2444  		"EmitEmpty": [],
  2445  		"PointerEmitEmpty": [],
  2446  		"EmitDefault": [],
  2447  		"PointerEmitDefault": []
  2448  	},
  2449  	{
  2450  		"EmitNull": [],
  2451  		"PointerEmitNull": [],
  2452  		"EmitEmpty": [],
  2453  		"PointerEmitEmpty": [],
  2454  		"EmitDefault": [],
  2455  		"PointerEmitDefault": []
  2456  	},
  2457  	{
  2458  		"EmitNull": [
  2459  			"v"
  2460  		],
  2461  		"PointerEmitNull": [
  2462  			"v"
  2463  		],
  2464  		"EmitEmpty": [
  2465  			"v"
  2466  		],
  2467  		"PointerEmitEmpty": [
  2468  			"v"
  2469  		],
  2470  		"EmitDefault": [
  2471  			"v"
  2472  		],
  2473  		"PointerEmitDefault": [
  2474  			"v"
  2475  		]
  2476  	}
  2477  ]`,
  2478  	}, {
  2479  		name:    jsontest.Name("Structs/Format/Invalid/Bool"),
  2480  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2481  		in:      structFormatInvalid{Bool: true},
  2482  		want:    `{"Bool"`,
  2483  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Bool":`, "/Bool").withType(0, boolType),
  2484  	}, {
  2485  		name:    jsontest.Name("Structs/Format/Invalid/String"),
  2486  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2487  		in:      structFormatInvalid{String: "string"},
  2488  		want:    `{"String"`,
  2489  		wantErr: EM(errInvalidFormatFlag).withPos(`{"String":`, "/String").withType(0, stringType),
  2490  	}, {
  2491  		name:    jsontest.Name("Structs/Format/Invalid/Bytes"),
  2492  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2493  		in:      structFormatInvalid{Bytes: []byte("bytes")},
  2494  		want:    `{"Bytes"`,
  2495  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Bytes":`, "/Bytes").withType(0, bytesType),
  2496  	}, {
  2497  		name:    jsontest.Name("Structs/Format/Invalid/Int"),
  2498  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2499  		in:      structFormatInvalid{Int: 1},
  2500  		want:    `{"Int"`,
  2501  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Int":`, "/Int").withType(0, T[int64]()),
  2502  	}, {
  2503  		name:    jsontest.Name("Structs/Format/Invalid/Uint"),
  2504  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2505  		in:      structFormatInvalid{Uint: 1},
  2506  		want:    `{"Uint"`,
  2507  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Uint":`, "/Uint").withType(0, T[uint64]()),
  2508  	}, {
  2509  		name:    jsontest.Name("Structs/Format/Invalid/Float"),
  2510  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2511  		in:      structFormatInvalid{Float: 1},
  2512  		want:    `{"Float"`,
  2513  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Float":`, "/Float").withType(0, T[float64]()),
  2514  	}, {
  2515  		name:    jsontest.Name("Structs/Format/Invalid/Map"),
  2516  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2517  		in:      structFormatInvalid{Map: map[string]string{}},
  2518  		want:    `{"Map"`,
  2519  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Map":`, "/Map").withType(0, T[map[string]string]()),
  2520  	}, {
  2521  		name:    jsontest.Name("Structs/Format/Invalid/Struct"),
  2522  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2523  		in:      structFormatInvalid{Struct: structAll{Bool: true}},
  2524  		want:    `{"Struct"`,
  2525  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Struct":`, "/Struct").withType(0, T[structAll]()),
  2526  	}, {
  2527  		name:    jsontest.Name("Structs/Format/Invalid/Slice"),
  2528  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2529  		in:      structFormatInvalid{Slice: []string{}},
  2530  		want:    `{"Slice"`,
  2531  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Slice":`, "/Slice").withType(0, T[[]string]()),
  2532  	}, {
  2533  		name:    jsontest.Name("Structs/Format/Invalid/Array"),
  2534  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2535  		in:      structFormatInvalid{Array: [1]string{"string"}},
  2536  		want:    `{"Array"`,
  2537  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Array":`, "/Array").withType(0, T[[1]string]()),
  2538  	}, {
  2539  		name:    jsontest.Name("Structs/Format/Invalid/Interface"),
  2540  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  2541  		in:      structFormatInvalid{Interface: "anything"},
  2542  		want:    `{"Interface"`,
  2543  		wantErr: EM(errInvalidFormatFlag).withPos(`{"Interface":`, "/Interface").withType(0, T[any]()),
  2544  	}, {
  2545  		name: jsontest.Name("Structs/Embed/Zero"),
  2546  		in:   structEmbedded{},
  2547  		want: `{"D":""}`,
  2548  	}, {
  2549  		name: jsontest.Name("Structs/Embed/Alloc"),
  2550  		in: structEmbedded{
  2551  			X: structEmbeddedL1{
  2552  				X:            &structEmbeddedL2{},
  2553  				StructEmbed1: StructEmbed1{},
  2554  			},
  2555  			StructEmbed2: &StructEmbed2{},
  2556  		},
  2557  		want: `{"A":"","B":"","D":"","E":"","F":"","G":""}`,
  2558  	}, {
  2559  		name: jsontest.Name("Structs/Embed/NonZero"),
  2560  		in: structEmbedded{
  2561  			X: structEmbeddedL1{
  2562  				X:            &structEmbeddedL2{A: "A1", B: "B1", C: "C1"},
  2563  				StructEmbed1: StructEmbed1{C: "C2", D: "D2", E: "E2"},
  2564  			},
  2565  			StructEmbed2: &StructEmbed2{E: "E3", F: "F3", G: "G3"},
  2566  		},
  2567  		want: `{"A":"A1","B":"B1","D":"D2","E":"E3","F":"F3","G":"G3"}`,
  2568  	}, {
  2569  		name: jsontest.Name("Structs/Embed/DualCycle"),
  2570  		in: cyclicA{
  2571  			B1: cyclicB{F: 1}, // B1.F ignored since it conflicts with B2.F
  2572  			B2: cyclicB{F: 2}, // B2.F ignored since it conflicts with B1.F
  2573  		},
  2574  		want: `{}`,
  2575  	}, {
  2576  		name: jsontest.Name("Structs/EmbeddedFallback/TextValue/Nil"),
  2577  		in:   structEmbedTextValue{X: jsontext.Value(nil)},
  2578  		want: `{}`,
  2579  	}, {
  2580  		name: jsontest.Name("Structs/EmbeddedFallback/TextValue/Empty"),
  2581  		in:   structEmbedTextValue{X: jsontext.Value("")},
  2582  		want: `{}`,
  2583  	}, {
  2584  		name: jsontest.Name("Structs/EmbeddedFallback/TextValue/NonEmptyN1"),
  2585  		in:   structEmbedTextValue{X: jsontext.Value(` { "fizz" : "buzz" } `)},
  2586  		want: `{"fizz":"buzz"}`,
  2587  	}, {
  2588  		name: jsontest.Name("Structs/EmbeddedFallback/TextValue/NonEmptyN2"),
  2589  		in:   structEmbedTextValue{X: jsontext.Value(` { "fizz" : "buzz" , "foo" : "bar" } `)},
  2590  		want: `{"fizz":"buzz","foo":"bar"}`,
  2591  	}, {
  2592  		name: jsontest.Name("Structs/EmbeddedFallback/TextValue/NonEmptyWithOthers"),
  2593  		in: structEmbedTextValue{
  2594  			A: 1,
  2595  			X: jsontext.Value(` { "fizz" : "buzz" , "foo" : "bar" } `),
  2596  			B: 2,
  2597  		},
  2598  		// NOTE: Embedded fallback fields are always serialized last.
  2599  		want: `{"A":1,"B":2,"fizz":"buzz","foo":"bar"}`,
  2600  	}, {
  2601  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/RejectDuplicateNames"),
  2602  		opts:    []Options{jsontext.AllowDuplicateNames(false)},
  2603  		in:      structEmbedTextValue{X: jsontext.Value(` { "fizz" : "buzz" , "fizz" : "buzz" } `)},
  2604  		want:    `{"fizz":"buzz"`,
  2605  		wantErr: newDuplicateNameError("/fizz", nil, len64(`{"fizz":"buzz"`)),
  2606  	}, {
  2607  		name: jsontest.Name("Structs/EmbeddedFallback/TextValue/AllowDuplicateNames"),
  2608  		opts: []Options{jsontext.AllowDuplicateNames(true)},
  2609  		in:   structEmbedTextValue{X: jsontext.Value(` { "fizz" : "buzz" , "fizz" : "buzz" } `)},
  2610  		want: `{"fizz":"buzz","fizz":"buzz"}`,
  2611  	}, {
  2612  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/RejectInvalidUTF8"),
  2613  		opts:    []Options{jsontext.AllowInvalidUTF8(false)},
  2614  		in:      structEmbedTextValue{X: jsontext.Value(`{"` + "\xde\xad\xbe\xef" + `":"value"}`)},
  2615  		want:    `{`,
  2616  		wantErr: newInvalidUTF8Error(len64(`{"`+"\xde\xad"), ""),
  2617  	}, {
  2618  		name: jsontest.Name("Structs/EmbeddedFallback/TextValue/AllowInvalidUTF8"),
  2619  		opts: []Options{jsontext.AllowInvalidUTF8(true)},
  2620  		in:   structEmbedTextValue{X: jsontext.Value(`{"` + "\xde\xad\xbe\xef" + `":"value"}`)},
  2621  		want: `{"ޭ��":"value"}`,
  2622  	}, {
  2623  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/InvalidWhitespace"),
  2624  		in:      structEmbedTextValue{X: jsontext.Value("\n\r\t ")},
  2625  		want:    `{`,
  2626  		wantErr: EM(io.ErrUnexpectedEOF).withPos(`{`, "").withType(0, T[jsontext.Value]()),
  2627  	}, {
  2628  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/InvalidObject"),
  2629  		in:      structEmbedTextValue{X: jsontext.Value(` true `)},
  2630  		want:    `{`,
  2631  		wantErr: EM(errRawEmbedNotObject).withPos(`{`, "").withType(0, T[jsontext.Value]()),
  2632  	}, {
  2633  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/InvalidObjectName"),
  2634  		in:      structEmbedTextValue{X: jsontext.Value(` { true : false } `)},
  2635  		want:    `{`,
  2636  		wantErr: EM(newNonStringNameError(len64(" { "), "")).withPos(`{`, "").withType(0, T[jsontext.Value]()),
  2637  	}, {
  2638  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/InvalidEndObject"),
  2639  		in:      structEmbedTextValue{X: jsontext.Value(` { "name" : false , } `)},
  2640  		want:    `{"name":false`,
  2641  		wantErr: EM(newInvalidCharacterError(",", "at start of value", len64(` { "name" : false `), "")).withPos(`{"name":false,`, "").withType(0, T[jsontext.Value]()),
  2642  	}, {
  2643  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/InvalidDualObject"),
  2644  		in:      structEmbedTextValue{X: jsontext.Value(`{}{}`)},
  2645  		want:    `{`,
  2646  		wantErr: EM(newInvalidCharacterError("{", "after top-level value", len64(`{}`), "")).withPos(`{`, "").withType(0, T[jsontext.Value]()),
  2647  	}, {
  2648  		name: jsontest.Name("Structs/EmbeddedFallback/TextValue/Nested/Nil"),
  2649  		in:   structEmbedPointerEmbedTextValue{},
  2650  		want: `{}`,
  2651  	}, {
  2652  		name: jsontest.Name("Structs/EmbeddedFallback/PointerTextValue/Nil"),
  2653  		in:   structEmbedPointerTextValue{},
  2654  		want: `{}`,
  2655  	}, {
  2656  		name: jsontest.Name("Structs/EmbeddedFallback/PointerTextValue/NonEmpty"),
  2657  		in:   structEmbedPointerTextValue{X: addr(jsontext.Value(` { "fizz" : "buzz" } `))},
  2658  		want: `{"fizz":"buzz"}`,
  2659  	}, {
  2660  		name: jsontest.Name("Structs/EmbeddedFallback/PointerTextValue/Nested/Nil"),
  2661  		in:   structEmbedEmbedPointerTextValue{},
  2662  		want: `{}`,
  2663  	}, {
  2664  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringAny/Nil"),
  2665  		in:   structEmbedMapStringAny{X: nil},
  2666  		want: `{}`,
  2667  	}, {
  2668  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringAny/Empty"),
  2669  		in:   structEmbedMapStringAny{X: make(jsonObject)},
  2670  		want: `{}`,
  2671  	}, {
  2672  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringAny/NonEmptyN1"),
  2673  		in:   structEmbedMapStringAny{X: jsonObject{"fizz": nil}},
  2674  		want: `{"fizz":null}`,
  2675  	}, {
  2676  		name:         jsontest.Name("Structs/EmbeddedFallback/MapStringAny/NonEmptyN2"),
  2677  		in:           structEmbedMapStringAny{X: jsonObject{"fizz": time.Time{}, "buzz": math.Pi}},
  2678  		want:         `{"buzz":3.141592653589793,"fizz":"0001-01-01T00:00:00Z"}`,
  2679  		canonicalize: true,
  2680  	}, {
  2681  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringAny/NonEmptyWithOthers"),
  2682  		in: structEmbedMapStringAny{
  2683  			A: 1,
  2684  			X: jsonObject{"fizz": nil},
  2685  			B: 2,
  2686  		},
  2687  		// NOTE: Embedded fallback fields are always serialized last.
  2688  		want: `{"A":1,"B":2,"fizz":null}`,
  2689  	}, {
  2690  		name:    jsontest.Name("Structs/EmbeddedFallback/MapStringAny/RejectInvalidUTF8"),
  2691  		opts:    []Options{jsontext.AllowInvalidUTF8(false)},
  2692  		in:      structEmbedMapStringAny{X: jsonObject{"\xde\xad\xbe\xef": nil}},
  2693  		want:    `{`,
  2694  		wantErr: EM(jsonwire.ErrInvalidUTF8).withPos(`{`, "").withType(0, stringType),
  2695  	}, {
  2696  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringAny/AllowInvalidUTF8"),
  2697  		opts: []Options{jsontext.AllowInvalidUTF8(true)},
  2698  		in:   structEmbedMapStringAny{X: jsonObject{"\xde\xad\xbe\xef": nil}},
  2699  		want: `{"ޭ��":null}`,
  2700  	}, {
  2701  		name:    jsontest.Name("Structs/EmbeddedFallback/MapStringAny/InvalidValue"),
  2702  		opts:    []Options{jsontext.AllowInvalidUTF8(true)},
  2703  		in:      structEmbedMapStringAny{X: jsonObject{"name": make(chan string)}},
  2704  		want:    `{"name"`,
  2705  		wantErr: EM(nil).withPos(`{"name":`, "/name").withType(0, T[chan string]()),
  2706  	}, {
  2707  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringAny/Nested/Nil"),
  2708  		in:   structEmbedPointerEmbedMapStringAny{},
  2709  		want: `{}`,
  2710  	}, {
  2711  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringAny/MarshalFunc"),
  2712  		opts: []Options{
  2713  			WithMarshalers(MarshalFunc(func(v float64) ([]byte, error) {
  2714  				return []byte(fmt.Sprintf(`"%v"`, v)), nil
  2715  			})),
  2716  		},
  2717  		in:   structEmbedMapStringAny{X: jsonObject{"fizz": 3.14159}},
  2718  		want: `{"fizz":"3.14159"}`,
  2719  	}, {
  2720  		name: jsontest.Name("Structs/EmbeddedFallback/PointerMapStringAny/Nil"),
  2721  		in:   structEmbedPointerMapStringAny{X: nil},
  2722  		want: `{}`,
  2723  	}, {
  2724  		name: jsontest.Name("Structs/EmbeddedFallback/PointerMapStringAny/NonEmpty"),
  2725  		in:   structEmbedPointerMapStringAny{X: addr(jsonObject{"name": "value"})},
  2726  		want: `{"name":"value"}`,
  2727  	}, {
  2728  		name: jsontest.Name("Structs/EmbeddedFallback/PointerMapStringAny/Nested/Nil"),
  2729  		in:   structEmbedEmbedPointerMapStringAny{},
  2730  		want: `{}`,
  2731  	}, {
  2732  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringInt"),
  2733  		in: structEmbedMapStringInt{
  2734  			X: map[string]int{"zero": 0, "one": 1, "two": 2},
  2735  		},
  2736  		want:         `{"one":1,"two":2,"zero":0}`,
  2737  		canonicalize: true,
  2738  	}, {
  2739  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringInt/Deterministic"),
  2740  		opts: []Options{Deterministic(true)},
  2741  		in: structEmbedMapStringInt{
  2742  			X: map[string]int{"zero": 0, "one": 1, "two": 2},
  2743  		},
  2744  		want: `{"one":1,"two":2,"zero":0}`,
  2745  	}, {
  2746  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringInt/Deterministic+AllowInvalidUTF8+RejectDuplicateNames"),
  2747  		opts: []Options{Deterministic(true), jsontext.AllowInvalidUTF8(true), jsontext.AllowDuplicateNames(false)},
  2748  		in: structEmbedMapStringInt{
  2749  			X: map[string]int{"\xff": 0, "\xfe": 1},
  2750  		},
  2751  		want:    `{"�":1`,
  2752  		wantErr: newDuplicateNameError("", []byte(`"�"`), len64(`{"�":1`)),
  2753  	}, {
  2754  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringInt/Deterministic+AllowInvalidUTF8+AllowDuplicateNames"),
  2755  		opts: []Options{Deterministic(true), jsontext.AllowInvalidUTF8(true), jsontext.AllowDuplicateNames(true)},
  2756  		in: structEmbedMapStringInt{
  2757  			X: map[string]int{"\xff": 0, "\xfe": 1},
  2758  		},
  2759  		want: `{"�":1,"�":0}`,
  2760  	}, {
  2761  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringInt/StringifiedNumbers"),
  2762  		opts: []Options{StringifyNumbers(true)},
  2763  		in: structEmbedMapStringInt{
  2764  			X: map[string]int{"zero": 0, "one": 1, "two": 2},
  2765  		},
  2766  		want:         `{"one":"1","two":"2","zero":"0"}`,
  2767  		canonicalize: true,
  2768  	}, {
  2769  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringInt/MarshalFunc"),
  2770  		opts: []Options{
  2771  			WithMarshalers(JoinMarshalers(
  2772  				// Marshalers do not affect the string key of embedded maps.
  2773  				MarshalFunc(func(v string) ([]byte, error) {
  2774  					return []byte(fmt.Sprintf(`"%q"`, strings.ToUpper(v))), nil
  2775  				}),
  2776  				MarshalFunc(func(v int) ([]byte, error) {
  2777  					return []byte(fmt.Sprintf(`"%v"`, v)), nil
  2778  				}),
  2779  			)),
  2780  		},
  2781  		in: structEmbedMapStringInt{
  2782  			X: map[string]int{"zero": 0, "one": 1, "two": 2},
  2783  		},
  2784  		want:         `{"one":"1","two":"2","zero":"0"}`,
  2785  		canonicalize: true,
  2786  	}, {
  2787  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringInt"),
  2788  		in: structEmbedMapNamedStringInt{
  2789  			X: map[namedString]int{"zero": 0, "one": 1, "two": 2},
  2790  		},
  2791  		want:         `{"one":1,"two":2,"zero":0}`,
  2792  		canonicalize: true,
  2793  	}, {
  2794  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringInt/Deterministic"),
  2795  		opts: []Options{Deterministic(true)},
  2796  		in: structEmbedMapNamedStringInt{
  2797  			X: map[namedString]int{"zero": 0, "one": 1, "two": 2},
  2798  		},
  2799  		want: `{"one":1,"two":2,"zero":0}`,
  2800  	}, {
  2801  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/Nil"),
  2802  		in:   structEmbedMapNamedStringAny{X: nil},
  2803  		want: `{}`,
  2804  	}, {
  2805  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/Empty"),
  2806  		in:   structEmbedMapNamedStringAny{X: make(map[namedString]any)},
  2807  		want: `{}`,
  2808  	}, {
  2809  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/NonEmptyN1"),
  2810  		in:   structEmbedMapNamedStringAny{X: map[namedString]any{"fizz": nil}},
  2811  		want: `{"fizz":null}`,
  2812  	}, {
  2813  		name:         jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/NonEmptyN2"),
  2814  		in:           structEmbedMapNamedStringAny{X: map[namedString]any{"fizz": time.Time{}, "buzz": math.Pi}},
  2815  		want:         `{"buzz":3.141592653589793,"fizz":"0001-01-01T00:00:00Z"}`,
  2816  		canonicalize: true,
  2817  	}, {
  2818  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/NonEmptyWithOthers"),
  2819  		in: structEmbedMapNamedStringAny{
  2820  			A: 1,
  2821  			X: map[namedString]any{"fizz": nil},
  2822  			B: 2,
  2823  		},
  2824  		// NOTE: Embedded fallback fields are always serialized last.
  2825  		want: `{"A":1,"B":2,"fizz":null}`,
  2826  	}, {
  2827  		name:    jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/RejectInvalidUTF8"),
  2828  		opts:    []Options{jsontext.AllowInvalidUTF8(false)},
  2829  		in:      structEmbedMapNamedStringAny{X: map[namedString]any{"\xde\xad\xbe\xef": nil}},
  2830  		want:    `{`,
  2831  		wantErr: EM(jsonwire.ErrInvalidUTF8).withPos(`{`, "").withType(0, T[namedString]()),
  2832  	}, {
  2833  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/AllowInvalidUTF8"),
  2834  		opts: []Options{jsontext.AllowInvalidUTF8(true)},
  2835  		in:   structEmbedMapNamedStringAny{X: map[namedString]any{"\xde\xad\xbe\xef": nil}},
  2836  		want: `{"ޭ��":null}`,
  2837  	}, {
  2838  		name:    jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/InvalidValue"),
  2839  		opts:    []Options{jsontext.AllowInvalidUTF8(true)},
  2840  		in:      structEmbedMapNamedStringAny{X: map[namedString]any{"name": make(chan string)}},
  2841  		want:    `{"name"`,
  2842  		wantErr: EM(nil).withPos(`{"name":`, "/name").withType(0, T[chan string]()),
  2843  	}, {
  2844  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/MarshalFunc"),
  2845  		opts: []Options{
  2846  			WithMarshalers(MarshalFunc(func(v float64) ([]byte, error) {
  2847  				return []byte(fmt.Sprintf(`"%v"`, v)), nil
  2848  			})),
  2849  		},
  2850  		in:   structEmbedMapNamedStringAny{X: map[namedString]any{"fizz": 3.14159}},
  2851  		want: `{"fizz":"3.14159"}`,
  2852  	}, {
  2853  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/Other"),
  2854  		in: structNoCaseEmbedTextValue{
  2855  			X: jsontext.Value(`{"dupe":"","dupe":""}`),
  2856  		},
  2857  		want:    `{"dupe":""`,
  2858  		wantErr: newDuplicateNameError("", []byte(`"dupe"`), len64(`{"dupe":""`)),
  2859  	}, {
  2860  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/Other/AllowDuplicateNames"),
  2861  		opts: []Options{jsontext.AllowDuplicateNames(true)},
  2862  		in: structNoCaseEmbedTextValue{
  2863  			X: jsontext.Value(`{"dupe": "", "dupe": ""}`),
  2864  		},
  2865  		want: `{"dupe":"","dupe":""}`,
  2866  	}, {
  2867  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/ExactDifferent"),
  2868  		in: structNoCaseEmbedTextValue{
  2869  			X: jsontext.Value(`{"Aaa": "", "AaA": "", "AAa": "", "AAA": ""}`),
  2870  		},
  2871  		want: `{"Aaa":"","AaA":"","AAa":"","AAA":""}`,
  2872  	}, {
  2873  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/ExactConflict"),
  2874  		in: structNoCaseEmbedTextValue{
  2875  			X: jsontext.Value(`{"Aaa": "", "Aaa": ""}`),
  2876  		},
  2877  		want:    `{"Aaa":""`,
  2878  		wantErr: newDuplicateNameError("", []byte(`"Aaa"`), len64(`{"Aaa":""`)),
  2879  	}, {
  2880  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/ExactConflict/AllowDuplicateNames"),
  2881  		opts: []Options{jsontext.AllowDuplicateNames(true)},
  2882  		in: structNoCaseEmbedTextValue{
  2883  			X: jsontext.Value(`{"Aaa": "", "Aaa": ""}`),
  2884  		},
  2885  		want: `{"Aaa":"","Aaa":""}`,
  2886  	}, {
  2887  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/NoCaseConflict"),
  2888  		in: structNoCaseEmbedTextValue{
  2889  			X: jsontext.Value(`{"Aaa": "", "AaA": "", "aaa": ""}`),
  2890  		},
  2891  		want:    `{"Aaa":"","AaA":""`,
  2892  		wantErr: newDuplicateNameError("", []byte(`"aaa"`), len64(`{"Aaa":"","AaA":""`)),
  2893  	}, {
  2894  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/NoCaseConflict/AllowDuplicateNames"),
  2895  		opts: []Options{jsontext.AllowDuplicateNames(true)},
  2896  		in: structNoCaseEmbedTextValue{
  2897  			X: jsontext.Value(`{"Aaa": "", "AaA": "", "aaa": ""}`),
  2898  		},
  2899  		want: `{"Aaa":"","AaA":"","aaa":""}`,
  2900  	}, {
  2901  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/ExactDifferentWithField"),
  2902  		in: structNoCaseEmbedTextValue{
  2903  			AAA: "x",
  2904  			AaA: "x",
  2905  			X:   jsontext.Value(`{"Aaa": ""}`),
  2906  		},
  2907  		want: `{"AAA":"x","AaA":"x","Aaa":""}`,
  2908  	}, {
  2909  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/ExactConflictWithField"),
  2910  		in: structNoCaseEmbedTextValue{
  2911  			AAA: "x",
  2912  			AaA: "x",
  2913  			X:   jsontext.Value(`{"AAA": ""}`),
  2914  		},
  2915  		want:    `{"AAA":"x","AaA":"x"`,
  2916  		wantErr: newDuplicateNameError("", []byte(`"AAA"`), len64(`{"AAA":"x","AaA":"x"`)),
  2917  	}, {
  2918  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedTextValue/NoCaseConflictWithField"),
  2919  		in: structNoCaseEmbedTextValue{
  2920  			AAA: "x",
  2921  			AaA: "x",
  2922  			X:   jsontext.Value(`{"aaa": ""}`),
  2923  		},
  2924  		want:    `{"AAA":"x","AaA":"x"`,
  2925  		wantErr: newDuplicateNameError("", []byte(`"aaa"`), len64(`{"AAA":"x","AaA":"x"`)),
  2926  	}, {
  2927  		name: jsontest.Name("Structs/DuplicateName/MatchCaseInsensitiveDelimiter"),
  2928  		in: structNoCaseEmbedTextValue{
  2929  			AaA: "x",
  2930  			X:   jsontext.Value(`{"aa_a": ""}`),
  2931  		},
  2932  		want:    `{"AaA":"x"`,
  2933  		wantErr: newDuplicateNameError("", []byte(`"aa_a"`), len64(`{"AaA":"x"`)),
  2934  	}, {
  2935  		name: jsontest.Name("Structs/DuplicateName/MatchCaseSensitiveDelimiter"),
  2936  		opts: []Options{jsonflags.MatchCaseSensitiveDelimiter | 1},
  2937  		in: structNoCaseEmbedTextValue{
  2938  			AaA: "x",
  2939  			X:   jsontext.Value(`{"aa_a": ""}`),
  2940  		},
  2941  		want: `{"AaA":"x","aa_a":""}`,
  2942  	}, {
  2943  		name: jsontest.Name("Structs/DuplicateName/MatchCaseInsensitiveNames+MatchCaseSensitiveDelimiter"),
  2944  		opts: []Options{MatchCaseInsensitiveNames(true), jsonflags.MatchCaseSensitiveDelimiter | 1},
  2945  		in: structNoCaseEmbedTextValue{
  2946  			AaA: "x",
  2947  			X:   jsontext.Value(`{"aa_a": ""}`),
  2948  		},
  2949  		want: `{"AaA":"x","aa_a":""}`,
  2950  	}, {
  2951  		name: jsontest.Name("Structs/DuplicateName/MatchCaseInsensitiveNames+MatchCaseSensitiveDelimiter"),
  2952  		opts: []Options{MatchCaseInsensitiveNames(true), jsonflags.MatchCaseSensitiveDelimiter | 1},
  2953  		in: structNoCaseEmbedTextValue{
  2954  			AA_b: "x",
  2955  			X:    jsontext.Value(`{"aa_b": ""}`),
  2956  		},
  2957  		want:    `{"AA_b":"x"`,
  2958  		wantErr: newDuplicateNameError("", []byte(`"aa_b"`), len64(`{"AA_b":"x"`)),
  2959  	}, {
  2960  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedMapStringAny/ExactDifferent"),
  2961  		in: structNoCaseEmbedMapStringAny{
  2962  			X: jsonObject{"Aaa": "", "AaA": "", "AAa": "", "AAA": ""},
  2963  		},
  2964  		want:         `{"AAA":"","AAa":"","AaA":"","Aaa":""}`,
  2965  		canonicalize: true,
  2966  	}, {
  2967  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedMapStringAny/ExactDifferentWithField"),
  2968  		in: structNoCaseEmbedMapStringAny{
  2969  			AAA: "x",
  2970  			AaA: "x",
  2971  			X:   jsonObject{"Aaa": ""},
  2972  		},
  2973  		want: `{"AAA":"x","AaA":"x","Aaa":""}`,
  2974  	}, {
  2975  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedMapStringAny/ExactConflictWithField"),
  2976  		in: structNoCaseEmbedMapStringAny{
  2977  			AAA: "x",
  2978  			AaA: "x",
  2979  			X:   jsonObject{"AAA": ""},
  2980  		},
  2981  		want:    `{"AAA":"x","AaA":"x"`,
  2982  		wantErr: newDuplicateNameError("", []byte(`"AAA"`), len64(`{"AAA":"x","AaA":"x"`)),
  2983  	}, {
  2984  		name: jsontest.Name("Structs/DuplicateName/NoCaseEmbedMapStringAny/NoCaseConflictWithField"),
  2985  		in: structNoCaseEmbedMapStringAny{
  2986  			AAA: "x",
  2987  			AaA: "x",
  2988  			X:   jsonObject{"aaa": ""},
  2989  		},
  2990  		want:    `{"AAA":"x","AaA":"x"`,
  2991  		wantErr: newDuplicateNameError("", []byte(`"aaa"`), len64(`{"AAA":"x","AaA":"x"`)),
  2992  	}, {
  2993  		name:    jsontest.Name("Structs/Invalid/Conflicting"),
  2994  		in:      structConflicting{},
  2995  		want:    ``,
  2996  		wantErr: EM(errors.New("Go struct fields A and B conflict over JSON object name \"conflict\"")).withType(0, T[structConflicting]()),
  2997  	}, {
  2998  		name:    jsontest.Name("Structs/Invalid/NoneExported"),
  2999  		in:      structNoneExported{},
  3000  		want:    ``,
  3001  		wantErr: EM(errNoExportedFields).withType(0, T[structNoneExported]()),
  3002  	}, {
  3003  		name:    jsontest.Name("Structs/Invalid/MalformedTag"),
  3004  		in:      structMalformedTag{},
  3005  		want:    ``,
  3006  		wantErr: EM(errors.New("Go struct field Malformed has malformed `json` tag: invalid character '\"' at start of option (expecting Unicode letter)")).withType(0, T[structMalformedTag]()),
  3007  	}, {
  3008  		name:    jsontest.Name("Structs/Invalid/UnexportedTag"),
  3009  		in:      structUnexportedTag{},
  3010  		want:    ``,
  3011  		wantErr: EM(errors.New("unexported Go struct field unexported cannot have non-ignored `json:\"name\"` tag")).withType(0, T[structUnexportedTag]()),
  3012  	}, {
  3013  		name:    jsontest.Name("Structs/Invalid/ExportedEmbedded"),
  3014  		in:      structExportedEmbedded{"hello"},
  3015  		want:    ``,
  3016  		wantErr: EM(errors.New("embedded Go struct field NamedString of non-struct type must be explicitly given a JSON name")).withType(0, T[structExportedEmbedded]()),
  3017  	}, {
  3018  		name: jsontest.Name("Structs/Valid/ExportedEmbedded"),
  3019  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  3020  		in:   structExportedEmbedded{"hello"},
  3021  		want: `{"NamedString":"hello"}`,
  3022  	}, {
  3023  		name: jsontest.Name("Structs/Valid/ExportedEmbeddedTag"),
  3024  		in:   structExportedEmbeddedTag{"hello"},
  3025  		want: `{"name":"hello"}`,
  3026  	}, {
  3027  		name:    jsontest.Name("Structs/Invalid/UnexportedEmbedded"),
  3028  		in:      structUnexportedEmbedded{},
  3029  		want:    ``,
  3030  		wantErr: EM(errors.New("embedded Go struct field namedString of non-struct type must be explicitly given a JSON name")).withType(0, T[structUnexportedEmbedded]()),
  3031  	}, {
  3032  		name: jsontest.Name("Structs/Valid/UnexportedEmbedded"),
  3033  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  3034  		in:   structUnexportedEmbedded{},
  3035  		want: `{}`,
  3036  	}, {
  3037  		name:    jsontest.Name("Structs/Invalid/UnexportedEmbeddedTag"),
  3038  		in:      structUnexportedEmbeddedTag{},
  3039  		wantErr: EM(errors.New("Go struct field namedString is not exported")).withType(0, T[structUnexportedEmbeddedTag]()),
  3040  	}, {
  3041  		name: jsontest.Name("Structs/Valid/UnexportedEmbeddedTag"),
  3042  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  3043  		in:   structUnexportedEmbeddedTag{},
  3044  		want: `{}`,
  3045  	}, {
  3046  		name: jsontest.Name("Structs/Invalid/UnexportedEmbeddedMethodTag"),
  3047  		opts: []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  3048  		in:   structUnexportedEmbeddedMethodTag{},
  3049  		want: `{}`,
  3050  	}, {
  3051  		name: jsontest.Name("Structs/UnexportedEmbeddedStruct/Zero"),
  3052  		in:   structUnexportedEmbeddedStruct{},
  3053  		want: `{"FizzBuzz":0,"Addr":""}`,
  3054  	}, {
  3055  		name: jsontest.Name("Structs/UnexportedEmbeddedStruct/NonZero"),
  3056  		in:   structUnexportedEmbeddedStruct{structOmitZeroAll{Bool: true}, 5, structNestedAddr{netip.AddrFrom4([4]byte{192, 168, 0, 1})}},
  3057  		want: `{"Bool":true,"FizzBuzz":5,"Addr":"192.168.0.1"}`,
  3058  	}, {
  3059  		name: jsontest.Name("Structs/UnexportedEmbeddedStructPointer/Nil"),
  3060  		in:   structUnexportedEmbeddedStructPointer{},
  3061  		want: `{"FizzBuzz":0}`,
  3062  	}, {
  3063  		name: jsontest.Name("Structs/UnexportedEmbeddedStructPointer/Zero"),
  3064  		in:   structUnexportedEmbeddedStructPointer{&structOmitZeroAll{}, 0, &structNestedAddr{}},
  3065  		want: `{"FizzBuzz":0,"Addr":""}`,
  3066  	}, {
  3067  		name: jsontest.Name("Structs/UnexportedEmbeddedStructPointer/NonZero"),
  3068  		in:   structUnexportedEmbeddedStructPointer{&structOmitZeroAll{Bool: true}, 5, &structNestedAddr{netip.AddrFrom4([4]byte{192, 168, 0, 1})}},
  3069  		want: `{"Bool":true,"FizzBuzz":5,"Addr":"192.168.0.1"}`,
  3070  	}, {
  3071  		name: jsontest.Name("Structs/IgnoreInvalidFormat"),
  3072  		opts: []Options{invalidFormatOption},
  3073  		in:   struct{}{},
  3074  		want: `{}`,
  3075  	}, {
  3076  		name: jsontest.Name("Slices/Interface"),
  3077  		in: []any{
  3078  			false, true,
  3079  			"hello", []byte("world"),
  3080  			int32(-32), namedInt64(-64),
  3081  			uint32(+32), namedUint64(+64),
  3082  			float32(32.32), namedFloat64(64.64),
  3083  		},
  3084  		want: `[false,true,"hello","d29ybGQ=",-32,-64,32,64,32.32,64.64]`,
  3085  	}, {
  3086  		name:    jsontest.Name("Slices/Invalid/Channel"),
  3087  		in:      [](chan string){nil},
  3088  		want:    `[`,
  3089  		wantErr: EM(nil).withPos(`[`, "/0").withType(0, T[chan string]()),
  3090  	}, {
  3091  		name: jsontest.Name("Slices/RecursiveSlice"),
  3092  		in: recursiveSlice{
  3093  			nil,
  3094  			{},
  3095  			{nil},
  3096  			{nil, {}},
  3097  		},
  3098  		want: `[[],[],[[]],[[],[]]]`,
  3099  	}, {
  3100  		name: jsontest.Name("Slices/CyclicSlice"),
  3101  		in: func() recursiveSlice {
  3102  			s := recursiveSlice{{}}
  3103  			s[0] = s
  3104  			return s
  3105  		}(),
  3106  		want:    strings.Repeat(`[`, startDetectingCyclesAfter) + `[`,
  3107  		wantErr: EM(internal.ErrCycle).withPos(strings.Repeat("[", startDetectingCyclesAfter+1), jsontext.Pointer(strings.Repeat("/0", startDetectingCyclesAfter+1))).withType(0, T[recursiveSlice]()),
  3108  	}, {
  3109  		name: jsontest.Name("Slices/NonCyclicSlice"),
  3110  		in: func() []any {
  3111  			v := []any{nil, nil}
  3112  			v[1] = v[:1]
  3113  			for i := 1000; i > 0; i-- {
  3114  				v = []any{v}
  3115  			}
  3116  			return v
  3117  		}(),
  3118  		want: strings.Repeat(`[`, startDetectingCyclesAfter) + `[null,[null]]` + strings.Repeat(`]`, startDetectingCyclesAfter),
  3119  	}, {
  3120  		name: jsontest.Name("Slices/IgnoreInvalidFormat"),
  3121  		opts: []Options{invalidFormatOption},
  3122  		in:   []string{"hello", "goodbye"},
  3123  		want: `["hello","goodbye"]`,
  3124  	}, {
  3125  		name: jsontest.Name("Arrays/Empty"),
  3126  		in:   [0]struct{}{},
  3127  		want: `[]`,
  3128  	}, {
  3129  		name: jsontest.Name("Arrays/Bool"),
  3130  		in:   [2]bool{false, true},
  3131  		want: `[false,true]`,
  3132  	}, {
  3133  		name: jsontest.Name("Arrays/String"),
  3134  		in:   [2]string{"hello", "goodbye"},
  3135  		want: `["hello","goodbye"]`,
  3136  	}, {
  3137  		name: jsontest.Name("Arrays/Bytes"),
  3138  		in:   [2][]byte{[]byte("hello"), []byte("goodbye")},
  3139  		want: `["aGVsbG8=","Z29vZGJ5ZQ=="]`,
  3140  	}, {
  3141  		name: jsontest.Name("Arrays/Int"),
  3142  		in:   [2]int64{math.MinInt64, math.MaxInt64},
  3143  		want: `[-9223372036854775808,9223372036854775807]`,
  3144  	}, {
  3145  		name: jsontest.Name("Arrays/Uint"),
  3146  		in:   [2]uint64{0, math.MaxUint64},
  3147  		want: `[0,18446744073709551615]`,
  3148  	}, {
  3149  		name: jsontest.Name("Arrays/Float"),
  3150  		in:   [2]float64{-math.MaxFloat64, +math.MaxFloat64},
  3151  		want: `[-1.7976931348623157e+308,1.7976931348623157e+308]`,
  3152  	}, {
  3153  		name:    jsontest.Name("Arrays/Invalid/Channel"),
  3154  		in:      new([1]chan string),
  3155  		want:    `[`,
  3156  		wantErr: EM(nil).withPos(`[`, "/0").withType(0, T[chan string]()),
  3157  	}, {
  3158  		name: jsontest.Name("Arrays/IgnoreInvalidFormat"),
  3159  		opts: []Options{invalidFormatOption},
  3160  		in:   [2]string{"hello", "goodbye"},
  3161  		want: `["hello","goodbye"]`,
  3162  	}, {
  3163  		name: jsontest.Name("Pointers/NilL0"),
  3164  		in:   (*int)(nil),
  3165  		want: `null`,
  3166  	}, {
  3167  		name: jsontest.Name("Pointers/NilL1"),
  3168  		in:   new(*int),
  3169  		want: `null`,
  3170  	}, {
  3171  		name: jsontest.Name("Pointers/Bool"),
  3172  		in:   addr(addr(bool(true))),
  3173  		want: `true`,
  3174  	}, {
  3175  		name: jsontest.Name("Pointers/String"),
  3176  		in:   addr(addr(string("string"))),
  3177  		want: `"string"`,
  3178  	}, {
  3179  		name: jsontest.Name("Pointers/Bytes"),
  3180  		in:   addr(addr([]byte("bytes"))),
  3181  		want: `"Ynl0ZXM="`,
  3182  	}, {
  3183  		name: jsontest.Name("Pointers/Int"),
  3184  		in:   addr(addr(int(-100))),
  3185  		want: `-100`,
  3186  	}, {
  3187  		name: jsontest.Name("Pointers/Uint"),
  3188  		in:   addr(addr(uint(100))),
  3189  		want: `100`,
  3190  	}, {
  3191  		name: jsontest.Name("Pointers/Float"),
  3192  		in:   addr(addr(float64(3.14159))),
  3193  		want: `3.14159`,
  3194  	}, {
  3195  		name: jsontest.Name("Pointers/CyclicPointer"),
  3196  		in: func() *recursivePointer {
  3197  			p := new(recursivePointer)
  3198  			p.P = p
  3199  			return p
  3200  		}(),
  3201  		want:    strings.Repeat(`{"P":`, startDetectingCyclesAfter) + `{"P"`,
  3202  		wantErr: EM(internal.ErrCycle).withPos(strings.Repeat(`{"P":`, startDetectingCyclesAfter+1), jsontext.Pointer(strings.Repeat("/P", startDetectingCyclesAfter+1))).withType(0, T[*recursivePointer]()),
  3203  	}, {
  3204  		name: jsontest.Name("Pointers/IgnoreInvalidFormat"),
  3205  		opts: []Options{invalidFormatOption},
  3206  		in:   addr(addr(bool(true))),
  3207  		want: `true`,
  3208  	}, {
  3209  		name: jsontest.Name("Interfaces/Nil/Empty"),
  3210  		in:   [1]any{nil},
  3211  		want: `[null]`,
  3212  	}, {
  3213  		name: jsontest.Name("Interfaces/Nil/NonEmpty"),
  3214  		in:   [1]io.Reader{nil},
  3215  		want: `[null]`,
  3216  	}, {
  3217  		name: jsontest.Name("Interfaces/IgnoreInvalidFormat"),
  3218  		opts: []Options{invalidFormatOption},
  3219  		in:   [1]io.Reader{nil},
  3220  		want: `[null]`,
  3221  	}, {
  3222  		name: jsontest.Name("Interfaces/Any"),
  3223  		in:   struct{ X any }{[]any{nil, false, "", 0.0, map[string]any{}, []any{}, [8]byte{}}},
  3224  		want: `{"X":[null,false,"",0,{},[],"AAAAAAAAAAA="]}`,
  3225  	}, {
  3226  		name: jsontest.Name("Interfaces/Any/Named"),
  3227  		in:   struct{ X namedAny }{[]namedAny{nil, false, "", 0.0, map[string]namedAny{}, []namedAny{}, [8]byte{}}},
  3228  		want: `{"X":[null,false,"",0,{},[],"AAAAAAAAAAA="]}`,
  3229  	}, {
  3230  		name: jsontest.Name("Interfaces/Any/Stringified"),
  3231  		opts: []Options{StringifyNumbers(true)},
  3232  		in:   struct{ X any }{0.0},
  3233  		want: `{"X":"0"}`,
  3234  	}, {
  3235  		name: jsontest.Name("Interfaces/Any/MarshalFunc/Any"),
  3236  		opts: []Options{
  3237  			WithMarshalers(MarshalFunc(func(v any) ([]byte, error) {
  3238  				return []byte(`"called"`), nil
  3239  			})),
  3240  		},
  3241  		in:   struct{ X any }{[]any{nil, false, "", 0.0, map[string]any{}, []any{}}},
  3242  		want: `"called"`,
  3243  	}, {
  3244  		name: jsontest.Name("Interfaces/Any/MarshalFunc/Bool"),
  3245  		opts: []Options{
  3246  			WithMarshalers(MarshalFunc(func(v bool) ([]byte, error) {
  3247  				return []byte(`"called"`), nil
  3248  			})),
  3249  		},
  3250  		in:   struct{ X any }{[]any{nil, false, "", 0.0, map[string]any{}, []any{}}},
  3251  		want: `{"X":[null,"called","",0,{},[]]}`,
  3252  	}, {
  3253  		name: jsontest.Name("Interfaces/Any/MarshalFunc/String"),
  3254  		opts: []Options{
  3255  			WithMarshalers(MarshalFunc(func(v string) ([]byte, error) {
  3256  				return []byte(`"called"`), nil
  3257  			})),
  3258  		},
  3259  		in:   struct{ X any }{[]any{nil, false, "", 0.0, map[string]any{}, []any{}}},
  3260  		want: `{"X":[null,false,"called",0,{},[]]}`,
  3261  	}, {
  3262  		name: jsontest.Name("Interfaces/Any/MarshalFunc/Float64"),
  3263  		opts: []Options{
  3264  			WithMarshalers(MarshalFunc(func(v float64) ([]byte, error) {
  3265  				return []byte(`"called"`), nil
  3266  			})),
  3267  		},
  3268  		in:   struct{ X any }{[]any{nil, false, "", 0.0, map[string]any{}, []any{}}},
  3269  		want: `{"X":[null,false,"","called",{},[]]}`,
  3270  	}, {
  3271  		name: jsontest.Name("Interfaces/Any/MarshalFunc/MapStringAny"),
  3272  		opts: []Options{
  3273  			WithMarshalers(MarshalFunc(func(v map[string]any) ([]byte, error) {
  3274  				return []byte(`"called"`), nil
  3275  			})),
  3276  		},
  3277  		in:   struct{ X any }{[]any{nil, false, "", 0.0, map[string]any{}, []any{}}},
  3278  		want: `{"X":[null,false,"",0,"called",[]]}`,
  3279  	}, {
  3280  		name: jsontest.Name("Interfaces/Any/MarshalFunc/SliceAny"),
  3281  		opts: []Options{
  3282  			WithMarshalers(MarshalFunc(func(v []any) ([]byte, error) {
  3283  				return []byte(`"called"`), nil
  3284  			})),
  3285  		},
  3286  		in:   struct{ X any }{[]any{nil, false, "", 0.0, map[string]any{}, []any{}}},
  3287  		want: `{"X":"called"}`,
  3288  	}, {
  3289  		name: jsontest.Name("Interfaces/Any/MarshalFunc/Bytes"),
  3290  		opts: []Options{
  3291  			WithMarshalers(MarshalFunc(func(v [8]byte) ([]byte, error) {
  3292  				return []byte(`"called"`), nil
  3293  			})),
  3294  		},
  3295  		in:   struct{ X any }{[8]byte{}},
  3296  		want: `{"X":"called"}`,
  3297  	}, {
  3298  		name:    jsontest.Name("Interfaces/Any/Float/NaN"),
  3299  		in:      struct{ X any }{math.NaN()},
  3300  		want:    `{"X"`,
  3301  		wantErr: EM(fmt.Errorf("unsupported value: %v", math.NaN())).withType(0, reflect.TypeFor[float64]()).withPos(`{"X":`, "/X"),
  3302  	}, {
  3303  		name: jsontest.Name("Interfaces/Any/Maps/Nil"),
  3304  		in:   struct{ X any }{map[string]any(nil)},
  3305  		want: `{"X":{}}`,
  3306  	}, {
  3307  		name: jsontest.Name("Interfaces/Any/Maps/Nil/FormatNilMapAsNull"),
  3308  		opts: []Options{FormatNilMapAsNull(true)},
  3309  		in:   struct{ X any }{map[string]any(nil)},
  3310  		want: `{"X":null}`,
  3311  	}, {
  3312  		name: jsontest.Name("Interfaces/Any/Maps/Empty"),
  3313  		in:   struct{ X any }{map[string]any{}},
  3314  		want: `{"X":{}}`,
  3315  	}, {
  3316  		name: jsontest.Name("Interfaces/Any/Maps/Empty/Multiline"),
  3317  		opts: []Options{jsontext.Multiline(true), jsontext.WithIndent("")},
  3318  		in:   struct{ X any }{map[string]any{}},
  3319  		want: "{\n\"X\": {}\n}",
  3320  	}, {
  3321  		name: jsontest.Name("Interfaces/Any/Maps/NonEmpty"),
  3322  		in:   struct{ X any }{map[string]any{"fizz": "buzz"}},
  3323  		want: `{"X":{"fizz":"buzz"}}`,
  3324  	}, {
  3325  		name: jsontest.Name("Interfaces/Any/Maps/Deterministic"),
  3326  		opts: []Options{Deterministic(true)},
  3327  		in:   struct{ X any }{map[string]any{"alpha": "", "bravo": ""}},
  3328  		want: `{"X":{"alpha":"","bravo":""}}`,
  3329  	}, {
  3330  		name:    jsontest.Name("Interfaces/Any/Maps/Deterministic+AllowInvalidUTF8+RejectDuplicateNames"),
  3331  		opts:    []Options{Deterministic(true), jsontext.AllowInvalidUTF8(true), jsontext.AllowDuplicateNames(false)},
  3332  		in:      struct{ X any }{map[string]any{"\xff": "", "\xfe": ""}},
  3333  		want:    `{"X":{"�":""`,
  3334  		wantErr: newDuplicateNameError("/X", []byte(`"�"`), len64(`{"X":{"�":"",`)),
  3335  	}, {
  3336  		name: jsontest.Name("Interfaces/Any/Maps/Deterministic+AllowInvalidUTF8+AllowDuplicateNames"),
  3337  		opts: []Options{Deterministic(true), jsontext.AllowInvalidUTF8(true), jsontext.AllowDuplicateNames(true)},
  3338  		in:   struct{ X any }{map[string]any{"\xff": "alpha", "\xfe": "bravo"}},
  3339  		want: `{"X":{"�":"bravo","�":"alpha"}}`,
  3340  	}, {
  3341  		name:    jsontest.Name("Interfaces/Any/Maps/RejectInvalidUTF8"),
  3342  		in:      struct{ X any }{map[string]any{"\xff": "", "\xfe": ""}},
  3343  		want:    `{"X":{`,
  3344  		wantErr: newInvalidUTF8Error(len64(`{"X":{`), "/X"),
  3345  	}, {
  3346  		name:    jsontest.Name("Interfaces/Any/Maps/AllowInvalidUTF8+RejectDuplicateNames"),
  3347  		opts:    []Options{jsontext.AllowInvalidUTF8(true)},
  3348  		in:      struct{ X any }{map[string]any{"\xff": "", "\xfe": ""}},
  3349  		want:    `{"X":{"�":""`,
  3350  		wantErr: newDuplicateNameError("/X", []byte(`"�"`), len64(`{"X":{"�":"",`)),
  3351  	}, {
  3352  		name: jsontest.Name("Interfaces/Any/Maps/AllowInvalidUTF8+AllowDuplicateNames"),
  3353  		opts: []Options{jsontext.AllowInvalidUTF8(true), jsontext.AllowDuplicateNames(true)},
  3354  		in:   struct{ X any }{map[string]any{"\xff": "", "\xfe": ""}},
  3355  		want: `{"X":{"�":"","�":""}}`,
  3356  	}, {
  3357  		name: jsontest.Name("Interfaces/Any/Maps/Cyclic"),
  3358  		in: func() any {
  3359  			m := map[string]any{}
  3360  			m[""] = m
  3361  			return struct{ X any }{m}
  3362  		}(),
  3363  		want:    `{"X"` + strings.Repeat(`:{""`, startDetectingCyclesAfter),
  3364  		wantErr: EM(internal.ErrCycle).withPos(`{"X":`+strings.Repeat(`{"":`, startDetectingCyclesAfter), "/X"+jsontext.Pointer(strings.Repeat("/", startDetectingCyclesAfter))).withType(0, T[map[string]any]()),
  3365  	}, {
  3366  		name: jsontest.Name("Interfaces/Any/Slices/Nil"),
  3367  		in:   struct{ X any }{[]any(nil)},
  3368  		want: `{"X":[]}`,
  3369  	}, {
  3370  		name: jsontest.Name("Interfaces/Any/Slices/Nil/FormatNilSliceAsNull"),
  3371  		opts: []Options{FormatNilSliceAsNull(true)},
  3372  		in:   struct{ X any }{[]any(nil)},
  3373  		want: `{"X":null}`,
  3374  	}, {
  3375  		name: jsontest.Name("Interfaces/Any/Slices/Empty"),
  3376  		in:   struct{ X any }{[]any{}},
  3377  		want: `{"X":[]}`,
  3378  	}, {
  3379  		name: jsontest.Name("Interfaces/Any/Slices/Empty/Multiline"),
  3380  		opts: []Options{jsontext.Multiline(true), jsontext.WithIndent("")},
  3381  		in:   struct{ X any }{[]any{}},
  3382  		want: "{\n\"X\": []\n}",
  3383  	}, {
  3384  		name: jsontest.Name("Interfaces/Any/Slices/NonEmpty"),
  3385  		in:   struct{ X any }{[]any{"fizz", "buzz"}},
  3386  		want: `{"X":["fizz","buzz"]}`,
  3387  	}, {
  3388  		name: jsontest.Name("Interfaces/Any/Slices/Cyclic"),
  3389  		in: func() any {
  3390  			s := make([]any, 1)
  3391  			s[0] = s
  3392  			return struct{ X any }{s}
  3393  		}(),
  3394  		want:    `{"X":` + strings.Repeat(`[`, startDetectingCyclesAfter),
  3395  		wantErr: EM(internal.ErrCycle).withPos(`{"X":`+strings.Repeat(`[`, startDetectingCyclesAfter), "/X"+jsontext.Pointer(strings.Repeat("/0", startDetectingCyclesAfter))).withType(0, T[[]any]()),
  3396  	}, {
  3397  		name: jsontest.Name("Methods/NilPointer"),
  3398  		in:   struct{ X *allMethods }{X: (*allMethods)(nil)}, // method should not be called
  3399  		want: `{"X":null}`,
  3400  	}, {
  3401  		// NOTE: Fixes https://github.com/dominikh/go-tools/issues/975.
  3402  		name: jsontest.Name("Methods/NilInterface"),
  3403  		in:   struct{ X MarshalerTo }{X: (*allMethods)(nil)}, // method should not be called
  3404  		want: `{"X":null}`,
  3405  	}, {
  3406  		name: jsontest.Name("Methods/AllMethods"),
  3407  		in:   struct{ X *allMethods }{X: &allMethods{method: "MarshalJSONTo", value: []byte(`"hello"`)}},
  3408  		want: `{"X":"hello"}`,
  3409  	}, {
  3410  		name: jsontest.Name("Methods/AllMethodsExceptJSONv2"),
  3411  		in:   struct{ X *allMethodsExceptJSONv2 }{X: &allMethodsExceptJSONv2{allMethods: allMethods{method: "MarshalJSON", value: []byte(`"hello"`)}}},
  3412  		want: `{"X":"hello"}`,
  3413  	}, {
  3414  		name: jsontest.Name("Methods/AllMethodsExceptJSONv1"),
  3415  		in:   struct{ X *allMethodsExceptJSONv1 }{X: &allMethodsExceptJSONv1{allMethods: allMethods{method: "MarshalJSONTo", value: []byte(`"hello"`)}}},
  3416  		want: `{"X":"hello"}`,
  3417  	}, {
  3418  		name: jsontest.Name("Methods/AllMethodsExceptText"),
  3419  		in:   struct{ X *allMethodsExceptText }{X: &allMethodsExceptText{allMethods: allMethods{method: "MarshalJSONTo", value: []byte(`"hello"`)}}},
  3420  		want: `{"X":"hello"}`,
  3421  	}, {
  3422  		name: jsontest.Name("Methods/OnlyMethodJSONv2"),
  3423  		in:   struct{ X *onlyMethodJSONv2 }{X: &onlyMethodJSONv2{allMethods: allMethods{method: "MarshalJSONTo", value: []byte(`"hello"`)}}},
  3424  		want: `{"X":"hello"}`,
  3425  	}, {
  3426  		name: jsontest.Name("Methods/OnlyMethodJSONv1"),
  3427  		in:   struct{ X *onlyMethodJSONv1 }{X: &onlyMethodJSONv1{allMethods: allMethods{method: "MarshalJSON", value: []byte(`"hello"`)}}},
  3428  		want: `{"X":"hello"}`,
  3429  	}, {
  3430  		name: jsontest.Name("Methods/OnlyMethodText"),
  3431  		in:   struct{ X *onlyMethodText }{X: &onlyMethodText{allMethods: allMethods{method: "MarshalText", value: []byte(`hello`)}}},
  3432  		want: `{"X":"hello"}`,
  3433  	}, {
  3434  		name: jsontest.Name("Methods/IP"),
  3435  		in:   net.IPv4(192, 168, 0, 100),
  3436  		want: `"192.168.0.100"`,
  3437  	}, {
  3438  		name: jsontest.Name("Methods/NetIP"),
  3439  		in: struct {
  3440  			Addr     netip.Addr
  3441  			AddrPort netip.AddrPort
  3442  			Prefix   netip.Prefix
  3443  		}{
  3444  			Addr:     netip.AddrFrom4([4]byte{1, 2, 3, 4}),
  3445  			AddrPort: netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 1234),
  3446  			Prefix:   netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 24),
  3447  		},
  3448  		want: `{"Addr":"1.2.3.4","AddrPort":"1.2.3.4:1234","Prefix":"1.2.3.4/24"}`,
  3449  	}, {
  3450  		// NOTE: Fixes https://go.dev/issue/46516.
  3451  		name: jsontest.Name("Methods/Anonymous"),
  3452  		in:   struct{ X struct{ allMethods } }{X: struct{ allMethods }{allMethods{method: "MarshalJSONTo", value: []byte(`"hello"`)}}},
  3453  		want: `{"X":"hello"}`,
  3454  	}, {
  3455  		// NOTE: Fixes https://go.dev/issue/22967.
  3456  		name: jsontest.Name("Methods/Addressable"),
  3457  		in: struct {
  3458  			V allMethods
  3459  			M map[string]allMethods
  3460  			I any
  3461  		}{
  3462  			V: allMethods{method: "MarshalJSONTo", value: []byte(`"hello"`)},
  3463  			M: map[string]allMethods{"K": {method: "MarshalJSONTo", value: []byte(`"hello"`)}},
  3464  			I: allMethods{method: "MarshalJSONTo", value: []byte(`"hello"`)},
  3465  		},
  3466  		want: `{"V":"hello","M":{"K":"hello"},"I":"hello"}`,
  3467  	}, {
  3468  		// NOTE: Fixes https://go.dev/issue/29732.
  3469  		name:         jsontest.Name("Methods/MapKey/JSONv2"),
  3470  		in:           map[structMethodJSONv2]string{{"k1"}: "v1", {"k2"}: "v2"},
  3471  		want:         `{"k1":"v1","k2":"v2"}`,
  3472  		canonicalize: true,
  3473  	}, {
  3474  		// NOTE: Fixes https://go.dev/issue/29732.
  3475  		name:         jsontest.Name("Methods/MapKey/JSONv1"),
  3476  		in:           map[structMethodJSONv1]string{{"k1"}: "v1", {"k2"}: "v2"},
  3477  		want:         `{"k1":"v1","k2":"v2"}`,
  3478  		canonicalize: true,
  3479  	}, {
  3480  		name:         jsontest.Name("Methods/MapKey/Text"),
  3481  		in:           map[structMethodText]string{{"k1"}: "v1", {"k2"}: "v2"},
  3482  		want:         `{"k1":"v1","k2":"v2"}`,
  3483  		canonicalize: true,
  3484  	}, {
  3485  		name: jsontest.Name("Methods/JSONv2/ErrUnsupported"),
  3486  		opts: []Options{Deterministic(true)},
  3487  		in:   unsupportedMethodJSONv2{"fizz": 123},
  3488  		want: `{"called":1,"fizz":123}`,
  3489  	}, {
  3490  		name: jsontest.Name("Methods/Invalid/JSONv2/Error"),
  3491  		in: marshalJSONv2Func(func(*jsontext.Encoder) error {
  3492  			return errSomeError
  3493  		}),
  3494  		wantErr: EM(errSomeError).withType(0, T[marshalJSONv2Func]()),
  3495  	}, {
  3496  		name: jsontest.Name("Methods/Invalid/JSONv2/TooFew"),
  3497  		in: marshalJSONv2Func(func(*jsontext.Encoder) error {
  3498  			return nil // do nothing
  3499  		}),
  3500  		wantErr: EM(errNonSingularValue).withType(0, T[marshalJSONv2Func]()),
  3501  	}, {
  3502  		name: jsontest.Name("Methods/Invalid/JSONv2/TooMany"),
  3503  		in: marshalJSONv2Func(func(enc *jsontext.Encoder) error {
  3504  			enc.WriteToken(jsontext.Null)
  3505  			enc.WriteToken(jsontext.Null)
  3506  			return nil
  3507  		}),
  3508  		want:    `nullnull`,
  3509  		wantErr: EM(errNonSingularValue).withPos(`nullnull`, "").withType(0, T[marshalJSONv2Func]()),
  3510  	}, {
  3511  		name: jsontest.Name("Methods/Invalid/JSONv2/ErrUnsupported"),
  3512  		in: marshalJSONv2Func(func(enc *jsontext.Encoder) error {
  3513  			return errors.ErrUnsupported
  3514  		}),
  3515  		wantErr: EM(nil).withType(0, T[marshalJSONv2Func]()),
  3516  	}, {
  3517  		name: jsontest.Name("Methods/Invalid/JSONv1/Error"),
  3518  		in: marshalJSONv1Func(func() ([]byte, error) {
  3519  			return nil, errSomeError
  3520  		}),
  3521  		wantErr: EM(errSomeError).withType(0, T[marshalJSONv1Func]()),
  3522  	}, {
  3523  		name: jsontest.Name("Methods/Invalid/JSONv1/Syntax"),
  3524  		in: marshalJSONv1Func(func() ([]byte, error) {
  3525  			return []byte("invalid"), nil
  3526  		}),
  3527  		wantErr: EM(newInvalidCharacterError("i", "at start of value", 0, "")).withType(0, T[marshalJSONv1Func]()),
  3528  	}, {
  3529  		name: jsontest.Name("Methods/Invalid/JSONv1/ErrUnsupported"),
  3530  		in: marshalJSONv1Func(func() ([]byte, error) {
  3531  			return nil, errors.ErrUnsupported
  3532  		}),
  3533  		wantErr: EM(errors.New("MarshalJSON method may not return errors.ErrUnsupported")).withType(0, T[marshalJSONv1Func]()),
  3534  	}, {
  3535  		name: jsontest.Name("Methods/AppendText"),
  3536  		in:   appendTextFunc(func(b []byte) ([]byte, error) { return append(b, "hello"...), nil }),
  3537  		want: `"hello"`,
  3538  	}, {
  3539  		name:    jsontest.Name("Methods/AppendText/Error"),
  3540  		in:      appendTextFunc(func(b []byte) ([]byte, error) { return append(b, "hello"...), errSomeError }),
  3541  		wantErr: EM(errSomeError).withType(0, T[appendTextFunc]()),
  3542  	}, {
  3543  		name: jsontest.Name("Methods/AppendText/NeedEscape"),
  3544  		in:   appendTextFunc(func(b []byte) ([]byte, error) { return append(b, `"`...), nil }),
  3545  		want: `"\""`,
  3546  	}, {
  3547  		name:    jsontest.Name("Methods/AppendText/RejectInvalidUTF8"),
  3548  		in:      appendTextFunc(func(b []byte) ([]byte, error) { return append(b, "\xde\xad\xbe\xef"...), nil }),
  3549  		wantErr: EM(newInvalidUTF8Error(0, "")).withType(0, T[appendTextFunc]()),
  3550  	}, {
  3551  		name: jsontest.Name("Methods/AppendText/AllowInvalidUTF8"),
  3552  		opts: []Options{jsontext.AllowInvalidUTF8(true)},
  3553  		in:   appendTextFunc(func(b []byte) ([]byte, error) { return append(b, "\xde\xad\xbe\xef"...), nil }),
  3554  		want: "\"\xde\xad\ufffd\ufffd\"",
  3555  	}, {
  3556  		name: jsontest.Name("Methods/Invalid/Text/Error"),
  3557  		in: marshalTextFunc(func() ([]byte, error) {
  3558  			return nil, errSomeError
  3559  		}),
  3560  		wantErr: EM(errSomeError).withType(0, T[marshalTextFunc]()),
  3561  	}, {
  3562  		name: jsontest.Name("Methods/Text/RejectInvalidUTF8"),
  3563  		in: marshalTextFunc(func() ([]byte, error) {
  3564  			return []byte("\xde\xad\xbe\xef"), nil
  3565  		}),
  3566  		wantErr: EM(newInvalidUTF8Error(0, "")).withType(0, T[marshalTextFunc]()),
  3567  	}, {
  3568  		name: jsontest.Name("Methods/Text/AllowInvalidUTF8"),
  3569  		opts: []Options{jsontext.AllowInvalidUTF8(true)},
  3570  		in: marshalTextFunc(func() ([]byte, error) {
  3571  			return []byte("\xde\xad\xbe\xef"), nil
  3572  		}),
  3573  		want: "\"\xde\xad\ufffd\ufffd\"",
  3574  	}, {
  3575  		name: jsontest.Name("Methods/Invalid/Text/ErrUnsupported"),
  3576  		in: marshalTextFunc(func() ([]byte, error) {
  3577  			return nil, errors.ErrUnsupported
  3578  		}),
  3579  		wantErr: EM(wrapErrUnsupported(errors.ErrUnsupported, "MarshalText method")).withType(0, T[marshalTextFunc]()),
  3580  	}, {
  3581  		name: jsontest.Name("Methods/Invalid/MapKey/JSONv2/Syntax"),
  3582  		in: map[any]string{
  3583  			addr(marshalJSONv2Func(func(enc *jsontext.Encoder) error {
  3584  				return enc.WriteToken(jsontext.Null)
  3585  			})): "invalid",
  3586  		},
  3587  		want:    `{`,
  3588  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, T[marshalJSONv2Func]()),
  3589  	}, {
  3590  		name: jsontest.Name("Methods/Invalid/MapKey/JSONv1/Syntax"),
  3591  		in: map[any]string{
  3592  			addr(marshalJSONv1Func(func() ([]byte, error) {
  3593  				return []byte(`null`), nil
  3594  			})): "invalid",
  3595  		},
  3596  		want:    `{`,
  3597  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, T[marshalJSONv1Func]()),
  3598  	}, {
  3599  		name: jsontest.Name("Functions/Bool/V1"),
  3600  		opts: []Options{
  3601  			WithMarshalers(MarshalFunc(func(bool) ([]byte, error) {
  3602  				return []byte(`"called"`), nil
  3603  			})),
  3604  		},
  3605  		in:   true,
  3606  		want: `"called"`,
  3607  	}, {
  3608  		name: jsontest.Name("Functions/Bool/Empty"),
  3609  		opts: []Options{WithMarshalers(nil)},
  3610  		in:   true,
  3611  		want: `true`,
  3612  	}, {
  3613  		name: jsontest.Name("Functions/NamedBool/V1/NoMatch"),
  3614  		opts: []Options{
  3615  			WithMarshalers(MarshalFunc(func(namedBool) ([]byte, error) {
  3616  				return nil, errMustNotCall
  3617  			})),
  3618  		},
  3619  		in:   true,
  3620  		want: `true`,
  3621  	}, {
  3622  		name: jsontest.Name("Functions/NamedBool/V1/Match"),
  3623  		opts: []Options{
  3624  			WithMarshalers(MarshalFunc(func(namedBool) ([]byte, error) {
  3625  				return []byte(`"called"`), nil
  3626  			})),
  3627  		},
  3628  		in:   namedBool(true),
  3629  		want: `"called"`,
  3630  	}, {
  3631  		name: jsontest.Name("Functions/PointerBool/V1/Match"),
  3632  		opts: []Options{
  3633  			WithMarshalers(MarshalFunc(func(v *bool) ([]byte, error) {
  3634  				_ = *v // must be a non-nil pointer
  3635  				return []byte(`"called"`), nil
  3636  			})),
  3637  		},
  3638  		in:   true,
  3639  		want: `"called"`,
  3640  	}, {
  3641  		name: jsontest.Name("Functions/Bool/V2"),
  3642  		opts: []Options{
  3643  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  3644  				return enc.WriteToken(jsontext.String("called"))
  3645  			})),
  3646  		},
  3647  		in:   true,
  3648  		want: `"called"`,
  3649  	}, {
  3650  		name: jsontest.Name("Functions/NamedBool/V2/NoMatch"),
  3651  		opts: []Options{
  3652  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v namedBool) error {
  3653  				return errMustNotCall
  3654  			})),
  3655  		},
  3656  		in:   true,
  3657  		want: `true`,
  3658  	}, {
  3659  		name: jsontest.Name("Functions/NamedBool/V2/Match"),
  3660  		opts: []Options{
  3661  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v namedBool) error {
  3662  				return enc.WriteToken(jsontext.String("called"))
  3663  			})),
  3664  		},
  3665  		in:   namedBool(true),
  3666  		want: `"called"`,
  3667  	}, {
  3668  		name: jsontest.Name("Functions/PointerBool/V2/Match"),
  3669  		opts: []Options{
  3670  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v *bool) error {
  3671  				_ = *v // must be a non-nil pointer
  3672  				return enc.WriteToken(jsontext.String("called"))
  3673  			})),
  3674  		},
  3675  		in:   true,
  3676  		want: `"called"`,
  3677  	}, {
  3678  		name: jsontest.Name("Functions/Bool/Empty1/NoMatch"),
  3679  		opts: []Options{
  3680  			WithMarshalers(new(Marshalers)),
  3681  		},
  3682  		in:   true,
  3683  		want: `true`,
  3684  	}, {
  3685  		name: jsontest.Name("Functions/Bool/Empty2/NoMatch"),
  3686  		opts: []Options{
  3687  			WithMarshalers(JoinMarshalers()),
  3688  		},
  3689  		in:   true,
  3690  		want: `true`,
  3691  	}, {
  3692  		name: jsontest.Name("Functions/Bool/V1/DirectError"),
  3693  		opts: []Options{
  3694  			WithMarshalers(MarshalFunc(func(bool) ([]byte, error) {
  3695  				return nil, errSomeError
  3696  			})),
  3697  		},
  3698  		in:      true,
  3699  		wantErr: EM(errSomeError).withType(0, T[bool]()),
  3700  	}, {
  3701  		name: jsontest.Name("Functions/Bool/V1/SkipError"),
  3702  		opts: []Options{
  3703  			WithMarshalers(MarshalFunc(func(bool) ([]byte, error) {
  3704  				return nil, errors.ErrUnsupported
  3705  			})),
  3706  		},
  3707  		in:      true,
  3708  		wantErr: EM(wrapErrUnsupported(errors.ErrUnsupported, "marshal function of type func(T) ([]byte, error)")).withType(0, T[bool]()),
  3709  	}, {
  3710  		name: jsontest.Name("Functions/Bool/V1/InvalidValue"),
  3711  		opts: []Options{
  3712  			WithMarshalers(MarshalFunc(func(bool) ([]byte, error) {
  3713  				return []byte("invalid"), nil
  3714  			})),
  3715  		},
  3716  		in:      true,
  3717  		wantErr: EM(newInvalidCharacterError("i", "at start of value", 0, "")).withType(0, T[bool]()),
  3718  	}, {
  3719  		name: jsontest.Name("Functions/Bool/V2/DirectError"),
  3720  		opts: []Options{
  3721  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  3722  				return errSomeError
  3723  			})),
  3724  		},
  3725  		in:      true,
  3726  		wantErr: EM(errSomeError).withType(0, T[bool]()),
  3727  	}, {
  3728  		name: jsontest.Name("Functions/Bool/V2/TooFew"),
  3729  		opts: []Options{
  3730  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  3731  				return nil
  3732  			})),
  3733  		},
  3734  		in:      true,
  3735  		wantErr: EM(errNonSingularValue).withType(0, T[bool]()),
  3736  	}, {
  3737  		name: jsontest.Name("Functions/Bool/V2/TooMany"),
  3738  		opts: []Options{
  3739  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  3740  				enc.WriteValue([]byte(`"hello"`))
  3741  				enc.WriteValue([]byte(`"world"`))
  3742  				return nil
  3743  			})),
  3744  		},
  3745  		in:      true,
  3746  		want:    `"hello""world"`,
  3747  		wantErr: EM(errNonSingularValue).withPos(`"hello""world"`, "").withType(0, T[bool]()),
  3748  	}, {
  3749  		name: jsontest.Name("Functions/Bool/V2/Skipped"),
  3750  		opts: []Options{
  3751  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  3752  				return errors.ErrUnsupported
  3753  			})),
  3754  		},
  3755  		in:   true,
  3756  		want: `true`,
  3757  	}, {
  3758  		name: jsontest.Name("Functions/Bool/V2/ProcessBeforeSkip"),
  3759  		opts: []Options{
  3760  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  3761  				enc.WriteValue([]byte(`"hello"`))
  3762  				return errors.ErrUnsupported
  3763  			})),
  3764  		},
  3765  		in:      true,
  3766  		want:    `"hello"`,
  3767  		wantErr: EM(errUnsupportedMutation).withPos(`"hello"`, "").withType(0, T[bool]()),
  3768  	}, {
  3769  		name: jsontest.Name("Functions/Bool/V2/WrappedUnsupportedError"),
  3770  		opts: []Options{
  3771  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  3772  				return fmt.Errorf("wrap: %w", errors.ErrUnsupported)
  3773  			})),
  3774  		},
  3775  		in:   true,
  3776  		want: `true`,
  3777  	}, {
  3778  		name: jsontest.Name("Functions/Map/Key/NoCaseString/V1"),
  3779  		opts: []Options{
  3780  			WithMarshalers(MarshalFunc(func(v nocaseString) ([]byte, error) {
  3781  				return []byte(`"called"`), nil
  3782  			})),
  3783  		},
  3784  		in:   map[nocaseString]string{"hello": "world"},
  3785  		want: `{"called":"world"}`,
  3786  	}, {
  3787  		name: jsontest.Name("Functions/Map/Key/PointerNoCaseString/V1"),
  3788  		opts: []Options{
  3789  			WithMarshalers(MarshalFunc(func(v *nocaseString) ([]byte, error) {
  3790  				_ = *v // must be a non-nil pointer
  3791  				return []byte(`"called"`), nil
  3792  			})),
  3793  		},
  3794  		in:   map[nocaseString]string{"hello": "world"},
  3795  		want: `{"called":"world"}`,
  3796  	}, {
  3797  		name: jsontest.Name("Functions/Map/Key/TextMarshaler/V1"),
  3798  		opts: []Options{
  3799  			WithMarshalers(MarshalFunc(func(v encoding.TextMarshaler) ([]byte, error) {
  3800  				_ = *v.(*nocaseString) // must be a non-nil *nocaseString
  3801  				return []byte(`"called"`), nil
  3802  			})),
  3803  		},
  3804  		in:   map[nocaseString]string{"hello": "world"},
  3805  		want: `{"called":"world"}`,
  3806  	}, {
  3807  		name: jsontest.Name("Functions/Map/Key/NoCaseString/V1/InvalidValue"),
  3808  		opts: []Options{
  3809  			WithMarshalers(MarshalFunc(func(v nocaseString) ([]byte, error) {
  3810  				return []byte(`null`), nil
  3811  			})),
  3812  		},
  3813  		in:      map[nocaseString]string{"hello": "world"},
  3814  		want:    `{`,
  3815  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, T[nocaseString]()),
  3816  	}, {
  3817  		name: jsontest.Name("Functions/Map/Key/NoCaseString/V2/InvalidKind"),
  3818  		opts: []Options{
  3819  			WithMarshalers(MarshalFunc(func(v nocaseString) ([]byte, error) {
  3820  				return []byte(`null`), nil
  3821  			})),
  3822  		},
  3823  		in:      map[nocaseString]string{"hello": "world"},
  3824  		want:    `{`,
  3825  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, T[nocaseString]()),
  3826  	}, {
  3827  		name: jsontest.Name("Functions/Map/Key/String/V1/DuplicateName"),
  3828  		opts: []Options{
  3829  			WithMarshalers(MarshalFunc(func(v string) ([]byte, error) {
  3830  				return []byte(`"name"`), nil
  3831  			})),
  3832  		},
  3833  		in:   map[string]string{"name1": "value", "name2": "value"},
  3834  		want: `{"name":"name"`,
  3835  		wantErr: EM(newDuplicateNameError("", []byte(`"name"`), len64(`{"name":"name",`))).
  3836  			withPos(`{"name":"name",`, "").withType(0, T[string]()),
  3837  	}, {
  3838  		name: jsontest.Name("Functions/Map/Key/NoCaseString/V2"),
  3839  		opts: []Options{
  3840  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v nocaseString) error {
  3841  				return enc.WriteValue([]byte(`"called"`))
  3842  			})),
  3843  		},
  3844  		in:   map[nocaseString]string{"hello": "world"},
  3845  		want: `{"called":"world"}`,
  3846  	}, {
  3847  		name: jsontest.Name("Functions/Map/Key/PointerNoCaseString/V2"),
  3848  		opts: []Options{
  3849  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v *nocaseString) error {
  3850  				_ = *v // must be a non-nil pointer
  3851  				return enc.WriteValue([]byte(`"called"`))
  3852  			})),
  3853  		},
  3854  		in:   map[nocaseString]string{"hello": "world"},
  3855  		want: `{"called":"world"}`,
  3856  	}, {
  3857  		name: jsontest.Name("Functions/Map/Key/TextMarshaler/V2"),
  3858  		opts: []Options{
  3859  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v encoding.TextMarshaler) error {
  3860  				_ = *v.(*nocaseString) // must be a non-nil *nocaseString
  3861  				return enc.WriteValue([]byte(`"called"`))
  3862  			})),
  3863  		},
  3864  		in:   map[nocaseString]string{"hello": "world"},
  3865  		want: `{"called":"world"}`,
  3866  	}, {
  3867  		name: jsontest.Name("Functions/Map/Key/NoCaseString/V2/InvalidToken"),
  3868  		opts: []Options{
  3869  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v nocaseString) error {
  3870  				return enc.WriteToken(jsontext.Null)
  3871  			})),
  3872  		},
  3873  		in:      map[nocaseString]string{"hello": "world"},
  3874  		want:    `{`,
  3875  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, T[nocaseString]()),
  3876  	}, {
  3877  		name: jsontest.Name("Functions/Map/Key/NoCaseString/V2/InvalidValue"),
  3878  		opts: []Options{
  3879  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v nocaseString) error {
  3880  				return enc.WriteValue([]byte(`null`))
  3881  			})),
  3882  		},
  3883  		in:      map[nocaseString]string{"hello": "world"},
  3884  		want:    `{`,
  3885  		wantErr: EM(newNonStringNameError(len64(`{`), "")).withPos(`{`, "").withType(0, T[nocaseString]()),
  3886  	}, {
  3887  		name: jsontest.Name("Functions/Map/Value/NoCaseString/V1"),
  3888  		opts: []Options{
  3889  			WithMarshalers(MarshalFunc(func(v nocaseString) ([]byte, error) {
  3890  				return []byte(`"called"`), nil
  3891  			})),
  3892  		},
  3893  		in:   map[string]nocaseString{"hello": "world"},
  3894  		want: `{"hello":"called"}`,
  3895  	}, {
  3896  		name: jsontest.Name("Functions/Map/Value/PointerNoCaseString/V1"),
  3897  		opts: []Options{
  3898  			WithMarshalers(MarshalFunc(func(v *nocaseString) ([]byte, error) {
  3899  				_ = *v // must be a non-nil pointer
  3900  				return []byte(`"called"`), nil
  3901  			})),
  3902  		},
  3903  		in:   map[string]nocaseString{"hello": "world"},
  3904  		want: `{"hello":"called"}`,
  3905  	}, {
  3906  		name: jsontest.Name("Functions/Map/Value/TextMarshaler/V1"),
  3907  		opts: []Options{
  3908  			WithMarshalers(MarshalFunc(func(v encoding.TextMarshaler) ([]byte, error) {
  3909  				_ = *v.(*nocaseString) // must be a non-nil *nocaseString
  3910  				return []byte(`"called"`), nil
  3911  			})),
  3912  		},
  3913  		in:   map[string]nocaseString{"hello": "world"},
  3914  		want: `{"hello":"called"}`,
  3915  	}, {
  3916  		name: jsontest.Name("Functions/Map/Value/NoCaseString/V2"),
  3917  		opts: []Options{
  3918  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v nocaseString) error {
  3919  				return enc.WriteValue([]byte(`"called"`))
  3920  			})),
  3921  		},
  3922  		in:   map[string]nocaseString{"hello": "world"},
  3923  		want: `{"hello":"called"}`,
  3924  	}, {
  3925  		name: jsontest.Name("Functions/Map/Value/PointerNoCaseString/V2"),
  3926  		opts: []Options{
  3927  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v *nocaseString) error {
  3928  				_ = *v // must be a non-nil pointer
  3929  				return enc.WriteValue([]byte(`"called"`))
  3930  			})),
  3931  		},
  3932  		in:   map[string]nocaseString{"hello": "world"},
  3933  		want: `{"hello":"called"}`,
  3934  	}, {
  3935  		name: jsontest.Name("Functions/Map/Value/TextMarshaler/V2"),
  3936  		opts: []Options{
  3937  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v encoding.TextMarshaler) error {
  3938  				_ = *v.(*nocaseString) // must be a non-nil *nocaseString
  3939  				return enc.WriteValue([]byte(`"called"`))
  3940  			})),
  3941  		},
  3942  		in:   map[string]nocaseString{"hello": "world"},
  3943  		want: `{"hello":"called"}`,
  3944  	}, {
  3945  		name: jsontest.Name("Funtions/Struct/Fields"),
  3946  		opts: []Options{
  3947  			WithMarshalers(JoinMarshalers(
  3948  				MarshalFunc(func(v bool) ([]byte, error) {
  3949  					return []byte(`"called1"`), nil
  3950  				}),
  3951  				MarshalFunc(func(v *string) ([]byte, error) {
  3952  					return []byte(`"called2"`), nil
  3953  				}),
  3954  				MarshalToFunc(func(enc *jsontext.Encoder, v []byte) error {
  3955  					return enc.WriteValue([]byte(`"called3"`))
  3956  				}),
  3957  				MarshalToFunc(func(enc *jsontext.Encoder, v *int64) error {
  3958  					return enc.WriteValue([]byte(`"called4"`))
  3959  				}),
  3960  			)),
  3961  		},
  3962  		in:   structScalars{},
  3963  		want: `{"Bool":"called1","String":"called2","Bytes":"called3","Int":"called4","Uint":0,"Float":0}`,
  3964  	}, {
  3965  		name: jsontest.Name("Functions/Struct/OmitEmpty"),
  3966  		opts: []Options{
  3967  			WithMarshalers(JoinMarshalers(
  3968  				MarshalFunc(func(v bool) ([]byte, error) {
  3969  					return []byte(`null`), nil
  3970  				}),
  3971  				MarshalFunc(func(v string) ([]byte, error) {
  3972  					return []byte(`"called1"`), nil
  3973  				}),
  3974  				MarshalFunc(func(v *stringMarshalNonEmpty) ([]byte, error) {
  3975  					return []byte(`""`), nil
  3976  				}),
  3977  				MarshalToFunc(func(enc *jsontext.Encoder, v bytesMarshalNonEmpty) error {
  3978  					return enc.WriteValue([]byte(`{}`))
  3979  				}),
  3980  				MarshalToFunc(func(enc *jsontext.Encoder, v *float64) error {
  3981  					return enc.WriteValue([]byte(`[]`))
  3982  				}),
  3983  				MarshalFunc(func(v mapMarshalNonEmpty) ([]byte, error) {
  3984  					return []byte(`"called2"`), nil
  3985  				}),
  3986  				MarshalFunc(func(v []string) ([]byte, error) {
  3987  					return []byte(`"called3"`), nil
  3988  				}),
  3989  				MarshalToFunc(func(enc *jsontext.Encoder, v *sliceMarshalNonEmpty) error {
  3990  					return enc.WriteValue([]byte(`"called4"`))
  3991  				}),
  3992  			)),
  3993  		},
  3994  		in:   structOmitEmptyAll{},
  3995  		want: `{"String":"called1","MapNonEmpty":"called2","Slice":"called3","SliceNonEmpty":"called4"}`,
  3996  	}, {
  3997  		name: jsontest.Name("Functions/Struct/OmitZero"),
  3998  		opts: []Options{
  3999  			WithMarshalers(JoinMarshalers(
  4000  				MarshalFunc(func(v bool) ([]byte, error) {
  4001  					panic("should not be called")
  4002  				}),
  4003  				MarshalFunc(func(v *string) ([]byte, error) {
  4004  					panic("should not be called")
  4005  				}),
  4006  				MarshalToFunc(func(enc *jsontext.Encoder, v []byte) error {
  4007  					panic("should not be called")
  4008  				}),
  4009  				MarshalToFunc(func(enc *jsontext.Encoder, v *int64) error {
  4010  					panic("should not be called")
  4011  				}),
  4012  			)),
  4013  		},
  4014  		in:   structOmitZeroAll{},
  4015  		want: `{}`,
  4016  	}, {
  4017  		name: jsontest.Name("Functions/Struct/Embedded"),
  4018  		opts: []Options{
  4019  			WithMarshalers(JoinMarshalers(
  4020  				MarshalFunc(func(v structEmbeddedL1) ([]byte, error) {
  4021  					panic("should not be called")
  4022  				}),
  4023  				MarshalToFunc(func(enc *jsontext.Encoder, v *StructEmbed2) error {
  4024  					panic("should not be called")
  4025  				}),
  4026  			)),
  4027  		},
  4028  		in:   structEmbedded{},
  4029  		want: `{"D":""}`,
  4030  	}, {
  4031  		name: jsontest.Name("Functions/Slice/Elem"),
  4032  		opts: []Options{
  4033  			WithMarshalers(MarshalFunc(func(v bool) ([]byte, error) {
  4034  				return []byte(`"` + strconv.FormatBool(v) + `"`), nil
  4035  			})),
  4036  		},
  4037  		in:   []bool{true, false},
  4038  		want: `["true","false"]`,
  4039  	}, {
  4040  		name: jsontest.Name("Functions/Array/Elem"),
  4041  		opts: []Options{
  4042  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v *bool) error {
  4043  				return enc.WriteValue([]byte(`"` + strconv.FormatBool(*v) + `"`))
  4044  			})),
  4045  		},
  4046  		in:   [2]bool{true, false},
  4047  		want: `["true","false"]`,
  4048  	}, {
  4049  		name: jsontest.Name("Functions/Pointer/Nil"),
  4050  		opts: []Options{
  4051  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v *bool) error {
  4052  				panic("should not be called")
  4053  			})),
  4054  		},
  4055  		in:   struct{ X *bool }{nil},
  4056  		want: `{"X":null}`,
  4057  	}, {
  4058  		name: jsontest.Name("Functions/Pointer/NonNil"),
  4059  		opts: []Options{
  4060  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v *bool) error {
  4061  				return enc.WriteValue([]byte(`"called"`))
  4062  			})),
  4063  		},
  4064  		in:   struct{ X *bool }{addr(false)},
  4065  		want: `{"X":"called"}`,
  4066  	}, {
  4067  		name: jsontest.Name("Functions/Interface/Nil"),
  4068  		opts: []Options{
  4069  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v fmt.Stringer) error {
  4070  				panic("should not be called")
  4071  			})),
  4072  		},
  4073  		in:   struct{ X fmt.Stringer }{nil},
  4074  		want: `{"X":null}`,
  4075  	}, {
  4076  		name: jsontest.Name("Functions/Interface/NonNil/MatchInterface"),
  4077  		opts: []Options{
  4078  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v fmt.Stringer) error {
  4079  				return enc.WriteValue([]byte(`"called"`))
  4080  			})),
  4081  		},
  4082  		in:   struct{ X fmt.Stringer }{valueStringer{}},
  4083  		want: `{"X":"called"}`,
  4084  	}, {
  4085  		name: jsontest.Name("Functions/Interface/NonNil/MatchConcrete"),
  4086  		opts: []Options{
  4087  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v valueStringer) error {
  4088  				return enc.WriteValue([]byte(`"called"`))
  4089  			})),
  4090  		},
  4091  		in:   struct{ X fmt.Stringer }{valueStringer{}},
  4092  		want: `{"X":"called"}`,
  4093  	}, {
  4094  		name: jsontest.Name("Functions/Interface/NonNil/MatchPointer"),
  4095  		opts: []Options{
  4096  			WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, v *valueStringer) error {
  4097  				return enc.WriteValue([]byte(`"called"`))
  4098  			})),
  4099  		},
  4100  		in:   struct{ X fmt.Stringer }{valueStringer{}},
  4101  		want: `{"X":"called"}`,
  4102  	}, {
  4103  		name: jsontest.Name("Functions/Interface/Any"),
  4104  		opts: []Options{
  4105  			WithMarshalers(func() *Marshalers {
  4106  				type P struct {
  4107  					D int
  4108  					N int64
  4109  				}
  4110  				type PV struct {
  4111  					P P
  4112  					V any
  4113  				}
  4114  
  4115  				var lastChecks []func() error
  4116  				checkLast := func() error {
  4117  					for _, fn := range lastChecks {
  4118  						if err := fn(); err != nil {
  4119  							return err
  4120  						}
  4121  					}
  4122  					return errors.ErrUnsupported
  4123  				}
  4124  				makeValueChecker := func(name string, want []PV) func(e *jsontext.Encoder, v any) error {
  4125  					checkNext := func(e *jsontext.Encoder, v any) error {
  4126  						xe := export.Encoder(e)
  4127  						p := P{len(xe.Tokens.Stack), xe.Tokens.Last.Length()}
  4128  						rv := reflect.ValueOf(v)
  4129  						pv := PV{p, v}
  4130  						switch {
  4131  						case len(want) == 0:
  4132  							return fmt.Errorf("%s: %v: got more values than expected", name, p)
  4133  						case !rv.IsValid() || rv.Kind() != reflect.Pointer || rv.IsNil():
  4134  							return fmt.Errorf("%s: %v: got %#v, want non-nil pointer type", name, p, v)
  4135  						case !reflect.DeepEqual(pv, want[0]):
  4136  							return fmt.Errorf("%s:\n\tgot  %#v\n\twant %#v", name, pv, want[0])
  4137  						default:
  4138  							want = want[1:]
  4139  							return errors.ErrUnsupported
  4140  						}
  4141  					}
  4142  					lastChecks = append(lastChecks, func() error {
  4143  						if len(want) > 0 {
  4144  							return fmt.Errorf("%s: did not get enough values, want %d more", name, len(want))
  4145  						}
  4146  						return nil
  4147  					})
  4148  					return checkNext
  4149  				}
  4150  				makePositionChecker := func(name string, want []P) func(e *jsontext.Encoder, v any) error {
  4151  					checkNext := func(e *jsontext.Encoder, v any) error {
  4152  						xe := export.Encoder(e)
  4153  						p := P{len(xe.Tokens.Stack), xe.Tokens.Last.Length()}
  4154  						switch {
  4155  						case len(want) == 0:
  4156  							return fmt.Errorf("%s: %v: got more values than wanted", name, p)
  4157  						case p != want[0]:
  4158  							return fmt.Errorf("%s: got %v, want %v", name, p, want[0])
  4159  						default:
  4160  							want = want[1:]
  4161  							return errors.ErrUnsupported
  4162  						}
  4163  					}
  4164  					lastChecks = append(lastChecks, func() error {
  4165  						if len(want) > 0 {
  4166  							return fmt.Errorf("%s: did not get enough values, want %d more", name, len(want))
  4167  						}
  4168  						return nil
  4169  					})
  4170  					return checkNext
  4171  				}
  4172  
  4173  				wantAny := []PV{
  4174  					{P{0, 0}, addr([]any{
  4175  						nil,
  4176  						valueStringer{},
  4177  						(*valueStringer)(nil),
  4178  						addr(valueStringer{}),
  4179  						(**valueStringer)(nil),
  4180  						addr((*valueStringer)(nil)),
  4181  						addr(addr(valueStringer{})),
  4182  						pointerStringer{},
  4183  						(*pointerStringer)(nil),
  4184  						addr(pointerStringer{}),
  4185  						(**pointerStringer)(nil),
  4186  						addr((*pointerStringer)(nil)),
  4187  						addr(addr(pointerStringer{})),
  4188  						"LAST",
  4189  					})},
  4190  					{P{1, 0}, addr(any(nil))},
  4191  					{P{1, 1}, addr(any(valueStringer{}))},
  4192  					{P{1, 1}, addr(valueStringer{})},
  4193  					{P{1, 2}, addr(any((*valueStringer)(nil)))},
  4194  					{P{1, 2}, addr((*valueStringer)(nil))},
  4195  					{P{1, 3}, addr(any(addr(valueStringer{})))},
  4196  					{P{1, 3}, addr(addr(valueStringer{}))},
  4197  					{P{1, 3}, addr(valueStringer{})},
  4198  					{P{1, 4}, addr(any((**valueStringer)(nil)))},
  4199  					{P{1, 4}, addr((**valueStringer)(nil))},
  4200  					{P{1, 5}, addr(any(addr((*valueStringer)(nil))))},
  4201  					{P{1, 5}, addr(addr((*valueStringer)(nil)))},
  4202  					{P{1, 5}, addr((*valueStringer)(nil))},
  4203  					{P{1, 6}, addr(any(addr(addr(valueStringer{}))))},
  4204  					{P{1, 6}, addr(addr(addr(valueStringer{})))},
  4205  					{P{1, 6}, addr(addr(valueStringer{}))},
  4206  					{P{1, 6}, addr(valueStringer{})},
  4207  					{P{1, 7}, addr(any(pointerStringer{}))},
  4208  					{P{1, 7}, addr(pointerStringer{})},
  4209  					{P{1, 8}, addr(any((*pointerStringer)(nil)))},
  4210  					{P{1, 8}, addr((*pointerStringer)(nil))},
  4211  					{P{1, 9}, addr(any(addr(pointerStringer{})))},
  4212  					{P{1, 9}, addr(addr(pointerStringer{}))},
  4213  					{P{1, 9}, addr(pointerStringer{})},
  4214  					{P{1, 10}, addr(any((**pointerStringer)(nil)))},
  4215  					{P{1, 10}, addr((**pointerStringer)(nil))},
  4216  					{P{1, 11}, addr(any(addr((*pointerStringer)(nil))))},
  4217  					{P{1, 11}, addr(addr((*pointerStringer)(nil)))},
  4218  					{P{1, 11}, addr((*pointerStringer)(nil))},
  4219  					{P{1, 12}, addr(any(addr(addr(pointerStringer{}))))},
  4220  					{P{1, 12}, addr(addr(addr(pointerStringer{})))},
  4221  					{P{1, 12}, addr(addr(pointerStringer{}))},
  4222  					{P{1, 12}, addr(pointerStringer{})},
  4223  					{P{1, 13}, addr(any("LAST"))},
  4224  					{P{1, 13}, addr("LAST")},
  4225  				}
  4226  				checkAny := makeValueChecker("any", wantAny)
  4227  				anyMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v any) error {
  4228  					return checkAny(enc, v)
  4229  				})
  4230  
  4231  				var wantPointerAny []PV
  4232  				for _, v := range wantAny {
  4233  					if _, ok := v.V.(*any); ok {
  4234  						wantPointerAny = append(wantPointerAny, v)
  4235  					}
  4236  				}
  4237  				checkPointerAny := makeValueChecker("*any", wantPointerAny)
  4238  				pointerAnyMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v *any) error {
  4239  					return checkPointerAny(enc, v)
  4240  				})
  4241  
  4242  				checkNamedAny := makeValueChecker("namedAny", wantAny)
  4243  				namedAnyMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v namedAny) error {
  4244  					return checkNamedAny(enc, v)
  4245  				})
  4246  
  4247  				checkPointerNamedAny := makeValueChecker("*namedAny", nil)
  4248  				pointerNamedAnyMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v *namedAny) error {
  4249  					return checkPointerNamedAny(enc, v)
  4250  				})
  4251  
  4252  				type stringer = fmt.Stringer
  4253  				var wantStringer []PV
  4254  				for _, v := range wantAny {
  4255  					if _, ok := v.V.(stringer); ok {
  4256  						wantStringer = append(wantStringer, v)
  4257  					}
  4258  				}
  4259  				checkStringer := makeValueChecker("stringer", wantStringer)
  4260  				stringerMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v stringer) error {
  4261  					return checkStringer(enc, v)
  4262  				})
  4263  
  4264  				checkPointerStringer := makeValueChecker("*stringer", nil)
  4265  				pointerStringerMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v *stringer) error {
  4266  					return checkPointerStringer(enc, v)
  4267  				})
  4268  
  4269  				wantValueStringer := []P{{1, 1}, {1, 3}, {1, 6}}
  4270  				checkValueValueStringer := makePositionChecker("valueStringer", wantValueStringer)
  4271  				valueValueStringerMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v valueStringer) error {
  4272  					return checkValueValueStringer(enc, v)
  4273  				})
  4274  
  4275  				checkPointerValueStringer := makePositionChecker("*valueStringer", wantValueStringer)
  4276  				pointerValueStringerMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v *valueStringer) error {
  4277  					return checkPointerValueStringer(enc, v)
  4278  				})
  4279  
  4280  				wantPointerStringer := []P{{1, 7}, {1, 9}, {1, 12}}
  4281  				checkValuePointerStringer := makePositionChecker("pointerStringer", wantPointerStringer)
  4282  				valuePointerStringerMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v pointerStringer) error {
  4283  					return checkValuePointerStringer(enc, v)
  4284  				})
  4285  
  4286  				checkPointerPointerStringer := makePositionChecker("*pointerStringer", wantPointerStringer)
  4287  				pointerPointerStringerMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v *pointerStringer) error {
  4288  					return checkPointerPointerStringer(enc, v)
  4289  				})
  4290  
  4291  				lastMarshaler := MarshalToFunc(func(enc *jsontext.Encoder, v string) error {
  4292  					return checkLast()
  4293  				})
  4294  
  4295  				return JoinMarshalers(
  4296  					anyMarshaler,
  4297  					pointerAnyMarshaler,
  4298  					namedAnyMarshaler,
  4299  					pointerNamedAnyMarshaler, // never called
  4300  					stringerMarshaler,
  4301  					pointerStringerMarshaler, // never called
  4302  					valueValueStringerMarshaler,
  4303  					pointerValueStringerMarshaler,
  4304  					valuePointerStringerMarshaler,
  4305  					pointerPointerStringerMarshaler,
  4306  					lastMarshaler,
  4307  				)
  4308  			}()),
  4309  		},
  4310  		in: []any{
  4311  			nil,                           // nil
  4312  			valueStringer{},               // T
  4313  			(*valueStringer)(nil),         // *T
  4314  			addr(valueStringer{}),         // *T
  4315  			(**valueStringer)(nil),        // **T
  4316  			addr((*valueStringer)(nil)),   // **T
  4317  			addr(addr(valueStringer{})),   // **T
  4318  			pointerStringer{},             // T
  4319  			(*pointerStringer)(nil),       // *T
  4320  			addr(pointerStringer{}),       // *T
  4321  			(**pointerStringer)(nil),      // **T
  4322  			addr((*pointerStringer)(nil)), // **T
  4323  			addr(addr(pointerStringer{})), // **T
  4324  			"LAST",
  4325  		},
  4326  		want: `[null,{},null,{},null,null,{},{},null,{},null,null,{},"LAST"]`,
  4327  	}, {
  4328  		name: jsontest.Name("Functions/Precedence/V1First"),
  4329  		opts: []Options{
  4330  			WithMarshalers(JoinMarshalers(
  4331  				MarshalFunc(func(bool) ([]byte, error) {
  4332  					return []byte(`"called"`), nil
  4333  				}),
  4334  				MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  4335  					panic("should not be called")
  4336  				}),
  4337  			)),
  4338  		},
  4339  		in:   true,
  4340  		want: `"called"`,
  4341  	}, {
  4342  		name: jsontest.Name("Functions/Precedence/V2First"),
  4343  		opts: []Options{
  4344  			WithMarshalers(JoinMarshalers(
  4345  				MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  4346  					return enc.WriteToken(jsontext.String("called"))
  4347  				}),
  4348  				MarshalFunc(func(bool) ([]byte, error) {
  4349  					panic("should not be called")
  4350  				}),
  4351  			)),
  4352  		},
  4353  		in:   true,
  4354  		want: `"called"`,
  4355  	}, {
  4356  		name: jsontest.Name("Functions/Precedence/V2Skipped"),
  4357  		opts: []Options{
  4358  			WithMarshalers(JoinMarshalers(
  4359  				MarshalToFunc(func(enc *jsontext.Encoder, v bool) error {
  4360  					return errors.ErrUnsupported
  4361  				}),
  4362  				MarshalFunc(func(bool) ([]byte, error) {
  4363  					return []byte(`"called"`), nil
  4364  				}),
  4365  			)),
  4366  		},
  4367  		in:   true,
  4368  		want: `"called"`,
  4369  	}, {
  4370  		name: jsontest.Name("Functions/Precedence/NestedFirst"),
  4371  		opts: []Options{
  4372  			WithMarshalers(JoinMarshalers(
  4373  				JoinMarshalers(
  4374  					MarshalFunc(func(bool) ([]byte, error) {
  4375  						return []byte(`"called"`), nil
  4376  					}),
  4377  				),
  4378  				MarshalFunc(func(bool) ([]byte, error) {
  4379  					panic("should not be called")
  4380  				}),
  4381  			)),
  4382  		},
  4383  		in:   true,
  4384  		want: `"called"`,
  4385  	}, {
  4386  		name: jsontest.Name("Functions/Precedence/NestedLast"),
  4387  		opts: []Options{
  4388  			WithMarshalers(JoinMarshalers(
  4389  				MarshalFunc(func(bool) ([]byte, error) {
  4390  					return []byte(`"called"`), nil
  4391  				}),
  4392  				JoinMarshalers(
  4393  					MarshalFunc(func(bool) ([]byte, error) {
  4394  						panic("should not be called")
  4395  					}),
  4396  				),
  4397  			)),
  4398  		},
  4399  		in:   true,
  4400  		want: `"called"`,
  4401  	}, {
  4402  		name: jsontest.Name("Duration/Zero"),
  4403  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  4404  		in: struct {
  4405  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  4406  			D2 time.Duration `json:",format:nano"`
  4407  		}{0, 0},
  4408  		want: `{"D1":"0s","D2":0}`,
  4409  	}, {
  4410  		name: jsontest.Name("Duration/Positive"),
  4411  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  4412  		in: struct {
  4413  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  4414  			D2 time.Duration `json:",format:nano"`
  4415  		}{
  4416  			123456789123456789,
  4417  			123456789123456789,
  4418  		},
  4419  		want: `{"D1":"34293h33m9.123456789s","D2":123456789123456789}`,
  4420  	}, {
  4421  		name: jsontest.Name("Duration/Negative"),
  4422  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  4423  		in: struct {
  4424  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  4425  			D2 time.Duration `json:",format:nano"`
  4426  		}{
  4427  			-123456789123456789,
  4428  			-123456789123456789,
  4429  		},
  4430  		want: `{"D1":"-34293h33m9.123456789s","D2":-123456789123456789}`,
  4431  	}, {
  4432  		name: jsontest.Name("Duration/Nanos/String"),
  4433  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  4434  		in: struct {
  4435  			D1 time.Duration `json:",string,format:nano"`
  4436  			D2 time.Duration `json:",string,format:nano"`
  4437  			D3 time.Duration `json:",string,format:nano"`
  4438  		}{
  4439  			math.MinInt64,
  4440  			0,
  4441  			math.MaxInt64,
  4442  		},
  4443  		want: `{"D1":"-9223372036854775808","D2":"0","D3":"9223372036854775807"}`,
  4444  	}, {
  4445  		name: jsontest.Name("Duration/Format/Invalid"),
  4446  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  4447  		in: struct {
  4448  			D time.Duration `json:",format:invalid"`
  4449  		}{},
  4450  		want:    `{"D"`,
  4451  		wantErr: EM(errInvalidFormatFlag).withPos(`{"D":`, "/D").withType(0, T[time.Duration]()),
  4452  	}, {
  4453  		/* TODO(https://go.dev/issue/71631): Re-enable this test case.
  4454  		name: jsontest.Name("Duration/IgnoreInvalidFormat"),
  4455  		opts: []Options{invalidFormatOption},
  4456  		in:   time.Duration(0),
  4457  		want: `"0s"`,
  4458  		}, { */
  4459  		name: jsontest.Name("Duration/Format"),
  4460  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsontext.Multiline(true)},
  4461  		in: structDurationFormat{
  4462  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4463  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4464  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4465  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4466  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4467  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4468  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4469  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4470  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4471  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4472  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4473  		},
  4474  		want: `{
  4475  	"D1": "12h34m56.078090012s",
  4476  	"D2": "12h34m56.078090012s",
  4477  	"D3": 45296.078090012,
  4478  	"D4": "45296.078090012",
  4479  	"D5": 45296078.090012,
  4480  	"D6": "45296078.090012",
  4481  	"D7": 45296078090.012,
  4482  	"D8": "45296078090.012",
  4483  	"D9": 45296078090012,
  4484  	"D10": "45296078090012",
  4485  	"D11": "PT12H34M56.078090012S"
  4486  }`,
  4487  	}, {
  4488  		/* TODO(https://go.dev/issue/71631): Re-enable this test case.
  4489  		name: jsontest.Name("Duration/Format/Legacy"),
  4490  		opts: []Options{jsonflags.FormatDurationAsNano | 1},
  4491  		in: structDurationFormat{
  4492  			D1: 12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4493  			D2: 12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  4494  		},
  4495  		want: `{"D1":45296078090012,"D2":"12h34m56.078090012s","D3":0,"D4":"0","D5":0,"D6":"0","D7":0,"D8":"0","D9":0,"D10":"0","D11":"PT0S"}`,
  4496  		}, { */
  4497  		/* TODO(https://go.dev/issue/71631): Re-enable this test case.
  4498  		name: jsontest.Name("Duration/MapKey"),
  4499  		in:   map[time.Duration]string{time.Second: ""},
  4500  		want: `{"1s":""}`,
  4501  		}, { */
  4502  		name: jsontest.Name("Duration/MapKey/Legacy"),
  4503  		opts: []Options{jsonflags.FormatDurationAsNano | 1},
  4504  		in:   map[time.Duration]string{time.Second: ""},
  4505  		want: `{"1000000000":""}`,
  4506  	}, {
  4507  		name: jsontest.Name("Time/Zero"),
  4508  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  4509  		in: struct {
  4510  			T1 time.Time
  4511  			T2 time.Time `json:",format:RFC822"`
  4512  			T3 time.Time `json:",format:'2006-01-02'"`
  4513  			T4 time.Time `json:",omitzero"`
  4514  			T5 time.Time `json:",omitempty"`
  4515  		}{
  4516  			time.Time{},
  4517  			time.Time{},
  4518  			time.Time{},
  4519  			// This is zero according to time.Time.IsZero,
  4520  			// but non-zero according to reflect.Value.IsZero.
  4521  			time.Date(1, 1, 1, 0, 0, 0, 0, time.FixedZone("UTC", 0)),
  4522  			time.Time{},
  4523  		},
  4524  		want: `{"T1":"0001-01-01T00:00:00Z","T2":"01 Jan 01 00:00 UTC","T3":"0001-01-01","T5":"0001-01-01T00:00:00Z"}`,
  4525  	}, {
  4526  		name: jsontest.Name("Time/Format"),
  4527  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsontext.Multiline(true)},
  4528  		in: structTimeFormat{
  4529  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4530  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4531  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4532  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4533  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4534  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4535  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4536  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4537  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4538  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4539  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4540  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4541  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4542  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4543  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4544  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4545  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4546  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4547  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4548  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4549  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4550  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4551  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4552  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4553  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4554  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4555  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4556  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4557  			time.Date(1234, 1, 2, 3, 4, 5, 6, time.UTC),
  4558  		},
  4559  		want: `{
  4560  	"T1": "1234-01-02T03:04:05.000000006Z",
  4561  	"T2": "Mon Jan  2 03:04:05 1234",
  4562  	"T3": "Mon Jan  2 03:04:05 UTC 1234",
  4563  	"T4": "Mon Jan 02 03:04:05 +0000 1234",
  4564  	"T5": "02 Jan 34 03:04 UTC",
  4565  	"T6": "02 Jan 34 03:04 +0000",
  4566  	"T7": "Monday, 02-Jan-34 03:04:05 UTC",
  4567  	"T8": "Mon, 02 Jan 1234 03:04:05 UTC",
  4568  	"T9": "Mon, 02 Jan 1234 03:04:05 +0000",
  4569  	"T10": "1234-01-02T03:04:05Z",
  4570  	"T11": "1234-01-02T03:04:05.000000006Z",
  4571  	"T12": "3:04AM",
  4572  	"T13": "Jan  2 03:04:05",
  4573  	"T14": "Jan  2 03:04:05.000",
  4574  	"T15": "Jan  2 03:04:05.000000",
  4575  	"T16": "Jan  2 03:04:05.000000006",
  4576  	"T17": "1234-01-02 03:04:05",
  4577  	"T18": "1234-01-02",
  4578  	"T19": "03:04:05",
  4579  	"T20": "1234-01-02",
  4580  	"T21": "\"weird\"1234",
  4581  	"T22": -23225777754.999999994,
  4582  	"T23": "-23225777754.999999994",
  4583  	"T24": -23225777754999.999994,
  4584  	"T25": "-23225777754999.999994",
  4585  	"T26": -23225777754999999.994,
  4586  	"T27": "-23225777754999999.994",
  4587  	"T28": -23225777754999999994,
  4588  	"T29": "-23225777754999999994"
  4589  }`,
  4590  	}, {
  4591  		name: jsontest.Name("Time/Format/Invalid"),
  4592  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  4593  		in: struct {
  4594  			T time.Time `json:",format:UndefinedConstant"`
  4595  		}{},
  4596  		want:    `{"T"`,
  4597  		wantErr: EM(errors.New(`invalid format flag "UndefinedConstant"`)).withPos(`{"T":`, "/T").withType(0, timeTimeType),
  4598  	}, {
  4599  		name:    jsontest.Name("Time/Format/String/Invalid"),
  4600  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  4601  		in:      structTimeFormatStringInvalid{},
  4602  		want:    `{"T"`,
  4603  		wantErr: EM(errInvalidStringTag).withPos(`{"T":`, "/T").withType(0, timeTimeType),
  4604  	}, {
  4605  		name: jsontest.Name("Time/Format/YearOverflow"),
  4606  		in: struct {
  4607  			T1 time.Time
  4608  			T2 time.Time
  4609  		}{
  4610  			time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Add(-time.Second),
  4611  			time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC),
  4612  		},
  4613  		want:    `{"T1":"9999-12-31T23:59:59Z","T2"`,
  4614  		wantErr: EM(errors.New(`year outside of range [0,9999]`)).withPos(`{"T1":"9999-12-31T23:59:59Z","T2":`, "/T2").withType(0, timeTimeType),
  4615  	}, {
  4616  		name: jsontest.Name("Time/Format/YearUnderflow"),
  4617  		in: struct {
  4618  			T1 time.Time
  4619  			T2 time.Time
  4620  		}{
  4621  			time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC),
  4622  			time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC).Add(-time.Second),
  4623  		},
  4624  		want:    `{"T1":"0000-01-01T00:00:00Z","T2"`,
  4625  		wantErr: EM(errors.New(`year outside of range [0,9999]`)).withPos(`{"T1":"0000-01-01T00:00:00Z","T2":`, "/T2").withType(0, timeTimeType),
  4626  	}, {
  4627  		name:    jsontest.Name("Time/Format/YearUnderflow"),
  4628  		in:      struct{ T time.Time }{time.Date(-998, 1, 1, 0, 0, 0, 0, time.UTC).Add(-time.Second)},
  4629  		want:    `{"T"`,
  4630  		wantErr: EM(errors.New(`year outside of range [0,9999]`)).withPos(`{"T":`, "/T").withType(0, timeTimeType),
  4631  	}, {
  4632  		name: jsontest.Name("Time/Format/ZoneExact"),
  4633  		in:   struct{ T time.Time }{time.Date(2020, 1, 1, 0, 0, 0, 0, time.FixedZone("", 23*60*60+59*60))},
  4634  		want: `{"T":"2020-01-01T00:00:00+23:59"}`,
  4635  	}, {
  4636  		name:    jsontest.Name("Time/Format/ZoneHourOverflow"),
  4637  		in:      struct{ T time.Time }{time.Date(2020, 1, 1, 0, 0, 0, 0, time.FixedZone("", 24*60*60))},
  4638  		want:    `{"T"`,
  4639  		wantErr: EM(errors.New(`timezone hour outside of range [0,23]`)).withPos(`{"T":`, "/T").withType(0, timeTimeType),
  4640  	}, {
  4641  		name:    jsontest.Name("Time/Format/ZoneHourOverflow"),
  4642  		in:      struct{ T time.Time }{time.Date(2020, 1, 1, 0, 0, 0, 0, time.FixedZone("", 123*60*60))},
  4643  		want:    `{"T"`,
  4644  		wantErr: EM(errors.New(`timezone hour outside of range [0,23]`)).withPos(`{"T":`, "/T").withType(0, timeTimeType),
  4645  	}, {
  4646  		name: jsontest.Name("Time/IgnoreInvalidFormat"),
  4647  		opts: []Options{invalidFormatOption},
  4648  		in:   time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
  4649  		want: `"2000-01-01T00:00:00Z"`,
  4650  	}}
  4651  
  4652  	for _, tt := range tests {
  4653  		t.Run(tt.name.Name, func(t *testing.T) {
  4654  			var got []byte
  4655  			var gotErr error
  4656  			if tt.useWriter {
  4657  				bb := new(struct{ bytes.Buffer }) // avoid optimizations with bytes.Buffer
  4658  				gotErr = MarshalWrite(bb, tt.in, tt.opts...)
  4659  				got = bb.Bytes()
  4660  			} else {
  4661  				got, gotErr = Marshal(tt.in, tt.opts...)
  4662  			}
  4663  			if tt.canonicalize {
  4664  				(*jsontext.Value)(&got).Canonicalize()
  4665  			}
  4666  			if string(got) != tt.want {
  4667  				t.Errorf("%s: Marshal output mismatch:\ngot  %s\nwant %s", tt.name.Where, got, tt.want)
  4668  			}
  4669  			if !reflect.DeepEqual(gotErr, tt.wantErr) {
  4670  				t.Errorf("%s: Marshal error mismatch:\ngot  %v\nwant %v", tt.name.Where, gotErr, tt.wantErr)
  4671  			}
  4672  		})
  4673  	}
  4674  }
  4675  
  4676  func TestUnmarshal(t *testing.T) {
  4677  	tests := []struct {
  4678  		name    jsontest.CaseName
  4679  		opts    []Options
  4680  		inBuf   string
  4681  		inVal   any
  4682  		want    any
  4683  		wantErr error
  4684  		skip    bool
  4685  	}{{
  4686  		name:    jsontest.Name("Nil"),
  4687  		inBuf:   `null`,
  4688  		wantErr: EU(internal.ErrNonNilReference),
  4689  	}, {
  4690  		name:    jsontest.Name("NilPointer"),
  4691  		inBuf:   `null`,
  4692  		inVal:   (*string)(nil),
  4693  		want:    (*string)(nil),
  4694  		wantErr: EU(internal.ErrNonNilReference).withType(0, T[*string]()),
  4695  	}, {
  4696  		name:    jsontest.Name("NonPointer"),
  4697  		inBuf:   `null`,
  4698  		inVal:   "unchanged",
  4699  		want:    "unchanged",
  4700  		wantErr: EU(internal.ErrNonNilReference).withType(0, T[string]()),
  4701  	}, {
  4702  		name:    jsontest.Name("Bools/TrailingJunk"),
  4703  		inBuf:   `falsetrue`,
  4704  		inVal:   addr(true),
  4705  		want:    addr(false),
  4706  		wantErr: newInvalidCharacterError("t", "after top-level value", len64(`false`), ""),
  4707  	}, {
  4708  		name:  jsontest.Name("Bools/Null"),
  4709  		inBuf: `null`,
  4710  		inVal: addr(true),
  4711  		want:  addr(false),
  4712  	}, {
  4713  		name:  jsontest.Name("Bools"),
  4714  		inBuf: `[null,false,true]`,
  4715  		inVal: new([]bool),
  4716  		want:  addr([]bool{false, false, true}),
  4717  	}, {
  4718  		name:  jsontest.Name("Bools/Named"),
  4719  		inBuf: `[null,false,true]`,
  4720  		inVal: new([]namedBool),
  4721  		want:  addr([]namedBool{false, false, true}),
  4722  	}, {
  4723  		name:    jsontest.Name("Bools/Invalid/StringifiedFalse"),
  4724  		opts:    []Options{StringifyNumbers(true)},
  4725  		inBuf:   `"false"`,
  4726  		inVal:   addr(true),
  4727  		want:    addr(true),
  4728  		wantErr: EU(nil).withType('"', boolType),
  4729  	}, {
  4730  		name:    jsontest.Name("Bools/Invalid/StringifiedTrue"),
  4731  		opts:    []Options{StringifyNumbers(true)},
  4732  		inBuf:   `"true"`,
  4733  		inVal:   addr(true),
  4734  		want:    addr(true),
  4735  		wantErr: EU(nil).withType('"', boolType),
  4736  	}, {
  4737  		name:  jsontest.Name("Bools/StringifiedBool/True"),
  4738  		opts:  []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
  4739  		inBuf: `"true"`,
  4740  		inVal: addr(false),
  4741  		want:  addr(true),
  4742  	}, {
  4743  		name:  jsontest.Name("Bools/StringifiedBool/False"),
  4744  		opts:  []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
  4745  		inBuf: `"false"`,
  4746  		inVal: addr(true),
  4747  		want:  addr(false),
  4748  	}, {
  4749  		name:    jsontest.Name("Bools/StringifiedBool/InvalidWhitespace"),
  4750  		opts:    []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
  4751  		inBuf:   `"false "`,
  4752  		inVal:   addr(true),
  4753  		want:    addr(true),
  4754  		wantErr: EU(strconv.ErrSyntax).withVal(`"false "`).withType('"', boolType),
  4755  	}, {
  4756  		name:    jsontest.Name("Bools/StringifiedBool/InvalidBool"),
  4757  		opts:    []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
  4758  		inBuf:   `false`,
  4759  		inVal:   addr(true),
  4760  		want:    addr(true),
  4761  		wantErr: EU(nil).withType('f', boolType),
  4762  	}, {
  4763  		name:    jsontest.Name("Bools/Invalid/Number"),
  4764  		inBuf:   `0`,
  4765  		inVal:   addr(true),
  4766  		want:    addr(true),
  4767  		wantErr: EU(nil).withType('0', boolType),
  4768  	}, {
  4769  		name:    jsontest.Name("Bools/Invalid/String"),
  4770  		inBuf:   `""`,
  4771  		inVal:   addr(true),
  4772  		want:    addr(true),
  4773  		wantErr: EU(nil).withType('"', boolType),
  4774  	}, {
  4775  		name:    jsontest.Name("Bools/Invalid/Object"),
  4776  		inBuf:   `{}`,
  4777  		inVal:   addr(true),
  4778  		want:    addr(true),
  4779  		wantErr: EU(nil).withType('{', boolType),
  4780  	}, {
  4781  		name:    jsontest.Name("Bools/Invalid/Array"),
  4782  		inBuf:   `[]`,
  4783  		inVal:   addr(true),
  4784  		want:    addr(true),
  4785  		wantErr: EU(nil).withType('[', boolType),
  4786  	}, {
  4787  		name:  jsontest.Name("Bools/IgnoreInvalidFormat"),
  4788  		opts:  []Options{invalidFormatOption},
  4789  		inBuf: `false`,
  4790  		inVal: addr(true),
  4791  		want:  addr(false),
  4792  	}, {
  4793  		name:  jsontest.Name("Strings/Null"),
  4794  		inBuf: `null`,
  4795  		inVal: addr("something"),
  4796  		want:  addr(""),
  4797  	}, {
  4798  		name:  jsontest.Name("Strings"),
  4799  		inBuf: `[null,"","hello","世界"]`,
  4800  		inVal: new([]string),
  4801  		want:  addr([]string{"", "", "hello", "世界"}),
  4802  	}, {
  4803  		name:  jsontest.Name("Strings/Escaped"),
  4804  		inBuf: `[null,"","\u0068\u0065\u006c\u006c\u006f","\u4e16\u754c"]`,
  4805  		inVal: new([]string),
  4806  		want:  addr([]string{"", "", "hello", "世界"}),
  4807  	}, {
  4808  		name:  jsontest.Name("Strings/Named"),
  4809  		inBuf: `[null,"","hello","世界"]`,
  4810  		inVal: new([]namedString),
  4811  		want:  addr([]namedString{"", "", "hello", "世界"}),
  4812  	}, {
  4813  		name:    jsontest.Name("Strings/Invalid/False"),
  4814  		inBuf:   `false`,
  4815  		inVal:   addr("nochange"),
  4816  		want:    addr("nochange"),
  4817  		wantErr: EU(nil).withType('f', stringType),
  4818  	}, {
  4819  		name:    jsontest.Name("Strings/Invalid/True"),
  4820  		inBuf:   `true`,
  4821  		inVal:   addr("nochange"),
  4822  		want:    addr("nochange"),
  4823  		wantErr: EU(nil).withType('t', stringType),
  4824  	}, {
  4825  		name:    jsontest.Name("Strings/Invalid/Object"),
  4826  		inBuf:   `{}`,
  4827  		inVal:   addr("nochange"),
  4828  		want:    addr("nochange"),
  4829  		wantErr: EU(nil).withType('{', stringType),
  4830  	}, {
  4831  		name:    jsontest.Name("Strings/Invalid/Array"),
  4832  		inBuf:   `[]`,
  4833  		inVal:   addr("nochange"),
  4834  		want:    addr("nochange"),
  4835  		wantErr: EU(nil).withType('[', stringType),
  4836  	}, {
  4837  		name:  jsontest.Name("Strings/IgnoreInvalidFormat"),
  4838  		opts:  []Options{invalidFormatOption},
  4839  		inBuf: `"hello"`,
  4840  		inVal: addr("goodbye"),
  4841  		want:  addr("hello"),
  4842  	}, {
  4843  		name:  jsontest.Name("Strings/StringifiedString"),
  4844  		opts:  []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
  4845  		inBuf: `"\"foo\""`,
  4846  		inVal: new(string),
  4847  		want:  addr("foo"),
  4848  	}, {
  4849  		name:    jsontest.Name("Strings/StringifiedString/InvalidWhitespace"),
  4850  		opts:    []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
  4851  		inBuf:   `"\"foo\" "`,
  4852  		inVal:   new(string),
  4853  		want:    new(string),
  4854  		wantErr: EU(newInvalidCharacterError(" ", "after string value", 0, "")).withType('"', stringType),
  4855  	}, {
  4856  		name:    jsontest.Name("Strings/StringifiedString/InvalidString"),
  4857  		opts:    []Options{jsonflags.StringTag | jsonflags.StringifyWithLegacySemantics | 1},
  4858  		inBuf:   `""`,
  4859  		inVal:   new(string),
  4860  		want:    new(string),
  4861  		wantErr: EU(&jsontext.SyntacticError{Err: io.ErrUnexpectedEOF}).withType('"', stringType),
  4862  	}, {
  4863  		name:  jsontest.Name("Bytes/Null"),
  4864  		inBuf: `null`,
  4865  		inVal: addr([]byte("something")),
  4866  		want:  addr([]byte(nil)),
  4867  	}, {
  4868  		name:  jsontest.Name("Bytes"),
  4869  		inBuf: `[null,"","AQ==","AQI=","AQID"]`,
  4870  		inVal: new([][]byte),
  4871  		want:  addr([][]byte{nil, {}, {1}, {1, 2}, {1, 2, 3}}),
  4872  	}, {
  4873  		name:  jsontest.Name("Bytes/Large"),
  4874  		inBuf: `"dGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cgYW5kIGF0ZSB0aGUgaG9tZXdvcmsgdGhhdCBJIHNwZW50IHNvIG11Y2ggdGltZSBvbi4="`,
  4875  		inVal: new([]byte),
  4876  		want:  addr([]byte("the quick brown fox jumped over the lazy dog and ate the homework that I spent so much time on.")),
  4877  	}, {
  4878  		name:  jsontest.Name("Bytes/Reuse"),
  4879  		inBuf: `"AQID"`,
  4880  		inVal: addr([]byte("changed")),
  4881  		want:  addr([]byte{1, 2, 3}),
  4882  	}, {
  4883  		name:  jsontest.Name("Bytes/Escaped"),
  4884  		inBuf: `[null,"","\u0041\u0051\u003d\u003d","\u0041\u0051\u0049\u003d","\u0041\u0051\u0049\u0044"]`,
  4885  		inVal: new([][]byte),
  4886  		want:  addr([][]byte{nil, {}, {1}, {1, 2}, {1, 2, 3}}),
  4887  	}, {
  4888  		name:  jsontest.Name("Bytes/Named"),
  4889  		inBuf: `[null,"","AQ==","AQI=","AQID"]`,
  4890  		inVal: new([]namedBytes),
  4891  		want:  addr([]namedBytes{nil, {}, {1}, {1, 2}, {1, 2, 3}}),
  4892  	}, {
  4893  		name:  jsontest.Name("Bytes/NotStringified"),
  4894  		opts:  []Options{StringifyNumbers(true)},
  4895  		inBuf: `[null,"","AQ==","AQI=","AQID"]`,
  4896  		inVal: new([][]byte),
  4897  		want:  addr([][]byte{nil, {}, {1}, {1, 2}, {1, 2, 3}}),
  4898  	}, {
  4899  		// NOTE: []namedByte is not assignable to []byte,
  4900  		// so the following should be treated as a slice of uints.
  4901  		name:  jsontest.Name("Bytes/Invariant"),
  4902  		inBuf: `[null,[],[1],[1,2],[1,2,3]]`,
  4903  		inVal: new([][]namedByte),
  4904  		want:  addr([][]namedByte{nil, {}, {1}, {1, 2}, {1, 2, 3}}),
  4905  	}, {
  4906  		// NOTE: This differs in behavior from v1,
  4907  		// but keeps the representation of slices and arrays more consistent.
  4908  		name:  jsontest.Name("Bytes/ByteArray"),
  4909  		inBuf: `"aGVsbG8="`,
  4910  		inVal: new([5]byte),
  4911  		want:  addr([5]byte{'h', 'e', 'l', 'l', 'o'}),
  4912  	}, {
  4913  		name:  jsontest.Name("Bytes/ByteArray0/Valid"),
  4914  		inBuf: `""`,
  4915  		inVal: new([0]byte),
  4916  		want:  addr([0]byte{}),
  4917  	}, {
  4918  		name:  jsontest.Name("Bytes/ByteArray0/Invalid"),
  4919  		inBuf: `"A"`,
  4920  		inVal: new([0]byte),
  4921  		want:  addr([0]byte{}),
  4922  		wantErr: EU(func() error {
  4923  			_, err := base64.StdEncoding.Decode(make([]byte, 0), []byte("A"))
  4924  			return err
  4925  		}()).withType('"', T[[0]byte]()),
  4926  	}, {
  4927  		name:    jsontest.Name("Bytes/ByteArray0/Overflow"),
  4928  		inBuf:   `"AA=="`,
  4929  		inVal:   new([0]byte),
  4930  		want:    addr([0]byte{}),
  4931  		wantErr: EU(errors.New("decoded length of 1 mismatches array length of 0")).withType('"', T[[0]byte]()),
  4932  	}, {
  4933  		name:  jsontest.Name("Bytes/ByteArray1/Valid"),
  4934  		inBuf: `"AQ=="`,
  4935  		inVal: new([1]byte),
  4936  		want:  addr([1]byte{1}),
  4937  	}, {
  4938  		name:  jsontest.Name("Bytes/ByteArray1/Invalid"),
  4939  		inBuf: `"$$=="`,
  4940  		inVal: new([1]byte),
  4941  		want:  addr([1]byte{}),
  4942  		wantErr: EU(func() error {
  4943  			_, err := base64.StdEncoding.Decode(make([]byte, 1), []byte("$$=="))
  4944  			return err
  4945  		}()).withType('"', T[[1]byte]()),
  4946  	}, {
  4947  		name:    jsontest.Name("Bytes/ByteArray1/Underflow"),
  4948  		inBuf:   `""`,
  4949  		inVal:   new([1]byte),
  4950  		want:    addr([1]byte{}),
  4951  		wantErr: EU(errors.New("decoded length of 0 mismatches array length of 1")).withType('"', T[[1]byte]()),
  4952  	}, {
  4953  		name:    jsontest.Name("Bytes/ByteArray1/Overflow"),
  4954  		inBuf:   `"AQI="`,
  4955  		inVal:   new([1]byte),
  4956  		want:    addr([1]byte{1}),
  4957  		wantErr: EU(errors.New("decoded length of 2 mismatches array length of 1")).withType('"', T[[1]byte]()),
  4958  	}, {
  4959  		name:  jsontest.Name("Bytes/ByteArray2/Valid"),
  4960  		inBuf: `"AQI="`,
  4961  		inVal: new([2]byte),
  4962  		want:  addr([2]byte{1, 2}),
  4963  	}, {
  4964  		name:  jsontest.Name("Bytes/ByteArray2/Invalid"),
  4965  		inBuf: `"$$$="`,
  4966  		inVal: new([2]byte),
  4967  		want:  addr([2]byte{}),
  4968  		wantErr: EU(func() error {
  4969  			_, err := base64.StdEncoding.Decode(make([]byte, 2), []byte("$$$="))
  4970  			return err
  4971  		}()).withType('"', T[[2]byte]()),
  4972  	}, {
  4973  		name:    jsontest.Name("Bytes/ByteArray2/Underflow"),
  4974  		inBuf:   `"AQ=="`,
  4975  		inVal:   new([2]byte),
  4976  		want:    addr([2]byte{1, 0}),
  4977  		wantErr: EU(errors.New("decoded length of 1 mismatches array length of 2")).withType('"', T[[2]byte]()),
  4978  	}, {
  4979  		name:  jsontest.Name("Bytes/ByteArray2/Underflow/Allowed"),
  4980  		opts:  []Options{jsonflags.UnmarshalArrayFromAnyLength | 1},
  4981  		inBuf: `"AQ=="`,
  4982  		inVal: new([2]byte),
  4983  		want:  addr([2]byte{1, 0}),
  4984  	}, {
  4985  		name:    jsontest.Name("Bytes/ByteArray2/Overflow"),
  4986  		inBuf:   `"AQID"`,
  4987  		inVal:   new([2]byte),
  4988  		want:    addr([2]byte{1, 2}),
  4989  		wantErr: EU(errors.New("decoded length of 3 mismatches array length of 2")).withType('"', T[[2]byte]()),
  4990  	}, {
  4991  		name:  jsontest.Name("Bytes/ByteArray2/Overflow/Allowed"),
  4992  		opts:  []Options{jsonflags.UnmarshalArrayFromAnyLength | 1},
  4993  		inBuf: `"AQID"`,
  4994  		inVal: new([2]byte),
  4995  		want:  addr([2]byte{1, 2}),
  4996  	}, {
  4997  		name:  jsontest.Name("Bytes/ByteArray3/Valid"),
  4998  		inBuf: `"AQID"`,
  4999  		inVal: new([3]byte),
  5000  		want:  addr([3]byte{1, 2, 3}),
  5001  	}, {
  5002  		name:  jsontest.Name("Bytes/ByteArray3/Invalid"),
  5003  		inBuf: `"$$$$"`,
  5004  		inVal: new([3]byte),
  5005  		want:  addr([3]byte{}),
  5006  		wantErr: EU(func() error {
  5007  			_, err := base64.StdEncoding.Decode(make([]byte, 3), []byte("$$$$"))
  5008  			return err
  5009  		}()).withType('"', T[[3]byte]()),
  5010  	}, {
  5011  		name:    jsontest.Name("Bytes/ByteArray3/Underflow"),
  5012  		inBuf:   `"AQI="`,
  5013  		inVal:   addr([3]byte{0xff, 0xff, 0xff}),
  5014  		want:    addr([3]byte{1, 2, 0}),
  5015  		wantErr: EU(errors.New("decoded length of 2 mismatches array length of 3")).withType('"', T[[3]byte]()),
  5016  	}, {
  5017  		name:    jsontest.Name("Bytes/ByteArray3/Overflow"),
  5018  		inBuf:   `"AQIDAQ=="`,
  5019  		inVal:   new([3]byte),
  5020  		want:    addr([3]byte{1, 2, 3}),
  5021  		wantErr: EU(errors.New("decoded length of 4 mismatches array length of 3")).withType('"', T[[3]byte]()),
  5022  	}, {
  5023  		name:  jsontest.Name("Bytes/ByteArray4/Valid"),
  5024  		inBuf: `"AQIDBA=="`,
  5025  		inVal: new([4]byte),
  5026  		want:  addr([4]byte{1, 2, 3, 4}),
  5027  	}, {
  5028  		name:  jsontest.Name("Bytes/ByteArray4/Invalid"),
  5029  		inBuf: `"$$$$$$=="`,
  5030  		inVal: new([4]byte),
  5031  		want:  addr([4]byte{}),
  5032  		wantErr: EU(func() error {
  5033  			_, err := base64.StdEncoding.Decode(make([]byte, 4), []byte("$$$$$$=="))
  5034  			return err
  5035  		}()).withType('"', T[[4]byte]()),
  5036  	}, {
  5037  		name:    jsontest.Name("Bytes/ByteArray4/Underflow"),
  5038  		inBuf:   `"AQID"`,
  5039  		inVal:   new([4]byte),
  5040  		want:    addr([4]byte{1, 2, 3, 0}),
  5041  		wantErr: EU(errors.New("decoded length of 3 mismatches array length of 4")).withType('"', T[[4]byte]()),
  5042  	}, {
  5043  		name:    jsontest.Name("Bytes/ByteArray4/Overflow"),
  5044  		inBuf:   `"AQIDBAU="`,
  5045  		inVal:   new([4]byte),
  5046  		want:    addr([4]byte{1, 2, 3, 4}),
  5047  		wantErr: EU(errors.New("decoded length of 5 mismatches array length of 4")).withType('"', T[[4]byte]()),
  5048  	}, {
  5049  		// NOTE: []namedByte is not assignable to []byte,
  5050  		// so the following should be treated as a array of uints.
  5051  		name:  jsontest.Name("Bytes/NamedByteArray"),
  5052  		inBuf: `[104,101,108,108,111]`,
  5053  		inVal: new([5]namedByte),
  5054  		want:  addr([5]namedByte{'h', 'e', 'l', 'l', 'o'}),
  5055  	}, {
  5056  		name:  jsontest.Name("Bytes/Valid/Denormalized"),
  5057  		inBuf: `"AR=="`,
  5058  		inVal: new([]byte),
  5059  		want:  addr([]byte{1}),
  5060  	}, {
  5061  		name:  jsontest.Name("Bytes/Invalid/Unpadded1"),
  5062  		inBuf: `"AQ="`,
  5063  		inVal: addr([]byte("nochange")),
  5064  		want:  addr([]byte("nochange")),
  5065  		wantErr: EU(func() error {
  5066  			_, err := base64.StdEncoding.Decode(make([]byte, 0), []byte("AQ="))
  5067  			return err
  5068  		}()).withType('"', bytesType),
  5069  	}, {
  5070  		name:  jsontest.Name("Bytes/Invalid/Unpadded2"),
  5071  		inBuf: `"AQ"`,
  5072  		inVal: addr([]byte("nochange")),
  5073  		want:  addr([]byte("nochange")),
  5074  		wantErr: EU(func() error {
  5075  			_, err := base64.StdEncoding.Decode(make([]byte, 0), []byte("AQ"))
  5076  			return err
  5077  		}()).withType('"', bytesType),
  5078  	}, {
  5079  		name:  jsontest.Name("Bytes/Invalid/Character"),
  5080  		inBuf: `"@@@@"`,
  5081  		inVal: addr([]byte("nochange")),
  5082  		want:  addr([]byte("nochange")),
  5083  		wantErr: EU(func() error {
  5084  			_, err := base64.StdEncoding.Decode(make([]byte, 3), []byte("@@@@"))
  5085  			return err
  5086  		}()).withType('"', bytesType),
  5087  	}, {
  5088  		name:    jsontest.Name("Bytes/Invalid/Bool"),
  5089  		inBuf:   `true`,
  5090  		inVal:   addr([]byte("nochange")),
  5091  		want:    addr([]byte("nochange")),
  5092  		wantErr: EU(nil).withType('t', bytesType),
  5093  	}, {
  5094  		name:    jsontest.Name("Bytes/Invalid/Number"),
  5095  		inBuf:   `0`,
  5096  		inVal:   addr([]byte("nochange")),
  5097  		want:    addr([]byte("nochange")),
  5098  		wantErr: EU(nil).withType('0', bytesType),
  5099  	}, {
  5100  		name:    jsontest.Name("Bytes/Invalid/Object"),
  5101  		inBuf:   `{}`,
  5102  		inVal:   addr([]byte("nochange")),
  5103  		want:    addr([]byte("nochange")),
  5104  		wantErr: EU(nil).withType('{', bytesType),
  5105  	}, {
  5106  		name:    jsontest.Name("Bytes/Invalid/Array"),
  5107  		inBuf:   `[]`,
  5108  		inVal:   addr([]byte("nochange")),
  5109  		want:    addr([]byte("nochange")),
  5110  		wantErr: EU(nil).withType('[', bytesType),
  5111  	}, {
  5112  		name:  jsontest.Name("Bytes/IgnoreInvalidFormat"),
  5113  		opts:  []Options{invalidFormatOption},
  5114  		inBuf: `"aGVsbG8="`,
  5115  		inVal: new([]byte),
  5116  		want:  addr([]byte("hello")),
  5117  	}, {
  5118  		name:  jsontest.Name("Ints/Null"),
  5119  		inBuf: `null`,
  5120  		inVal: addr(int(1)),
  5121  		want:  addr(int(0)),
  5122  	}, {
  5123  		name:  jsontest.Name("Ints/Int"),
  5124  		inBuf: `1`,
  5125  		inVal: addr(int(0)),
  5126  		want:  addr(int(1)),
  5127  	}, {
  5128  		name:    jsontest.Name("Ints/Int8/MinOverflow"),
  5129  		inBuf:   `-129`,
  5130  		inVal:   addr(int8(-1)),
  5131  		want:    addr(int8(-1)),
  5132  		wantErr: EU(strconv.ErrRange).withVal(`-129`).withType('0', T[int8]()),
  5133  	}, {
  5134  		name:  jsontest.Name("Ints/Int8/Min"),
  5135  		inBuf: `-128`,
  5136  		inVal: addr(int8(0)),
  5137  		want:  addr(int8(-128)),
  5138  	}, {
  5139  		name:  jsontest.Name("Ints/Int8/Max"),
  5140  		inBuf: `127`,
  5141  		inVal: addr(int8(0)),
  5142  		want:  addr(int8(127)),
  5143  	}, {
  5144  		name:    jsontest.Name("Ints/Int8/MaxOverflow"),
  5145  		inBuf:   `128`,
  5146  		inVal:   addr(int8(-1)),
  5147  		want:    addr(int8(-1)),
  5148  		wantErr: EU(strconv.ErrRange).withVal(`128`).withType('0', T[int8]()),
  5149  	}, {
  5150  		name:    jsontest.Name("Ints/Int16/MinOverflow"),
  5151  		inBuf:   `-32769`,
  5152  		inVal:   addr(int16(-1)),
  5153  		want:    addr(int16(-1)),
  5154  		wantErr: EU(strconv.ErrRange).withVal(`-32769`).withType('0', T[int16]()),
  5155  	}, {
  5156  		name:  jsontest.Name("Ints/Int16/Min"),
  5157  		inBuf: `-32768`,
  5158  		inVal: addr(int16(0)),
  5159  		want:  addr(int16(-32768)),
  5160  	}, {
  5161  		name:  jsontest.Name("Ints/Int16/Max"),
  5162  		inBuf: `32767`,
  5163  		inVal: addr(int16(0)),
  5164  		want:  addr(int16(32767)),
  5165  	}, {
  5166  		name:    jsontest.Name("Ints/Int16/MaxOverflow"),
  5167  		inBuf:   `32768`,
  5168  		inVal:   addr(int16(-1)),
  5169  		want:    addr(int16(-1)),
  5170  		wantErr: EU(strconv.ErrRange).withVal(`32768`).withType('0', T[int16]()),
  5171  	}, {
  5172  		name:    jsontest.Name("Ints/Int32/MinOverflow"),
  5173  		inBuf:   `-2147483649`,
  5174  		inVal:   addr(int32(-1)),
  5175  		want:    addr(int32(-1)),
  5176  		wantErr: EU(strconv.ErrRange).withVal(`-2147483649`).withType('0', T[int32]()),
  5177  	}, {
  5178  		name:  jsontest.Name("Ints/Int32/Min"),
  5179  		inBuf: `-2147483648`,
  5180  		inVal: addr(int32(0)),
  5181  		want:  addr(int32(-2147483648)),
  5182  	}, {
  5183  		name:  jsontest.Name("Ints/Int32/Max"),
  5184  		inBuf: `2147483647`,
  5185  		inVal: addr(int32(0)),
  5186  		want:  addr(int32(2147483647)),
  5187  	}, {
  5188  		name:    jsontest.Name("Ints/Int32/MaxOverflow"),
  5189  		inBuf:   `2147483648`,
  5190  		inVal:   addr(int32(-1)),
  5191  		want:    addr(int32(-1)),
  5192  		wantErr: EU(strconv.ErrRange).withVal(`2147483648`).withType('0', T[int32]()),
  5193  	}, {
  5194  		name:    jsontest.Name("Ints/Int64/MinOverflow"),
  5195  		inBuf:   `-9223372036854775809`,
  5196  		inVal:   addr(int64(-1)),
  5197  		want:    addr(int64(-1)),
  5198  		wantErr: EU(strconv.ErrRange).withVal(`-9223372036854775809`).withType('0', T[int64]()),
  5199  	}, {
  5200  		name:  jsontest.Name("Ints/Int64/Min"),
  5201  		inBuf: `-9223372036854775808`,
  5202  		inVal: addr(int64(0)),
  5203  		want:  addr(int64(-9223372036854775808)),
  5204  	}, {
  5205  		name:  jsontest.Name("Ints/Int64/Max"),
  5206  		inBuf: `9223372036854775807`,
  5207  		inVal: addr(int64(0)),
  5208  		want:  addr(int64(9223372036854775807)),
  5209  	}, {
  5210  		name:    jsontest.Name("Ints/Int64/MaxOverflow"),
  5211  		inBuf:   `9223372036854775808`,
  5212  		inVal:   addr(int64(-1)),
  5213  		want:    addr(int64(-1)),
  5214  		wantErr: EU(strconv.ErrRange).withVal(`9223372036854775808`).withType('0', T[int64]()),
  5215  	}, {
  5216  		name:  jsontest.Name("Ints/Named"),
  5217  		inBuf: `-6464`,
  5218  		inVal: addr(namedInt64(0)),
  5219  		want:  addr(namedInt64(-6464)),
  5220  	}, {
  5221  		name:  jsontest.Name("Ints/Stringified"),
  5222  		opts:  []Options{StringifyNumbers(true)},
  5223  		inBuf: `"-6464"`,
  5224  		inVal: new(int),
  5225  		want:  addr(int(-6464)),
  5226  	}, {
  5227  		name:    jsontest.Name("Ints/Stringified/Invalid"),
  5228  		opts:    []Options{StringifyNumbers(true)},
  5229  		inBuf:   `-6464`,
  5230  		inVal:   new(int),
  5231  		want:    new(int),
  5232  		wantErr: EU(nil).withType('0', T[int]()),
  5233  	}, {
  5234  		name:    jsontest.Name("Ints/Stringified/LeadingZero"),
  5235  		opts:    []Options{StringifyNumbers(true)},
  5236  		inBuf:   `"00"`,
  5237  		inVal:   addr(int(-1)),
  5238  		want:    addr(int(-1)),
  5239  		wantErr: EU(strconv.ErrSyntax).withVal(`"00"`).withType('"', T[int]()),
  5240  	}, {
  5241  		name:  jsontest.Name("Ints/Escaped"),
  5242  		opts:  []Options{StringifyNumbers(true)},
  5243  		inBuf: `"\u002d\u0036\u0034\u0036\u0034"`,
  5244  		inVal: new(int),
  5245  		want:  addr(int(-6464)),
  5246  	}, {
  5247  		name:  jsontest.Name("Ints/Valid/NegativeZero"),
  5248  		inBuf: `-0`,
  5249  		inVal: addr(int(1)),
  5250  		want:  addr(int(0)),
  5251  	}, {
  5252  		name:    jsontest.Name("Ints/Invalid/Fraction"),
  5253  		inBuf:   `1.0`,
  5254  		inVal:   addr(int(-1)),
  5255  		want:    addr(int(-1)),
  5256  		wantErr: EU(strconv.ErrSyntax).withVal(`1.0`).withType('0', T[int]()),
  5257  	}, {
  5258  		name:    jsontest.Name("Ints/Invalid/Exponent"),
  5259  		inBuf:   `1e0`,
  5260  		inVal:   addr(int(-1)),
  5261  		want:    addr(int(-1)),
  5262  		wantErr: EU(strconv.ErrSyntax).withVal(`1e0`).withType('0', T[int]()),
  5263  	}, {
  5264  		name:    jsontest.Name("Ints/Invalid/StringifiedFraction"),
  5265  		opts:    []Options{StringifyNumbers(true)},
  5266  		inBuf:   `"1.0"`,
  5267  		inVal:   addr(int(-1)),
  5268  		want:    addr(int(-1)),
  5269  		wantErr: EU(strconv.ErrSyntax).withVal(`"1.0"`).withType('"', T[int]()),
  5270  	}, {
  5271  		name:    jsontest.Name("Ints/Invalid/StringifiedExponent"),
  5272  		opts:    []Options{StringifyNumbers(true)},
  5273  		inBuf:   `"1e0"`,
  5274  		inVal:   addr(int(-1)),
  5275  		want:    addr(int(-1)),
  5276  		wantErr: EU(strconv.ErrSyntax).withVal(`"1e0"`).withType('"', T[int]()),
  5277  	}, {
  5278  		name:    jsontest.Name("Ints/Invalid/Overflow"),
  5279  		inBuf:   `100000000000000000000000000000`,
  5280  		inVal:   addr(int(-1)),
  5281  		want:    addr(int(-1)),
  5282  		wantErr: EU(strconv.ErrRange).withVal(`100000000000000000000000000000`).withType('0', T[int]()),
  5283  	}, {
  5284  		name:    jsontest.Name("Ints/Invalid/OverflowSyntax"),
  5285  		opts:    []Options{StringifyNumbers(true)},
  5286  		inBuf:   `"100000000000000000000000000000x"`,
  5287  		inVal:   addr(int(-1)),
  5288  		want:    addr(int(-1)),
  5289  		wantErr: EU(strconv.ErrSyntax).withVal(`"100000000000000000000000000000x"`).withType('"', T[int]()),
  5290  	}, {
  5291  		name:    jsontest.Name("Ints/Invalid/Whitespace"),
  5292  		opts:    []Options{StringifyNumbers(true)},
  5293  		inBuf:   `"0 "`,
  5294  		inVal:   addr(int(-1)),
  5295  		want:    addr(int(-1)),
  5296  		wantErr: EU(strconv.ErrSyntax).withVal(`"0 "`).withType('"', T[int]()),
  5297  	}, {
  5298  		name:    jsontest.Name("Ints/Invalid/Bool"),
  5299  		inBuf:   `true`,
  5300  		inVal:   addr(int(-1)),
  5301  		want:    addr(int(-1)),
  5302  		wantErr: EU(nil).withType('t', T[int]()),
  5303  	}, {
  5304  		name:    jsontest.Name("Ints/Invalid/String"),
  5305  		inBuf:   `"0"`,
  5306  		inVal:   addr(int(-1)),
  5307  		want:    addr(int(-1)),
  5308  		wantErr: EU(nil).withType('"', T[int]()),
  5309  	}, {
  5310  		name:    jsontest.Name("Ints/Invalid/Object"),
  5311  		inBuf:   `{}`,
  5312  		inVal:   addr(int(-1)),
  5313  		want:    addr(int(-1)),
  5314  		wantErr: EU(nil).withType('{', T[int]()),
  5315  	}, {
  5316  		name:    jsontest.Name("Ints/Invalid/Array"),
  5317  		inBuf:   `[]`,
  5318  		inVal:   addr(int(-1)),
  5319  		want:    addr(int(-1)),
  5320  		wantErr: EU(nil).withType('[', T[int]()),
  5321  	}, {
  5322  		name:  jsontest.Name("Ints/IgnoreInvalidFormat"),
  5323  		opts:  []Options{invalidFormatOption},
  5324  		inBuf: `1`,
  5325  		inVal: addr(int(0)),
  5326  		want:  addr(int(1)),
  5327  	}, {
  5328  		name:  jsontest.Name("Uints/Null"),
  5329  		inBuf: `null`,
  5330  		inVal: addr(uint(1)),
  5331  		want:  addr(uint(0)),
  5332  	}, {
  5333  		name:  jsontest.Name("Uints/Uint"),
  5334  		inBuf: `1`,
  5335  		inVal: addr(uint(0)),
  5336  		want:  addr(uint(1)),
  5337  	}, {
  5338  		name:  jsontest.Name("Uints/Uint8/Min"),
  5339  		inBuf: `0`,
  5340  		inVal: addr(uint8(1)),
  5341  		want:  addr(uint8(0)),
  5342  	}, {
  5343  		name:  jsontest.Name("Uints/Uint8/Max"),
  5344  		inBuf: `255`,
  5345  		inVal: addr(uint8(0)),
  5346  		want:  addr(uint8(255)),
  5347  	}, {
  5348  		name:    jsontest.Name("Uints/Uint8/MaxOverflow"),
  5349  		inBuf:   `256`,
  5350  		inVal:   addr(uint8(1)),
  5351  		want:    addr(uint8(1)),
  5352  		wantErr: EU(strconv.ErrRange).withVal(`256`).withType('0', T[uint8]()),
  5353  	}, {
  5354  		name:  jsontest.Name("Uints/Uint16/Min"),
  5355  		inBuf: `0`,
  5356  		inVal: addr(uint16(1)),
  5357  		want:  addr(uint16(0)),
  5358  	}, {
  5359  		name:  jsontest.Name("Uints/Uint16/Max"),
  5360  		inBuf: `65535`,
  5361  		inVal: addr(uint16(0)),
  5362  		want:  addr(uint16(65535)),
  5363  	}, {
  5364  		name:    jsontest.Name("Uints/Uint16/MaxOverflow"),
  5365  		inBuf:   `65536`,
  5366  		inVal:   addr(uint16(1)),
  5367  		want:    addr(uint16(1)),
  5368  		wantErr: EU(strconv.ErrRange).withVal(`65536`).withType('0', T[uint16]()),
  5369  	}, {
  5370  		name:  jsontest.Name("Uints/Uint32/Min"),
  5371  		inBuf: `0`,
  5372  		inVal: addr(uint32(1)),
  5373  		want:  addr(uint32(0)),
  5374  	}, {
  5375  		name:  jsontest.Name("Uints/Uint32/Max"),
  5376  		inBuf: `4294967295`,
  5377  		inVal: addr(uint32(0)),
  5378  		want:  addr(uint32(4294967295)),
  5379  	}, {
  5380  		name:    jsontest.Name("Uints/Uint32/MaxOverflow"),
  5381  		inBuf:   `4294967296`,
  5382  		inVal:   addr(uint32(1)),
  5383  		want:    addr(uint32(1)),
  5384  		wantErr: EU(strconv.ErrRange).withVal(`4294967296`).withType('0', T[uint32]()),
  5385  	}, {
  5386  		name:  jsontest.Name("Uints/Uint64/Min"),
  5387  		inBuf: `0`,
  5388  		inVal: addr(uint64(1)),
  5389  		want:  addr(uint64(0)),
  5390  	}, {
  5391  		name:  jsontest.Name("Uints/Uint64/Max"),
  5392  		inBuf: `18446744073709551615`,
  5393  		inVal: addr(uint64(0)),
  5394  		want:  addr(uint64(18446744073709551615)),
  5395  	}, {
  5396  		name:    jsontest.Name("Uints/Uint64/MaxOverflow"),
  5397  		inBuf:   `18446744073709551616`,
  5398  		inVal:   addr(uint64(1)),
  5399  		want:    addr(uint64(1)),
  5400  		wantErr: EU(strconv.ErrRange).withVal(`18446744073709551616`).withType('0', T[uint64]()),
  5401  	}, {
  5402  		name:  jsontest.Name("Uints/Uintptr"),
  5403  		inBuf: `1`,
  5404  		inVal: addr(uintptr(0)),
  5405  		want:  addr(uintptr(1)),
  5406  	}, {
  5407  		name:  jsontest.Name("Uints/Named"),
  5408  		inBuf: `6464`,
  5409  		inVal: addr(namedUint64(0)),
  5410  		want:  addr(namedUint64(6464)),
  5411  	}, {
  5412  		name:  jsontest.Name("Uints/Stringified"),
  5413  		opts:  []Options{StringifyNumbers(true)},
  5414  		inBuf: `"6464"`,
  5415  		inVal: new(uint),
  5416  		want:  addr(uint(6464)),
  5417  	}, {
  5418  		name:    jsontest.Name("Uints/Stringified/Invalid"),
  5419  		opts:    []Options{StringifyNumbers(true)},
  5420  		inBuf:   `6464`,
  5421  		inVal:   new(uint),
  5422  		want:    new(uint),
  5423  		wantErr: EU(nil).withType('0', T[uint]()),
  5424  	}, {
  5425  		name:    jsontest.Name("Uints/Stringified/LeadingZero"),
  5426  		opts:    []Options{StringifyNumbers(true)},
  5427  		inBuf:   `"00"`,
  5428  		inVal:   addr(uint(1)),
  5429  		want:    addr(uint(1)),
  5430  		wantErr: EU(strconv.ErrSyntax).withVal(`"00"`).withType('"', T[uint]()),
  5431  	}, {
  5432  		name:  jsontest.Name("Uints/Escaped"),
  5433  		opts:  []Options{StringifyNumbers(true)},
  5434  		inBuf: `"\u0036\u0034\u0036\u0034"`,
  5435  		inVal: new(uint),
  5436  		want:  addr(uint(6464)),
  5437  	}, {
  5438  		name:    jsontest.Name("Uints/Invalid/NegativeOne"),
  5439  		inBuf:   `-1`,
  5440  		inVal:   addr(uint(1)),
  5441  		want:    addr(uint(1)),
  5442  		wantErr: EU(strconv.ErrSyntax).withVal(`-1`).withType('0', T[uint]()),
  5443  	}, {
  5444  		name:    jsontest.Name("Uints/Invalid/NegativeZero"),
  5445  		inBuf:   `-0`,
  5446  		inVal:   addr(uint(1)),
  5447  		want:    addr(uint(1)),
  5448  		wantErr: EU(strconv.ErrSyntax).withVal(`-0`).withType('0', T[uint]()),
  5449  	}, {
  5450  		name:    jsontest.Name("Uints/Invalid/Fraction"),
  5451  		inBuf:   `1.0`,
  5452  		inVal:   addr(uint(10)),
  5453  		want:    addr(uint(10)),
  5454  		wantErr: EU(strconv.ErrSyntax).withVal(`1.0`).withType('0', T[uint]()),
  5455  	}, {
  5456  		name:    jsontest.Name("Uints/Invalid/Exponent"),
  5457  		inBuf:   `1e0`,
  5458  		inVal:   addr(uint(10)),
  5459  		want:    addr(uint(10)),
  5460  		wantErr: EU(strconv.ErrSyntax).withVal(`1e0`).withType('0', T[uint]()),
  5461  	}, {
  5462  		name:    jsontest.Name("Uints/Invalid/StringifiedFraction"),
  5463  		opts:    []Options{StringifyNumbers(true)},
  5464  		inBuf:   `"1.0"`,
  5465  		inVal:   addr(uint(10)),
  5466  		want:    addr(uint(10)),
  5467  		wantErr: EU(strconv.ErrSyntax).withVal(`"1.0"`).withType('"', T[uint]()),
  5468  	}, {
  5469  		name:    jsontest.Name("Uints/Invalid/StringifiedExponent"),
  5470  		opts:    []Options{StringifyNumbers(true)},
  5471  		inBuf:   `"1e0"`,
  5472  		inVal:   addr(uint(10)),
  5473  		want:    addr(uint(10)),
  5474  		wantErr: EU(strconv.ErrSyntax).withVal(`"1e0"`).withType('"', T[uint]()),
  5475  	}, {
  5476  		name:    jsontest.Name("Uints/Invalid/Overflow"),
  5477  		inBuf:   `100000000000000000000000000000`,
  5478  		inVal:   addr(uint(1)),
  5479  		want:    addr(uint(1)),
  5480  		wantErr: EU(strconv.ErrRange).withVal(`100000000000000000000000000000`).withType('0', T[uint]()),
  5481  	}, {
  5482  		name:    jsontest.Name("Uints/Invalid/OverflowSyntax"),
  5483  		opts:    []Options{StringifyNumbers(true)},
  5484  		inBuf:   `"100000000000000000000000000000x"`,
  5485  		inVal:   addr(uint(1)),
  5486  		want:    addr(uint(1)),
  5487  		wantErr: EU(strconv.ErrSyntax).withVal(`"100000000000000000000000000000x"`).withType('"', T[uint]()),
  5488  	}, {
  5489  		name:    jsontest.Name("Uints/Invalid/Whitespace"),
  5490  		opts:    []Options{StringifyNumbers(true)},
  5491  		inBuf:   `"0 "`,
  5492  		inVal:   addr(uint(1)),
  5493  		want:    addr(uint(1)),
  5494  		wantErr: EU(strconv.ErrSyntax).withVal(`"0 "`).withType('"', T[uint]()),
  5495  	}, {
  5496  		name:    jsontest.Name("Uints/Invalid/Bool"),
  5497  		inBuf:   `true`,
  5498  		inVal:   addr(uint(1)),
  5499  		want:    addr(uint(1)),
  5500  		wantErr: EU(nil).withType('t', T[uint]()),
  5501  	}, {
  5502  		name:    jsontest.Name("Uints/Invalid/String"),
  5503  		inBuf:   `"0"`,
  5504  		inVal:   addr(uint(1)),
  5505  		want:    addr(uint(1)),
  5506  		wantErr: EU(nil).withType('"', T[uint]()),
  5507  	}, {
  5508  		name:    jsontest.Name("Uints/Invalid/Object"),
  5509  		inBuf:   `{}`,
  5510  		inVal:   addr(uint(1)),
  5511  		want:    addr(uint(1)),
  5512  		wantErr: EU(nil).withType('{', T[uint]()),
  5513  	}, {
  5514  		name:    jsontest.Name("Uints/Invalid/Array"),
  5515  		inBuf:   `[]`,
  5516  		inVal:   addr(uint(1)),
  5517  		want:    addr(uint(1)),
  5518  		wantErr: EU(nil).withType('[', T[uint]()),
  5519  	}, {
  5520  		name:  jsontest.Name("Uints/IgnoreInvalidFormat"),
  5521  		opts:  []Options{invalidFormatOption},
  5522  		inBuf: `1`,
  5523  		inVal: addr(uint(0)),
  5524  		want:  addr(uint(1)),
  5525  	}, {
  5526  		name:  jsontest.Name("Floats/Null"),
  5527  		inBuf: `null`,
  5528  		inVal: addr(float64(64.64)),
  5529  		want:  addr(float64(0)),
  5530  	}, {
  5531  		name:  jsontest.Name("Floats/Float32/Pi"),
  5532  		inBuf: `3.14159265358979323846264338327950288419716939937510582097494459`,
  5533  		inVal: addr(float32(32.32)),
  5534  		want:  addr(float32(math.Pi)),
  5535  	}, {
  5536  		name:  jsontest.Name("Floats/Float32/Underflow"),
  5537  		inBuf: `1e-1000`,
  5538  		inVal: addr(float32(32.32)),
  5539  		want:  addr(float32(0)),
  5540  	}, {
  5541  		name:    jsontest.Name("Floats/Float32/Overflow"),
  5542  		inBuf:   `-1e1000`,
  5543  		inVal:   addr(float32(32.32)),
  5544  		want:    addr(float32(math.Inf(-1))),
  5545  		wantErr: EU(strconv.ErrRange).withVal(`-1e1000`).withType('0', T[float32]()),
  5546  	}, {
  5547  		name:  jsontest.Name("Floats/Float64/Pi"),
  5548  		inBuf: `3.14159265358979323846264338327950288419716939937510582097494459`,
  5549  		inVal: addr(float64(64.64)),
  5550  		want:  addr(float64(math.Pi)),
  5551  	}, {
  5552  		name:  jsontest.Name("Floats/Float64/Underflow"),
  5553  		inBuf: `1e-1000`,
  5554  		inVal: addr(float64(64.64)),
  5555  		want:  addr(float64(0)),
  5556  	}, {
  5557  		name:    jsontest.Name("Floats/Float64/Overflow"),
  5558  		inBuf:   `-1e1000`,
  5559  		inVal:   addr(float64(64.64)),
  5560  		want:    addr(float64(math.Inf(-1))),
  5561  		wantErr: EU(strconv.ErrRange).withVal(`-1e1000`).withType('0', T[float64]()),
  5562  	}, {
  5563  		name:    jsontest.Name("Floats/Any/Overflow"),
  5564  		inBuf:   `1e1000`,
  5565  		inVal:   new(any),
  5566  		want:    addr(any(float64(math.Inf(+1)))),
  5567  		wantErr: EU(strconv.ErrRange).withVal(`1e1000`).withType('0', T[float64]()),
  5568  	}, {
  5569  		name:  jsontest.Name("Floats/Named"),
  5570  		inBuf: `64.64`,
  5571  		inVal: addr(namedFloat64(0)),
  5572  		want:  addr(namedFloat64(64.64)),
  5573  	}, {
  5574  		name:  jsontest.Name("Floats/Stringified"),
  5575  		opts:  []Options{StringifyNumbers(true)},
  5576  		inBuf: `"64.64"`,
  5577  		inVal: new(float64),
  5578  		want:  addr(float64(64.64)),
  5579  	}, {
  5580  		name:    jsontest.Name("Floats/Stringified/Invalid"),
  5581  		opts:    []Options{StringifyNumbers(true)},
  5582  		inBuf:   `64.64`,
  5583  		inVal:   new(float64),
  5584  		want:    new(float64),
  5585  		wantErr: EU(nil).withType('0', T[float64]()),
  5586  	}, {
  5587  		name:  jsontest.Name("Floats/Escaped"),
  5588  		opts:  []Options{StringifyNumbers(true)},
  5589  		inBuf: `"\u0036\u0034\u002e\u0036\u0034"`,
  5590  		inVal: new(float64),
  5591  		want:  addr(float64(64.64)),
  5592  	}, {
  5593  		name:    jsontest.Name("Floats/Invalid/NaN"),
  5594  		opts:    []Options{StringifyNumbers(true)},
  5595  		inBuf:   `"NaN"`,
  5596  		inVal:   addr(float64(64.64)),
  5597  		want:    addr(float64(64.64)),
  5598  		wantErr: EU(strconv.ErrSyntax).withVal(`"NaN"`).withType('"', float64Type),
  5599  	}, {
  5600  		name:    jsontest.Name("Floats/Invalid/Infinity"),
  5601  		opts:    []Options{StringifyNumbers(true)},
  5602  		inBuf:   `"Infinity"`,
  5603  		inVal:   addr(float64(64.64)),
  5604  		want:    addr(float64(64.64)),
  5605  		wantErr: EU(strconv.ErrSyntax).withVal(`"Infinity"`).withType('"', float64Type),
  5606  	}, {
  5607  		name:    jsontest.Name("Floats/Invalid/Whitespace"),
  5608  		opts:    []Options{StringifyNumbers(true)},
  5609  		inBuf:   `"1 "`,
  5610  		inVal:   addr(float64(64.64)),
  5611  		want:    addr(float64(64.64)),
  5612  		wantErr: EU(strconv.ErrSyntax).withVal(`"1 "`).withType('"', float64Type),
  5613  	}, {
  5614  		name:    jsontest.Name("Floats/Invalid/GoSyntax"),
  5615  		opts:    []Options{StringifyNumbers(true)},
  5616  		inBuf:   `"1p-2"`,
  5617  		inVal:   addr(float64(64.64)),
  5618  		want:    addr(float64(64.64)),
  5619  		wantErr: EU(strconv.ErrSyntax).withVal(`"1p-2"`).withType('"', float64Type),
  5620  	}, {
  5621  		name:    jsontest.Name("Floats/Invalid/Bool"),
  5622  		inBuf:   `true`,
  5623  		inVal:   addr(float64(64.64)),
  5624  		want:    addr(float64(64.64)),
  5625  		wantErr: EU(nil).withType('t', float64Type),
  5626  	}, {
  5627  		name:    jsontest.Name("Floats/Invalid/String"),
  5628  		inBuf:   `"0"`,
  5629  		inVal:   addr(float64(64.64)),
  5630  		want:    addr(float64(64.64)),
  5631  		wantErr: EU(nil).withType('"', float64Type),
  5632  	}, {
  5633  		name:    jsontest.Name("Floats/Invalid/Object"),
  5634  		inBuf:   `{}`,
  5635  		inVal:   addr(float64(64.64)),
  5636  		want:    addr(float64(64.64)),
  5637  		wantErr: EU(nil).withType('{', float64Type),
  5638  	}, {
  5639  		name:    jsontest.Name("Floats/Invalid/Array"),
  5640  		inBuf:   `[]`,
  5641  		inVal:   addr(float64(64.64)),
  5642  		want:    addr(float64(64.64)),
  5643  		wantErr: EU(nil).withType('[', float64Type),
  5644  	}, {
  5645  		name:  jsontest.Name("Floats/IgnoreInvalidFormat"),
  5646  		opts:  []Options{invalidFormatOption},
  5647  		inBuf: `1`,
  5648  		inVal: addr(float64(0)),
  5649  		want:  addr(float64(1)),
  5650  	}, {
  5651  		name:  jsontest.Name("Maps/Null"),
  5652  		inBuf: `null`,
  5653  		inVal: addr(map[string]string{"key": "value"}),
  5654  		want:  new(map[string]string),
  5655  	}, {
  5656  		name:    jsontest.Name("Maps/InvalidKey/Bool"),
  5657  		inBuf:   `{"true":"false"}`,
  5658  		inVal:   new(map[bool]bool),
  5659  		want:    addr(make(map[bool]bool)),
  5660  		wantErr: EU(nil).withPos(`{`, "/true").withType('"', boolType),
  5661  	}, {
  5662  		name:    jsontest.Name("Maps/InvalidKey/NamedBool"),
  5663  		inBuf:   `{"true":"false"}`,
  5664  		inVal:   new(map[namedBool]bool),
  5665  		want:    addr(make(map[namedBool]bool)),
  5666  		wantErr: EU(nil).withPos(`{`, "/true").withType('"', T[namedBool]()),
  5667  	}, {
  5668  		name:    jsontest.Name("Maps/InvalidKey/Array"),
  5669  		inBuf:   `{"key":"value"}`,
  5670  		inVal:   new(map[[1]string]string),
  5671  		want:    addr(make(map[[1]string]string)),
  5672  		wantErr: EU(nil).withPos(`{`, "/key").withType('"', T[[1]string]()),
  5673  	}, {
  5674  		name:    jsontest.Name("Maps/InvalidKey/Channel"),
  5675  		inBuf:   `{"key":"value"}`,
  5676  		inVal:   new(map[chan string]string),
  5677  		want:    addr(make(map[chan string]string)),
  5678  		wantErr: EU(nil).withPos(`{`, "").withType(0, T[chan string]()),
  5679  	}, {
  5680  		name:  jsontest.Name("Maps/ValidKey/Int"),
  5681  		inBuf: `{"0":0,"-1":1,"2":2,"-3":3}`,
  5682  		inVal: new(map[int]int),
  5683  		want:  addr(map[int]int{0: 0, -1: 1, 2: 2, -3: 3}),
  5684  	}, {
  5685  		name:  jsontest.Name("Maps/ValidKey/NamedInt"),
  5686  		inBuf: `{"0":0,"-1":1,"2":2,"-3":3}`,
  5687  		inVal: new(map[namedInt64]int),
  5688  		want:  addr(map[namedInt64]int{0: 0, -1: 1, 2: 2, -3: 3}),
  5689  	}, {
  5690  		name:  jsontest.Name("Maps/ValidKey/Uint"),
  5691  		inBuf: `{"0":0,"1":1,"2":2,"3":3}`,
  5692  		inVal: new(map[uint]uint),
  5693  		want:  addr(map[uint]uint{0: 0, 1: 1, 2: 2, 3: 3}),
  5694  	}, {
  5695  		name:  jsontest.Name("Maps/ValidKey/NamedUint"),
  5696  		inBuf: `{"0":0,"1":1,"2":2,"3":3}`,
  5697  		inVal: new(map[namedUint64]uint),
  5698  		want:  addr(map[namedUint64]uint{0: 0, 1: 1, 2: 2, 3: 3}),
  5699  	}, {
  5700  		name:  jsontest.Name("Maps/ValidKey/Float"),
  5701  		inBuf: `{"1.234":1.234,"12.34":12.34,"123.4":123.4}`,
  5702  		inVal: new(map[float64]float64),
  5703  		want:  addr(map[float64]float64{1.234: 1.234, 12.34: 12.34, 123.4: 123.4}),
  5704  	}, {
  5705  		name:    jsontest.Name("Maps/DuplicateName/Int"),
  5706  		inBuf:   `{"0":1,"-0":-1}`,
  5707  		inVal:   new(map[int]int),
  5708  		want:    addr(map[int]int{0: 1}),
  5709  		wantErr: newDuplicateNameError("", []byte(`"-0"`), len64(`{"0":1,`)),
  5710  	}, {
  5711  		name:    jsontest.Name("Maps/DuplicateName/Int/MergeWithLegacySemantics"),
  5712  		opts:    []Options{jsonflags.MergeWithLegacySemantics | 1},
  5713  		inBuf:   `{"0":1,"-0":-1}`,
  5714  		inVal:   new(map[int]int),
  5715  		want:    addr(map[int]int{0: 1}),
  5716  		wantErr: newDuplicateNameError("", []byte(`"-0"`), len64(`{"0":1,`)),
  5717  	}, {
  5718  		name:  jsontest.Name("Maps/DuplicateName/Int/AllowDuplicateNames"),
  5719  		opts:  []Options{jsontext.AllowDuplicateNames(true)},
  5720  		inBuf: `{"0":1,"-0":-1}`,
  5721  		inVal: new(map[int]int),
  5722  		want:  addr(map[int]int{0: -1}), // latter takes precedence
  5723  	}, {
  5724  		name:  jsontest.Name("Maps/DuplicateName/Int/OverwriteExisting"),
  5725  		inBuf: `{"-0":-1}`,
  5726  		inVal: addr(map[int]int{0: 1}),
  5727  		want:  addr(map[int]int{0: -1}),
  5728  	}, {
  5729  		name:    jsontest.Name("Maps/DuplicateName/Float"),
  5730  		inBuf:   `{"1.0":"1.0","1":"1","1e0":"1e0"}`,
  5731  		inVal:   new(map[float64]string),
  5732  		want:    addr(map[float64]string{1: "1.0"}),
  5733  		wantErr: newDuplicateNameError("", []byte(`"1"`), len64(`{"1.0":"1.0",`)),
  5734  	}, {
  5735  		name:  jsontest.Name("Maps/DuplicateName/Float/AllowDuplicateNames"),
  5736  		opts:  []Options{jsontext.AllowDuplicateNames(true)},
  5737  		inBuf: `{"1.0":"1.0","1":"1","1e0":"1e0"}`,
  5738  		inVal: new(map[float64]string),
  5739  		want:  addr(map[float64]string{1: "1e0"}), // latter takes precedence
  5740  	}, {
  5741  		name:  jsontest.Name("Maps/DuplicateName/Float/OverwriteExisting"),
  5742  		inBuf: `{"1.0":"1.0"}`,
  5743  		inVal: addr(map[float64]string{1: "1"}),
  5744  		want:  addr(map[float64]string{1: "1.0"}),
  5745  	}, {
  5746  		name:    jsontest.Name("Maps/DuplicateName/NoCaseString"),
  5747  		inBuf:   `{"hello":"hello","HELLO":"HELLO"}`,
  5748  		inVal:   new(map[nocaseString]string),
  5749  		want:    addr(map[nocaseString]string{"hello": "hello"}),
  5750  		wantErr: newDuplicateNameError("", []byte(`"HELLO"`), len64(`{"hello":"hello",`)),
  5751  	}, {
  5752  		name:  jsontest.Name("Maps/DuplicateName/NoCaseString/AllowDuplicateNames"),
  5753  		opts:  []Options{jsontext.AllowDuplicateNames(true)},
  5754  		inBuf: `{"hello":"hello","HELLO":"HELLO"}`,
  5755  		inVal: new(map[nocaseString]string),
  5756  		want:  addr(map[nocaseString]string{"hello": "HELLO"}), // latter takes precedence
  5757  	}, {
  5758  		name:  jsontest.Name("Maps/DuplicateName/NoCaseString/OverwriteExisting"),
  5759  		opts:  []Options{jsontext.AllowDuplicateNames(true)},
  5760  		inBuf: `{"HELLO":"HELLO"}`,
  5761  		inVal: addr(map[nocaseString]string{"hello": "hello"}),
  5762  		want:  addr(map[nocaseString]string{"hello": "HELLO"}),
  5763  	}, {
  5764  		name:  jsontest.Name("Maps/ValidKey/Interface"),
  5765  		inBuf: `{"false":"false","true":"true","string":"string","0":"0","[]":"[]","{}":"{}"}`,
  5766  		inVal: new(map[any]string),
  5767  		want: addr(map[any]string{
  5768  			"false":  "false",
  5769  			"true":   "true",
  5770  			"string": "string",
  5771  			"0":      "0",
  5772  			"[]":     "[]",
  5773  			"{}":     "{}",
  5774  		}),
  5775  	}, {
  5776  		name:  jsontest.Name("Maps/InvalidValue/Channel"),
  5777  		inBuf: `{"key":"value"}`,
  5778  		inVal: new(map[string]chan string),
  5779  		want: addr(map[string]chan string{
  5780  			"key": nil,
  5781  		}),
  5782  		wantErr: EU(nil).withPos(`{"key":`, "/key").withType(0, T[chan string]()),
  5783  	}, {
  5784  		name:  jsontest.Name("Maps/RecursiveMap"),
  5785  		inBuf: `{"buzz":{},"fizz":{"bar":{},"foo":{}}}`,
  5786  		inVal: new(recursiveMap),
  5787  		want: addr(recursiveMap{
  5788  			"fizz": {
  5789  				"foo": {},
  5790  				"bar": {},
  5791  			},
  5792  			"buzz": {},
  5793  		}),
  5794  	}, {
  5795  		// NOTE: The semantics differs from v1,
  5796  		// where existing map entries were not merged into.
  5797  		// See https://go.dev/issue/31924.
  5798  		name:  jsontest.Name("Maps/Merge"),
  5799  		opts:  []Options{jsontext.AllowDuplicateNames(true)},
  5800  		inBuf: `{"k1":{"k2":"v2"},"k2":{"k1":"v1"},"k2":{"k2":"v2"}}`,
  5801  		inVal: addr(map[string]map[string]string{
  5802  			"k1": {"k1": "v1"},
  5803  		}),
  5804  		want: addr(map[string]map[string]string{
  5805  			"k1": {"k1": "v1", "k2": "v2"},
  5806  			"k2": {"k1": "v1", "k2": "v2"},
  5807  		}),
  5808  	}, {
  5809  		name:    jsontest.Name("Maps/Invalid/Bool"),
  5810  		inBuf:   `true`,
  5811  		inVal:   addr(map[string]string{"key": "value"}),
  5812  		want:    addr(map[string]string{"key": "value"}),
  5813  		wantErr: EU(nil).withType('t', T[map[string]string]()),
  5814  	}, {
  5815  		name:    jsontest.Name("Maps/Invalid/String"),
  5816  		inBuf:   `""`,
  5817  		inVal:   addr(map[string]string{"key": "value"}),
  5818  		want:    addr(map[string]string{"key": "value"}),
  5819  		wantErr: EU(nil).withType('"', T[map[string]string]()),
  5820  	}, {
  5821  		name:    jsontest.Name("Maps/Invalid/Number"),
  5822  		inBuf:   `0`,
  5823  		inVal:   addr(map[string]string{"key": "value"}),
  5824  		want:    addr(map[string]string{"key": "value"}),
  5825  		wantErr: EU(nil).withType('0', T[map[string]string]()),
  5826  	}, {
  5827  		name:    jsontest.Name("Maps/Invalid/Array"),
  5828  		inBuf:   `[]`,
  5829  		inVal:   addr(map[string]string{"key": "value"}),
  5830  		want:    addr(map[string]string{"key": "value"}),
  5831  		wantErr: EU(nil).withType('[', T[map[string]string]()),
  5832  	}, {
  5833  		name:  jsontest.Name("Maps/IgnoreInvalidFormat"),
  5834  		opts:  []Options{invalidFormatOption},
  5835  		inBuf: `{"hello":"goodbye"}`,
  5836  		inVal: addr(map[string]string{}),
  5837  		want:  addr(map[string]string{"hello": "goodbye"}),
  5838  	}, {
  5839  		name:  jsontest.Name("Structs/Null"),
  5840  		inBuf: `null`,
  5841  		inVal: addr(structAll{String: "something"}),
  5842  		want:  addr(structAll{}),
  5843  	}, {
  5844  		name:  jsontest.Name("Structs/Empty"),
  5845  		inBuf: `{}`,
  5846  		inVal: addr(structAll{
  5847  			String: "hello",
  5848  			Map:    map[string]string{},
  5849  			Slice:  []string{},
  5850  		}),
  5851  		want: addr(structAll{
  5852  			String: "hello",
  5853  			Map:    map[string]string{},
  5854  			Slice:  []string{},
  5855  		}),
  5856  	}, {
  5857  		name: jsontest.Name("Structs/Normal"),
  5858  		inBuf: `{
  5859  	"Bool": true,
  5860  	"String": "hello",
  5861  	"Bytes": "AQID",
  5862  	"Int": -64,
  5863  	"Uint": 64,
  5864  	"Float": 3.14159,
  5865  	"Map": {"key": "value"},
  5866  	"StructScalars": {
  5867  		"Bool": true,
  5868  		"String": "hello",
  5869  		"Bytes": "AQID",
  5870  		"Int": -64,
  5871  		"Uint": 64,
  5872  		"Float": 3.14159
  5873  	},
  5874  	"StructMaps": {
  5875  		"MapBool": {"": true},
  5876  		"MapString": {"": "hello"},
  5877  		"MapBytes": {"": "AQID"},
  5878  		"MapInt": {"": -64},
  5879  		"MapUint": {"": 64},
  5880  		"MapFloat": {"": 3.14159}
  5881  	},
  5882  	"StructSlices": {
  5883  		"SliceBool": [true],
  5884  		"SliceString": ["hello"],
  5885  		"SliceBytes": ["AQID"],
  5886  		"SliceInt": [-64],
  5887  		"SliceUint": [64],
  5888  		"SliceFloat": [3.14159]
  5889  	},
  5890  	"Slice": ["fizz","buzz"],
  5891  	"Array": ["goodbye"],
  5892  	"Pointer": {},
  5893  	"Interface": null
  5894  }`,
  5895  		inVal: new(structAll),
  5896  		want: addr(structAll{
  5897  			Bool:   true,
  5898  			String: "hello",
  5899  			Bytes:  []byte{1, 2, 3},
  5900  			Int:    -64,
  5901  			Uint:   +64,
  5902  			Float:  3.14159,
  5903  			Map:    map[string]string{"key": "value"},
  5904  			StructScalars: structScalars{
  5905  				Bool:   true,
  5906  				String: "hello",
  5907  				Bytes:  []byte{1, 2, 3},
  5908  				Int:    -64,
  5909  				Uint:   +64,
  5910  				Float:  3.14159,
  5911  			},
  5912  			StructMaps: structMaps{
  5913  				MapBool:   map[string]bool{"": true},
  5914  				MapString: map[string]string{"": "hello"},
  5915  				MapBytes:  map[string][]byte{"": {1, 2, 3}},
  5916  				MapInt:    map[string]int64{"": -64},
  5917  				MapUint:   map[string]uint64{"": +64},
  5918  				MapFloat:  map[string]float64{"": 3.14159},
  5919  			},
  5920  			StructSlices: structSlices{
  5921  				SliceBool:   []bool{true},
  5922  				SliceString: []string{"hello"},
  5923  				SliceBytes:  [][]byte{{1, 2, 3}},
  5924  				SliceInt:    []int64{-64},
  5925  				SliceUint:   []uint64{+64},
  5926  				SliceFloat:  []float64{3.14159},
  5927  			},
  5928  			Slice:   []string{"fizz", "buzz"},
  5929  			Array:   [1]string{"goodbye"},
  5930  			Pointer: new(structAll),
  5931  		}),
  5932  	}, {
  5933  		name: jsontest.Name("Structs/Merge"),
  5934  		inBuf: `{
  5935  	"Bool": false,
  5936  	"String": "goodbye",
  5937  	"Int": -64,
  5938  	"Float": 3.14159,
  5939  	"Map": {"k2": "v2"},
  5940  	"StructScalars": {
  5941  		"Bool": true,
  5942  		"String": "hello",
  5943  		"Bytes": "AQID",
  5944  		"Int": -64
  5945  	},
  5946  	"StructMaps": {
  5947  		"MapBool": {"": true},
  5948  		"MapString": {"": "hello"},
  5949  		"MapBytes": {"": "AQID"},
  5950  		"MapInt": {"": -64},
  5951  		"MapUint": {"": 64},
  5952  		"MapFloat": {"": 3.14159}
  5953  	},
  5954  	"StructSlices": {
  5955  		"SliceString": ["hello"],
  5956  		"SliceBytes": ["AQID"],
  5957  		"SliceInt": [-64],
  5958  		"SliceUint": [64]
  5959  	},
  5960  	"Slice": ["fizz","buzz"],
  5961  	"Array": ["goodbye"],
  5962  	"Pointer": {},
  5963  	"Interface": {"k2":"v2"}
  5964  }`,
  5965  		inVal: addr(structAll{
  5966  			Bool:   true,
  5967  			String: "hello",
  5968  			Bytes:  []byte{1, 2, 3},
  5969  			Uint:   +64,
  5970  			Float:  math.NaN(),
  5971  			Map:    map[string]string{"k1": "v1"},
  5972  			StructScalars: structScalars{
  5973  				String: "hello",
  5974  				Bytes:  make([]byte, 2, 4),
  5975  				Uint:   +64,
  5976  				Float:  3.14159,
  5977  			},
  5978  			StructMaps: structMaps{
  5979  				MapBool:  map[string]bool{"": false},
  5980  				MapBytes: map[string][]byte{"": {}},
  5981  				MapInt:   map[string]int64{"": 123},
  5982  				MapFloat: map[string]float64{"": math.Inf(+1)},
  5983  			},
  5984  			StructSlices: structSlices{
  5985  				SliceBool:  []bool{true},
  5986  				SliceBytes: [][]byte{nil, nil},
  5987  				SliceInt:   []int64{-123},
  5988  				SliceUint:  []uint64{+123},
  5989  				SliceFloat: []float64{3.14159},
  5990  			},
  5991  			Slice:     []string{"buzz", "fizz", "gizz"},
  5992  			Array:     [1]string{"hello"},
  5993  			Pointer:   new(structAll),
  5994  			Interface: map[string]string{"k1": "v1"},
  5995  		}),
  5996  		want: addr(structAll{
  5997  			Bool:   false,
  5998  			String: "goodbye",
  5999  			Bytes:  []byte{1, 2, 3},
  6000  			Int:    -64,
  6001  			Uint:   +64,
  6002  			Float:  3.14159,
  6003  			Map:    map[string]string{"k1": "v1", "k2": "v2"},
  6004  			StructScalars: structScalars{
  6005  				Bool:   true,
  6006  				String: "hello",
  6007  				Bytes:  []byte{1, 2, 3},
  6008  				Int:    -64,
  6009  				Uint:   +64,
  6010  				Float:  3.14159,
  6011  			},
  6012  			StructMaps: structMaps{
  6013  				MapBool:   map[string]bool{"": true},
  6014  				MapString: map[string]string{"": "hello"},
  6015  				MapBytes:  map[string][]byte{"": {1, 2, 3}},
  6016  				MapInt:    map[string]int64{"": -64},
  6017  				MapUint:   map[string]uint64{"": +64},
  6018  				MapFloat:  map[string]float64{"": 3.14159},
  6019  			},
  6020  			StructSlices: structSlices{
  6021  				SliceBool:   []bool{true},
  6022  				SliceString: []string{"hello"},
  6023  				SliceBytes:  [][]byte{{1, 2, 3}},
  6024  				SliceInt:    []int64{-64},
  6025  				SliceUint:   []uint64{+64},
  6026  				SliceFloat:  []float64{3.14159},
  6027  			},
  6028  			Slice:     []string{"fizz", "buzz"},
  6029  			Array:     [1]string{"goodbye"},
  6030  			Pointer:   new(structAll),
  6031  			Interface: map[string]string{"k1": "v1", "k2": "v2"},
  6032  		}),
  6033  	}, {
  6034  		name: jsontest.Name("Structs/Stringified"),
  6035  		inBuf: `{
  6036  	"Int": "-64",
  6037  	"Uint": "64",
  6038  	"Float": "3.14159",
  6039  	"PointerInt": "-64",
  6040  	"PointerUint": "64",
  6041  	"PointerFloat": "3.14159"
  6042  }`,
  6043  		inVal: new(structStringified),
  6044  		want: addr(structStringified{
  6045  			Int:          -64,
  6046  			Uint:         +64,
  6047  			Float:        3.14159,
  6048  			PointerInt:   new(int64(-64)),
  6049  			PointerUint:  new(uint64(+64)),
  6050  			PointerFloat: new(float64(3.14159)),
  6051  		}),
  6052  	}, {
  6053  		name:    jsontest.Name("Structs/Stringified/Invalid/EmptyIntString"),
  6054  		inBuf:   `{"Int":""}`,
  6055  		inVal:   new(structStringified),
  6056  		want:    new(structStringified),
  6057  		wantErr: EU(strconv.ErrSyntax).withVal(`""`).withPos(`{"Int":`, "/Int").withType('"', T[int64]()),
  6058  	}, {
  6059  		name:    jsontest.Name("Structs/Stringified/Invalid/Bool"),
  6060  		inBuf:   `{"Bool": "true"}`,
  6061  		inVal:   new(structStringifiedBool),
  6062  		want:    new(structStringifiedBool),
  6063  		wantErr: EU(errInvalidStringTag).withPos(`{"Bool": `, "/Bool").withType(0, T[bool]()),
  6064  	}, {
  6065  		name:  jsontest.Name("Structs/Stringified/Ignored/Bool"),
  6066  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6067  		inBuf: `{"Bool": true}`,
  6068  		inVal: new(structStringifiedBool),
  6069  		want:  new(structStringifiedBool{Bool: true}),
  6070  	}, {
  6071  		name:    jsontest.Name("Structs/Stringified/Invalid/String"),
  6072  		inBuf:   `{"String": "\"hello\""}`,
  6073  		inVal:   new(structStringifiedString),
  6074  		want:    new(structStringifiedString),
  6075  		wantErr: EU(errInvalidStringTag).withPos(`{"String": `, "/String").withType(0, T[string]()),
  6076  	}, {
  6077  		name:  jsontest.Name("Structs/Stringified/Ignored/String"),
  6078  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6079  		inBuf: `{"String": "\"hello\""}`,
  6080  		inVal: new(structStringifiedString),
  6081  		want:  new(structStringifiedString{String: `"hello"`}),
  6082  	}, {
  6083  		name:    jsontest.Name("Structs/Stringified/Invalid/Bytes"),
  6084  		inBuf:   `{"Bytes": "AQID"}`,
  6085  		inVal:   new(structStringifiedBytes),
  6086  		want:    new(structStringifiedBytes),
  6087  		wantErr: EU(errInvalidStringTag).withPos(`{"Bytes": `, "/Bytes").withType(0, T[[]byte]()),
  6088  	}, {
  6089  		name:  jsontest.Name("Structs/Stringified/Ignored/Bytes"),
  6090  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6091  		inBuf: `{"Bytes": "AQID"}`,
  6092  		inVal: new(structStringifiedBytes),
  6093  		want:  new(structStringifiedBytes{Bytes: []byte{1, 2, 3}}),
  6094  	}, {
  6095  		name:    jsontest.Name("Structs/Stringified/Invalid/Map"),
  6096  		inBuf:   `{"Map": {"Key": "Value"}}`,
  6097  		inVal:   new(structStringifiedMap),
  6098  		want:    new(structStringifiedMap),
  6099  		wantErr: EU(errInvalidStringTag).withPos(`{"Map": `, "/Map").withType(0, T[map[string]string]()),
  6100  	}, {
  6101  		name:  jsontest.Name("Structs/Stringified/Ignored/Map"),
  6102  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6103  		inBuf: `{"Map": {"Key": "Value"}}`,
  6104  		inVal: new(structStringifiedMap),
  6105  		want:  new(structStringifiedMap{Map: map[string]string{"Key": "Value"}}),
  6106  	}, {
  6107  		name:    jsontest.Name("Structs/Stringified/Invalid/Slice"),
  6108  		inBuf:   `{"Slice": ["hello"]}`,
  6109  		inVal:   new(structStringifiedSlice),
  6110  		want:    new(structStringifiedSlice),
  6111  		wantErr: EU(errInvalidStringTag).withPos(`{"Slice": `, "/Slice").withType(0, T[[]string]()),
  6112  	}, {
  6113  		name:  jsontest.Name("Structs/Stringified/Ignored/Slice"),
  6114  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6115  		inBuf: `{"Slice": ["hello"]}`,
  6116  		inVal: new(structStringifiedSlice),
  6117  		want:  new(structStringifiedSlice{Slice: []string{"hello"}}),
  6118  	}, {
  6119  		name:    jsontest.Name("Structs/Stringified/Invalid/Array"),
  6120  		inBuf:   `{"Array": ["hello"]}`,
  6121  		inVal:   new(structStringifiedArray),
  6122  		want:    new(structStringifiedArray),
  6123  		wantErr: EU(errInvalidStringTag).withPos(`{"Array": `, "/Array").withType(0, T[[1]string]()),
  6124  	}, {
  6125  		name:  jsontest.Name("Structs/Stringified/Ignored/Array"),
  6126  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6127  		inBuf: `{"Array": ["hello"]}`,
  6128  		inVal: new(structStringifiedArray),
  6129  		want:  new(structStringifiedArray{Array: [1]string{"hello"}}),
  6130  	}, {
  6131  		name:    jsontest.Name("Structs/Stringified/Invalid/Struct"),
  6132  		inBuf:   `{"Struct": {"Bool": true}}`,
  6133  		inVal:   new(structStringifiedStruct),
  6134  		want:    new(structStringifiedStruct),
  6135  		wantErr: EU(errInvalidStringTag).withPos(`{"Struct": `, "/Struct").withType(0, T[structAll]()),
  6136  	}, {
  6137  		name:  jsontest.Name("Structs/Stringified/Ignored/Struct"),
  6138  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6139  		inBuf: `{"Struct": {"Bool": true}}`,
  6140  		inVal: new(structStringifiedStruct),
  6141  		want:  new(structStringifiedStruct{Struct: structAll{Bool: true}}),
  6142  	}, {
  6143  		name:    jsontest.Name("Structs/Stringified/Invalid/Pointer"),
  6144  		inBuf:   `{"Pointer": {"Bool": true}}`,
  6145  		inVal:   new(structStringifiedPointer),
  6146  		want:    new(structStringifiedPointer{Pointer: new(structAll)}),
  6147  		wantErr: EU(errInvalidStringTag).withPos(`{"Pointer": `, "/Pointer").withType(0, T[structAll]()),
  6148  	}, {
  6149  		name:  jsontest.Name("Structs/Stringified/Ignored/Pointer"),
  6150  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6151  		inBuf: `{"Pointer": {"Bool": true}}`,
  6152  		inVal: new(structStringifiedPointer),
  6153  		want:  new(structStringifiedPointer{Pointer: new(structAll{Bool: true})}),
  6154  	}, {
  6155  		name:  jsontest.Name("Structs/Stringified/PointerPointerInt"),
  6156  		inBuf: `{"Pointer": "5"}`,
  6157  		inVal: new(structStringifiedPointerPointerInt),
  6158  		want:  new(structStringifiedPointerPointerInt{Pointer: new(new(5))}),
  6159  	}, {
  6160  		name:    jsontest.Name("Structs/Stringified/Invalid/Interface"),
  6161  		inBuf:   `{"Interface": null}`,
  6162  		inVal:   new(structStringifiedInterface),
  6163  		want:    new(structStringifiedInterface),
  6164  		wantErr: EU(errInvalidStringTag).withPos(`{"Interface": `, "/Interface").withType(0, T[any]()),
  6165  	}, {
  6166  		name:  jsontest.Name("Structs/Stringified/Ignored/Interface"),
  6167  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  6168  		inBuf: `{"Interface": null}`,
  6169  		inVal: new(structStringifiedInterface),
  6170  		want:  new(structStringifiedInterface),
  6171  	}, {
  6172  		name: jsontest.Name("Structs/LegacyStringified"),
  6173  		opts: []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6174  		inBuf: `{
  6175  	"Bool": "true",
  6176  	"String": "\"hello\"",
  6177  	"Int": "-64",
  6178  	"Uint": "64",
  6179  	"Float": "3.14159",
  6180  	"PointerBool": "true",
  6181  	"PointerString": "\"hello\"",
  6182  	"PointerInt": "-64",
  6183  	"PointerUint": "64",
  6184  	"PointerFloat": "3.14159"
  6185  }`,
  6186  		inVal: new(structStringifiedLegacy),
  6187  		want: addr(structStringifiedLegacy{
  6188  			Bool:          true,
  6189  			String:        "hello",
  6190  			Int:           -64,
  6191  			Uint:          +64,
  6192  			Float:         3.14159,
  6193  			PointerBool:   new(true),
  6194  			PointerString: new("hello"),
  6195  			PointerInt:    new(int64(-64)),
  6196  			PointerUint:   new(uint64(+64)),
  6197  			PointerFloat:  new(float64(3.14159)),
  6198  		}),
  6199  	}, {
  6200  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/EmptyIntString"),
  6201  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6202  		inBuf:   `{"Int":""}`,
  6203  		inVal:   new(structStringifiedLegacy),
  6204  		want:    new(structStringifiedLegacy),
  6205  		wantErr: EU(strconv.ErrSyntax).withVal(`""`).withPos(`{"Int":`, "/Int").withType('"', T[int64]()),
  6206  	}, {
  6207  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Bool"),
  6208  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6209  		inBuf:   `{"Bool": true}`,
  6210  		inVal:   new(structStringifiedLegacy),
  6211  		wantErr: EU(nil).withPos(`{"Bool": `, "/Bool").withType('t', T[bool]()),
  6212  	}, {
  6213  		name:  jsontest.Name("Structs/LegacyStringified/Invalid/String"),
  6214  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6215  		inBuf: `{"String": "string"}`,
  6216  		inVal: new(structStringifiedLegacy),
  6217  		wantErr: EU(newInvalidCharacterError("s", "at start of string (expecting '\"')", 0, "")).
  6218  			withPos(`{"String": `, "/String").withType('"', T[string]()),
  6219  	}, {
  6220  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Bytes"),
  6221  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6222  		inBuf:   `{"Bytes": "AQID"}`,
  6223  		inVal:   new(structStringifiedBytes),
  6224  		want:    new(structStringifiedBytes),
  6225  		wantErr: EU(errInvalidStringTag).withPos(`{"Bytes": `, "/Bytes").withType(0, T[[]byte]()),
  6226  	}, {
  6227  		name:  jsontest.Name("Structs/LegacyStringified/Ignored/Bytes"),
  6228  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  6229  		inBuf: `{"Bytes": "AQID"}`,
  6230  		inVal: new(structStringifiedBytes),
  6231  		want:  new(structStringifiedBytes{Bytes: []byte{1, 2, 3}}),
  6232  	}, {
  6233  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Map"),
  6234  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6235  		inBuf:   `{"Map": {"Key": "Value"}}`,
  6236  		inVal:   new(structStringifiedMap),
  6237  		want:    new(structStringifiedMap),
  6238  		wantErr: EU(errInvalidStringTag).withPos(`{"Map": `, "/Map").withType(0, T[map[string]string]()),
  6239  	}, {
  6240  		name:  jsontest.Name("Structs/LegacyStringified/Ignored/Map"),
  6241  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  6242  		inBuf: `{"Map": {"Key": "Value"}}`,
  6243  		inVal: new(structStringifiedMap),
  6244  		want:  new(structStringifiedMap{Map: map[string]string{"Key": "Value"}}),
  6245  	}, {
  6246  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Slice"),
  6247  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6248  		inBuf:   `{"Slice": ["hello"]}`,
  6249  		inVal:   new(structStringifiedSlice),
  6250  		want:    new(structStringifiedSlice),
  6251  		wantErr: EU(errInvalidStringTag).withPos(`{"Slice": `, "/Slice").withType(0, T[[]string]()),
  6252  	}, {
  6253  		name:  jsontest.Name("Structs/LegacyStringified/Ignored/Slice"),
  6254  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  6255  		inBuf: `{"Slice": ["hello"]}`,
  6256  		inVal: new(structStringifiedSlice),
  6257  		want:  new(structStringifiedSlice{Slice: []string{"hello"}}),
  6258  	}, {
  6259  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Array"),
  6260  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6261  		inBuf:   `{"Array": ["hello"]}`,
  6262  		inVal:   new(structStringifiedArray),
  6263  		want:    new(structStringifiedArray),
  6264  		wantErr: EU(errInvalidStringTag).withPos(`{"Array": `, "/Array").withType(0, T[[1]string]()),
  6265  	}, {
  6266  		name:  jsontest.Name("Structs/LegacyStringified/Ignored/Array"),
  6267  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  6268  		inBuf: `{"Array": ["hello"]}`,
  6269  		inVal: new(structStringifiedArray),
  6270  		want:  new(structStringifiedArray{Array: [1]string{"hello"}}),
  6271  	}, {
  6272  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Struct"),
  6273  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6274  		inBuf:   `{"Struct": {"Bool": true}}`,
  6275  		inVal:   new(structStringifiedStruct),
  6276  		want:    new(structStringifiedStruct),
  6277  		wantErr: EU(errInvalidStringTag).withPos(`{"Struct": `, "/Struct").withType(0, T[structAll]()),
  6278  	}, {
  6279  		name:  jsontest.Name("Structs/LegacyStringified/Ignored/Struct"),
  6280  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  6281  		inBuf: `{"Struct": {"Bool": true}}`,
  6282  		inVal: new(structStringifiedStruct),
  6283  		want:  new(structStringifiedStruct{Struct: structAll{Bool: true}}),
  6284  	}, {
  6285  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Pointer"),
  6286  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6287  		inBuf:   `{"Pointer": {"Bool": true}}`,
  6288  		inVal:   new(structStringifiedPointer),
  6289  		want:    new(structStringifiedPointer{Pointer: new(structAll)}),
  6290  		wantErr: EU(errInvalidStringTag).withPos(`{"Pointer": `, "/Pointer").withType(0, T[structAll]()),
  6291  	}, {
  6292  		name:  jsontest.Name("Structs/LegacyStringified/Ignored/Pointer"),
  6293  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  6294  		inBuf: `{"Pointer": {"Bool": true}}`,
  6295  		inVal: new(structStringifiedPointer),
  6296  		want:  new(structStringifiedPointer{Pointer: new(structAll{Bool: true})}),
  6297  	}, {
  6298  		name:    jsontest.Name("Structs/Stringified/Invalid/PointerPointerInt"),
  6299  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6300  		inBuf:   `{"Pointer": 5}`,
  6301  		inVal:   new(structStringifiedPointerPointerInt),
  6302  		want:    new(structStringifiedPointerPointerInt{}),
  6303  		wantErr: EU(errInvalidStringTag).withPos(`{"Pointer": `, "/Pointer").withType(0, T[**int]()),
  6304  	}, {
  6305  		name:  jsontest.Name("Structs/Stringified/Ignored/PointerPointerInt"),
  6306  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | jsonflags.ReportErrorsWithLegacySemantics | 1},
  6307  		inBuf: `{"Pointer": 5}`,
  6308  		inVal: new(structStringifiedPointerPointerInt),
  6309  		want:  new(structStringifiedPointerPointerInt{Pointer: new(new(5))}),
  6310  	}, {
  6311  		name:    jsontest.Name("Structs/LegacyStringified/Invalid/Interface"),
  6312  		opts:    []Options{jsonflags.StringifyWithLegacySemantics | 1},
  6313  		inBuf:   `{"Interface": null}`,
  6314  		inVal:   new(structStringifiedInterface),
  6315  		want:    new(structStringifiedInterface),
  6316  		wantErr: EU(errInvalidStringTag).withPos(`{"Interface": `, "/Interface").withType(0, T[any]()),
  6317  	}, {
  6318  		name:  jsontest.Name("Structs/LegacyStringified/Ignored/Interface"),
  6319  		opts:  []Options{jsonflags.StringifyWithLegacySemantics | 1, jsonflags.ReportErrorsWithLegacySemantics | 1},
  6320  		inBuf: `{"Interface": null}`,
  6321  		inVal: new(structStringifiedInterface),
  6322  		want:  new(structStringifiedInterface),
  6323  	}, {
  6324  		name:    jsontest.Name("Structs/Format/Bytes/Unsupported"),
  6325  		inBuf:   `{}`,
  6326  		inVal:   new(structFormatBytes),
  6327  		wantErr: EU(errors.New("Go struct field Base16 has unsupported `format` tag option")).withType('{', T[structFormatBytes]()),
  6328  	}, {
  6329  		name: jsontest.Name("Structs/Format/Bytes"),
  6330  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6331  		inBuf: `{
  6332  	"Base16": "0123456789abcdef",
  6333  	"Base32": "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
  6334  	"Base32Hex": "0123456789ABCDEFGHIJKLMNOPQRSTUV",
  6335  	"Base64": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  6336  	"Base64URL": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
  6337  	"Array": [1, 2, 3, 4]
  6338  }`,
  6339  		inVal: new(structFormatBytes),
  6340  		want: addr(structFormatBytes{
  6341  			Base16:    []byte("\x01\x23\x45\x67\x89\xab\xcd\xef"),
  6342  			Base32:    []byte("\x00D2\x14\xc7BT\xb65τe:V\xd7\xc6u\xbew\xdf"),
  6343  			Base32Hex: []byte("\x00D2\x14\xc7BT\xb65τe:V\xd7\xc6u\xbew\xdf"),
  6344  			Base64:    []byte("\x00\x10\x83\x10Q\x87 \x92\x8b0ӏA\x14\x93QU\x97a\x96\x9bqן\x82\x18\xa3\x92Y\xa7\xa2\x9a\xab\xb2ۯ\xc3\x1c\xb3\xd3]\xb7㞻\xf3߿"),
  6345  			Base64URL: []byte("\x00\x10\x83\x10Q\x87 \x92\x8b0ӏA\x14\x93QU\x97a\x96\x9bqן\x82\x18\xa3\x92Y\xa7\xa2\x9a\xab\xb2ۯ\xc3\x1c\xb3\xd3]\xb7㞻\xf3߿"),
  6346  			Array:     []byte{1, 2, 3, 4},
  6347  		}),
  6348  	}, {
  6349  		name: jsontest.Name("Structs/Format/ArrayBytes"),
  6350  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6351  		inBuf: `{
  6352  	"Base16": "01020304",
  6353  	"Base32": "AEBAGBA=",
  6354  	"Base32Hex": "0410610=",
  6355  	"Base64": "AQIDBA==",
  6356  	"Base64URL": "AQIDBA==",
  6357  	"Array": [1, 2, 3, 4],
  6358  	"Default": "AQIDBA=="
  6359  }`,
  6360  		inVal: new(structFormatArrayBytes),
  6361  		want: addr(structFormatArrayBytes{
  6362  			Base16:    [4]byte{1, 2, 3, 4},
  6363  			Base32:    [4]byte{1, 2, 3, 4},
  6364  			Base32Hex: [4]byte{1, 2, 3, 4},
  6365  			Base64:    [4]byte{1, 2, 3, 4},
  6366  			Base64URL: [4]byte{1, 2, 3, 4},
  6367  			Array:     [4]byte{1, 2, 3, 4},
  6368  			Default:   [4]byte{1, 2, 3, 4},
  6369  		}),
  6370  	}, {
  6371  		name: jsontest.Name("Structs/Format/ArrayBytes/Legacy"),
  6372  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true), jsonflags.FormatBytesWithLegacySemantics | 1},
  6373  		inBuf: `{
  6374  	"Base16": "01020304",
  6375  	"Base32": "AEBAGBA=",
  6376  	"Base32Hex": "0410610=",
  6377  	"Base64": "AQIDBA==",
  6378  	"Base64URL": "AQIDBA==",
  6379  	"Array": [1, 2, 3, 4],
  6380  	"Default": [1, 2, 3, 4]
  6381  }`,
  6382  		inVal: new(structFormatArrayBytes),
  6383  		want: addr(structFormatArrayBytes{
  6384  			Base16:    [4]byte{1, 2, 3, 4},
  6385  			Base32:    [4]byte{1, 2, 3, 4},
  6386  			Base32Hex: [4]byte{1, 2, 3, 4},
  6387  			Base64:    [4]byte{1, 2, 3, 4},
  6388  			Base64URL: [4]byte{1, 2, 3, 4},
  6389  			Array:     [4]byte{1, 2, 3, 4},
  6390  			Default:   [4]byte{1, 2, 3, 4},
  6391  		}),
  6392  	}, {
  6393  		name: jsontest.Name("Structs/Format/Bytes/Array"),
  6394  		opts: []Options{
  6395  			jsonopts.ExperimentalSupportFormatTag(true),
  6396  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *byte) error {
  6397  				if string(b) == "true" {
  6398  					*v = 1
  6399  				} else {
  6400  					*v = 0
  6401  				}
  6402  				return nil
  6403  			})),
  6404  		},
  6405  		inBuf: `{"Array":[false,true,false,true,false,true]}`,
  6406  		inVal: new(struct {
  6407  			Array []byte `json:",format:array"`
  6408  		}),
  6409  		want: addr(struct {
  6410  			Array []byte `json:",format:array"`
  6411  		}{
  6412  			Array: []byte{0, 1, 0, 1, 0, 1},
  6413  		}),
  6414  	}, {
  6415  		name:    jsontest.Name("Structs/Format/Bytes/Invalid/Base16/WrongKind"),
  6416  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6417  		inBuf:   `{"Base16": [1,2,3,4]}`,
  6418  		inVal:   new(structFormatBytes),
  6419  		wantErr: EU(nil).withPos(`{"Base16": `, "/Base16").withType('[', T[[]byte]()),
  6420  	}, {
  6421  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base16/AllPadding"),
  6422  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6423  		inBuf: `{"Base16": "===="}`,
  6424  		inVal: new(structFormatBytes),
  6425  		wantErr: EU(func() error {
  6426  			_, err := hex.Decode(make([]byte, 2), []byte("====="))
  6427  			return err
  6428  		}()).withPos(`{"Base16": `, "/Base16").withType('"', T[[]byte]()),
  6429  	}, {
  6430  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base16/EvenPadding"),
  6431  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6432  		inBuf: `{"Base16": "0123456789abcdef="}`,
  6433  		inVal: new(structFormatBytes),
  6434  		wantErr: EU(func() error {
  6435  			_, err := hex.Decode(make([]byte, 8), []byte("0123456789abcdef="))
  6436  			return err
  6437  		}()).withPos(`{"Base16": `, "/Base16").withType('"', T[[]byte]()),
  6438  	}, {
  6439  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base16/OddPadding"),
  6440  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6441  		inBuf: `{"Base16": "0123456789abcdef0="}`,
  6442  		inVal: new(structFormatBytes),
  6443  		wantErr: EU(func() error {
  6444  			_, err := hex.Decode(make([]byte, 9), []byte("0123456789abcdef0="))
  6445  			return err
  6446  		}()).withPos(`{"Base16": `, "/Base16").withType('"', T[[]byte]()),
  6447  	}, {
  6448  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base16/NonAlphabet/LineFeed"),
  6449  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6450  		inBuf: `{"Base16": "aa\naa"}`,
  6451  		inVal: new(structFormatBytes),
  6452  		wantErr: EU(func() error {
  6453  			_, err := hex.Decode(make([]byte, 9), []byte("aa\naa"))
  6454  			return err
  6455  		}()).withPos(`{"Base16": `, "/Base16").withType('"', T[[]byte]()),
  6456  	}, {
  6457  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base16/NonAlphabet/CarriageReturn"),
  6458  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6459  		inBuf: `{"Base16": "aa\raa"}`,
  6460  		inVal: new(structFormatBytes),
  6461  		wantErr: EU(func() error {
  6462  			_, err := hex.Decode(make([]byte, 9), []byte("aa\raa"))
  6463  			return err
  6464  		}()).withPos(`{"Base16": `, "/Base16").withType('"', T[[]byte]()),
  6465  	}, {
  6466  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base16/NonAlphabet/Space"),
  6467  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6468  		inBuf: `{"Base16": "aa aa"}`,
  6469  		inVal: new(structFormatBytes),
  6470  		wantErr: EU(func() error {
  6471  			_, err := hex.Decode(make([]byte, 9), []byte("aa aa"))
  6472  			return err
  6473  		}()).withPos(`{"Base16": `, "/Base16").withType('"', T[[]byte]()),
  6474  	}, {
  6475  		name: jsontest.Name("Structs/Format/Bytes/Invalid/Base32/Padding"),
  6476  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6477  		inBuf: `[
  6478  			{"Base32": "NA======"},
  6479  			{"Base32": "NBSQ===="},
  6480  			{"Base32": "NBSWY==="},
  6481  			{"Base32": "NBSWY3A="},
  6482  			{"Base32": "NBSWY3DP"}
  6483  		]`,
  6484  		inVal: new([]structFormatBytes),
  6485  		want: addr([]structFormatBytes{
  6486  			{Base32: []byte("h")},
  6487  			{Base32: []byte("he")},
  6488  			{Base32: []byte("hel")},
  6489  			{Base32: []byte("hell")},
  6490  			{Base32: []byte("hello")},
  6491  		}),
  6492  	}, {
  6493  		name: jsontest.Name("Structs/Format/Bytes/Invalid/Base32/Invalid/NoPadding"),
  6494  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6495  		inBuf: `[
  6496  				{"Base32": "NA"},
  6497  				{"Base32": "NBSQ"},
  6498  				{"Base32": "NBSWY"},
  6499  				{"Base32": "NBSWY3A"},
  6500  				{"Base32": "NBSWY3DP"}
  6501  			]`,
  6502  		inVal: new([]structFormatBytes),
  6503  		wantErr: EU(func() error {
  6504  			_, err := base32.StdEncoding.Decode(make([]byte, 1), []byte("NA"))
  6505  			return err
  6506  		}()).withPos(`[`+"\n\t\t\t\t"+`{"Base32": `, "/0/Base32").withType('"', T[[]byte]()),
  6507  	}, {
  6508  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base32/WrongAlphabet"),
  6509  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6510  		inBuf: `{"Base32": "0123456789ABCDEFGHIJKLMNOPQRSTUV"}`,
  6511  		inVal: new(structFormatBytes),
  6512  		wantErr: EU(func() error {
  6513  			_, err := base32.StdEncoding.Decode(make([]byte, 20), []byte("0123456789ABCDEFGHIJKLMNOPQRSTUV"))
  6514  			return err
  6515  		}()).withPos(`{"Base32": `, "/Base32").withType('"', T[[]byte]()),
  6516  	}, {
  6517  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base32Hex/WrongAlphabet"),
  6518  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6519  		inBuf: `{"Base32Hex": "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"}`,
  6520  		inVal: new(structFormatBytes),
  6521  		wantErr: EU(func() error {
  6522  			_, err := base32.HexEncoding.Decode(make([]byte, 20), []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"))
  6523  			return err
  6524  		}()).withPos(`{"Base32Hex": `, "/Base32Hex").withType('"', T[[]byte]()),
  6525  	}, {
  6526  		name:    jsontest.Name("Structs/Format/Bytes/Invalid/Base32/NonAlphabet/LineFeed"),
  6527  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6528  		inBuf:   `{"Base32": "AAAA\nAAAA"}`,
  6529  		inVal:   new(structFormatBytes),
  6530  		wantErr: EU(errors.New("illegal character '\\n' at offset 4")).withPos(`{"Base32": `, "/Base32").withType('"', T[[]byte]()),
  6531  	}, {
  6532  		name:    jsontest.Name("Structs/Format/Bytes/Invalid/Base32/NonAlphabet/CarriageReturn"),
  6533  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6534  		inBuf:   `{"Base32": "AAAA\rAAAA"}`,
  6535  		inVal:   new(structFormatBytes),
  6536  		wantErr: EU(errors.New("illegal character '\\r' at offset 4")).withPos(`{"Base32": `, "/Base32").withType('"', T[[]byte]()),
  6537  	}, {
  6538  		name:    jsontest.Name("Structs/Format/Bytes/Invalid/Base32/NonAlphabet/Space"),
  6539  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6540  		inBuf:   `{"Base32": "AAAA AAAA"}`,
  6541  		inVal:   new(structFormatBytes),
  6542  		wantErr: EU(base32.CorruptInputError(4)).withPos(`{"Base32": `, "/Base32").withType('"', T[[]byte]()),
  6543  	}, {
  6544  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base64/WrongAlphabet"),
  6545  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6546  		inBuf: `{"Base64": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"}`,
  6547  		inVal: new(structFormatBytes),
  6548  		wantErr: EU(func() error {
  6549  			_, err := base64.StdEncoding.Decode(make([]byte, 48), []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"))
  6550  			return err
  6551  		}()).withPos(`{"Base64": `, "/Base64").withType('"', T[[]byte]()),
  6552  	}, {
  6553  		name:  jsontest.Name("Structs/Format/Bytes/Invalid/Base64URL/WrongAlphabet"),
  6554  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6555  		inBuf: `{"Base64URL": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"}`,
  6556  		inVal: new(structFormatBytes),
  6557  		wantErr: EU(func() error {
  6558  			_, err := base64.URLEncoding.Decode(make([]byte, 48), []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"))
  6559  			return err
  6560  		}()).withPos(`{"Base64URL": `, "/Base64URL").withType('"', T[[]byte]()),
  6561  	}, {
  6562  		name:    jsontest.Name("Structs/Format/Bytes/Invalid/Base64/NonAlphabet/LineFeed"),
  6563  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6564  		inBuf:   `{"Base64": "aa=\n="}`,
  6565  		inVal:   new(structFormatBytes),
  6566  		wantErr: EU(errors.New("illegal character '\\n' at offset 3")).withPos(`{"Base64": `, "/Base64").withType('"', T[[]byte]()),
  6567  	}, {
  6568  		name:    jsontest.Name("Structs/Format/Bytes/Invalid/Base64/NonAlphabet/CarriageReturn"),
  6569  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6570  		inBuf:   `{"Base64": "aa=\r="}`,
  6571  		inVal:   new(structFormatBytes),
  6572  		wantErr: EU(errors.New("illegal character '\\r' at offset 3")).withPos(`{"Base64": `, "/Base64").withType('"', T[[]byte]()),
  6573  	}, {
  6574  		name:  jsontest.Name("Structs/Format/Bytes/Base64/NonAlphabet/Ignored"),
  6575  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true), jsonflags.ParseBytesWithLooseRFC4648 | 1},
  6576  		inBuf: `{"Base64": "aa=\r\n="}`,
  6577  		inVal: new(structFormatBytes),
  6578  		want:  &structFormatBytes{Base64: []byte{105}},
  6579  	}, {
  6580  		name:    jsontest.Name("Structs/Format/Bytes/Invalid/Base64/NonAlphabet/Space"),
  6581  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6582  		inBuf:   `{"Base64": "aa= ="}`,
  6583  		inVal:   new(structFormatBytes),
  6584  		wantErr: EU(base64.CorruptInputError(2)).withPos(`{"Base64": `, "/Base64").withType('"', T[[]byte]()),
  6585  	}, {
  6586  		name: jsontest.Name("Structs/Format/Floats"),
  6587  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6588  		inBuf: `[
  6589  	{"NonFinite": 3.141592653589793, "PointerNonFinite": 3.141592653589793},
  6590  	{"NonFinite": "-Infinity", "PointerNonFinite": "-Infinity"},
  6591  	{"NonFinite": "Infinity", "PointerNonFinite": "Infinity"}
  6592  ]`,
  6593  		inVal: new([]structFormatFloats),
  6594  		want: addr([]structFormatFloats{
  6595  			{NonFinite: math.Pi, PointerNonFinite: addr(math.Pi)},
  6596  			{NonFinite: math.Inf(-1), PointerNonFinite: addr(math.Inf(-1))},
  6597  			{NonFinite: math.Inf(+1), PointerNonFinite: addr(math.Inf(+1))},
  6598  		}),
  6599  	}, {
  6600  		name:  jsontest.Name("Structs/Format/Floats/NaN"),
  6601  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6602  		inBuf: `{"NonFinite": "NaN"}`,
  6603  		inVal: new(structFormatFloats),
  6604  		// Avoid checking want since reflect.DeepEqual fails for NaNs.
  6605  	}, {
  6606  		name:    jsontest.Name("Structs/Format/Floats/Invalid/NaN"),
  6607  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6608  		inBuf:   `{"NonFinite": "nan"}`,
  6609  		inVal:   new(structFormatFloats),
  6610  		wantErr: EU(nil).withPos(`{"NonFinite": `, "/NonFinite").withType('"', T[float64]()),
  6611  	}, {
  6612  		name:    jsontest.Name("Structs/Format/Floats/Invalid/PositiveInfinity"),
  6613  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6614  		inBuf:   `{"NonFinite": "+Infinity"}`,
  6615  		inVal:   new(structFormatFloats),
  6616  		wantErr: EU(nil).withPos(`{"NonFinite": `, "/NonFinite").withType('"', T[float64]()),
  6617  	}, {
  6618  		name:    jsontest.Name("Structs/Format/Floats/Invalid/NegativeInfinitySpace"),
  6619  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6620  		inBuf:   `{"NonFinite": "-Infinity "}`,
  6621  		inVal:   new(structFormatFloats),
  6622  		wantErr: EU(nil).withPos(`{"NonFinite": `, "/NonFinite").withType('"', T[float64]()),
  6623  	}, {
  6624  		name: jsontest.Name("Structs/Format/Maps"),
  6625  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6626  		inBuf: `[
  6627  	{"EmitNull": null, "PointerEmitNull": null, "EmitEmpty": null, "PointerEmitEmpty": null, "EmitDefault": null, "PointerEmitDefault": null},
  6628  	{"EmitNull": {}, "PointerEmitNull": {}, "EmitEmpty": {}, "PointerEmitEmpty": {}, "EmitDefault": {}, "PointerEmitDefault": {}},
  6629  	{"EmitNull": {"k": "v"}, "PointerEmitNull": {"k": "v"}, "EmitEmpty": {"k": "v"}, "PointerEmitEmpty": {"k": "v"}, "EmitDefault": {"k": "v"}, "PointerEmitDefault": {"k": "v"}}
  6630  ]`,
  6631  		inVal: new([]structFormatMaps),
  6632  		want: addr([]structFormatMaps{{
  6633  			EmitNull: map[string]string(nil), PointerEmitNull: (*map[string]string)(nil),
  6634  			EmitEmpty: map[string]string(nil), PointerEmitEmpty: (*map[string]string)(nil),
  6635  			EmitDefault: map[string]string(nil), PointerEmitDefault: (*map[string]string)(nil),
  6636  		}, {
  6637  			EmitNull: map[string]string{}, PointerEmitNull: addr(map[string]string{}),
  6638  			EmitEmpty: map[string]string{}, PointerEmitEmpty: addr(map[string]string{}),
  6639  			EmitDefault: map[string]string{}, PointerEmitDefault: addr(map[string]string{}),
  6640  		}, {
  6641  			EmitNull: map[string]string{"k": "v"}, PointerEmitNull: addr(map[string]string{"k": "v"}),
  6642  			EmitEmpty: map[string]string{"k": "v"}, PointerEmitEmpty: addr(map[string]string{"k": "v"}),
  6643  			EmitDefault: map[string]string{"k": "v"}, PointerEmitDefault: addr(map[string]string{"k": "v"}),
  6644  		}}),
  6645  	}, {
  6646  		name: jsontest.Name("Structs/Format/Slices"),
  6647  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6648  		inBuf: `[
  6649  	{"EmitNull": null, "PointerEmitNull": null, "EmitEmpty": null, "PointerEmitEmpty": null, "EmitDefault": null, "PointerEmitDefault": null},
  6650  	{"EmitNull": [], "PointerEmitNull": [], "EmitEmpty": [], "PointerEmitEmpty": [], "EmitDefault": [], "PointerEmitDefault": []},
  6651  	{"EmitNull": ["v"], "PointerEmitNull": ["v"], "EmitEmpty": ["v"], "PointerEmitEmpty": ["v"], "EmitDefault": ["v"], "PointerEmitDefault": ["v"]}
  6652  ]`,
  6653  		inVal: new([]structFormatSlices),
  6654  		want: addr([]structFormatSlices{{
  6655  			EmitNull: []string(nil), PointerEmitNull: (*[]string)(nil),
  6656  			EmitEmpty: []string(nil), PointerEmitEmpty: (*[]string)(nil),
  6657  			EmitDefault: []string(nil), PointerEmitDefault: (*[]string)(nil),
  6658  		}, {
  6659  			EmitNull: []string{}, PointerEmitNull: addr([]string{}),
  6660  			EmitEmpty: []string{}, PointerEmitEmpty: addr([]string{}),
  6661  			EmitDefault: []string{}, PointerEmitDefault: addr([]string{}),
  6662  		}, {
  6663  			EmitNull: []string{"v"}, PointerEmitNull: addr([]string{"v"}),
  6664  			EmitEmpty: []string{"v"}, PointerEmitEmpty: addr([]string{"v"}),
  6665  			EmitDefault: []string{"v"}, PointerEmitDefault: addr([]string{"v"}),
  6666  		}}),
  6667  	}, {
  6668  		name:    jsontest.Name("Structs/Format/Invalid/Bool"),
  6669  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6670  		inBuf:   `{"Bool":true}`,
  6671  		inVal:   new(structFormatInvalid),
  6672  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Bool":`, "/Bool").withType(0, T[bool]()),
  6673  	}, {
  6674  		name:    jsontest.Name("Structs/Format/Invalid/String"),
  6675  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6676  		inBuf:   `{"String": "string"}`,
  6677  		inVal:   new(structFormatInvalid),
  6678  		wantErr: EU(errInvalidFormatFlag).withPos(`{"String": `, "/String").withType(0, T[string]()),
  6679  	}, {
  6680  		name:    jsontest.Name("Structs/Format/Invalid/Bytes"),
  6681  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6682  		inBuf:   `{"Bytes": "bytes"}`,
  6683  		inVal:   new(structFormatInvalid),
  6684  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Bytes": `, "/Bytes").withType(0, T[[]byte]()),
  6685  	}, {
  6686  		name:    jsontest.Name("Structs/Format/Invalid/Int"),
  6687  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6688  		inBuf:   `{"Int":   1}`,
  6689  		inVal:   new(structFormatInvalid),
  6690  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Int":   `, "/Int").withType(0, T[int64]()),
  6691  	}, {
  6692  		name:    jsontest.Name("Structs/Format/Invalid/Uint"),
  6693  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6694  		inBuf:   `{"Uint": 1}`,
  6695  		inVal:   new(structFormatInvalid),
  6696  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Uint": `, "/Uint").withType(0, T[uint64]()),
  6697  	}, {
  6698  		name:    jsontest.Name("Structs/Format/Invalid/Float"),
  6699  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6700  		inBuf:   `{"Float" : 1}`,
  6701  		inVal:   new(structFormatInvalid),
  6702  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Float" : `, "/Float").withType(0, T[float64]()),
  6703  	}, {
  6704  		name:    jsontest.Name("Structs/Format/Invalid/Map"),
  6705  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6706  		inBuf:   `{"Map":{}}`,
  6707  		inVal:   new(structFormatInvalid),
  6708  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Map":`, "/Map").withType(0, T[map[string]string]()),
  6709  	}, {
  6710  		name:    jsontest.Name("Structs/Format/Invalid/Struct"),
  6711  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6712  		inBuf:   `{"Struct": {}}`,
  6713  		inVal:   new(structFormatInvalid),
  6714  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Struct": `, "/Struct").withType(0, T[structAll]()),
  6715  	}, {
  6716  		name:    jsontest.Name("Structs/Format/Invalid/Slice"),
  6717  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6718  		inBuf:   `{"Slice": {}}`,
  6719  		inVal:   new(structFormatInvalid),
  6720  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Slice": `, "/Slice").withType(0, T[[]string]()),
  6721  	}, {
  6722  		name:    jsontest.Name("Structs/Format/Invalid/Array"),
  6723  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6724  		inBuf:   `{"Array": []}`,
  6725  		inVal:   new(structFormatInvalid),
  6726  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Array": `, "/Array").withType(0, T[[1]string]()),
  6727  	}, {
  6728  		name:    jsontest.Name("Structs/Format/Invalid/Interface"),
  6729  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  6730  		inBuf:   `{"Interface": "anything"}`,
  6731  		inVal:   new(structFormatInvalid),
  6732  		wantErr: EU(errInvalidFormatFlag).withPos(`{"Interface": `, "/Interface").withType(0, T[any]()),
  6733  	}, {
  6734  		name:  jsontest.Name("Structs/Embed/Zero"),
  6735  		inBuf: `{"D":""}`,
  6736  		inVal: new(structEmbedded),
  6737  		want:  new(structEmbedded),
  6738  	}, {
  6739  		name:  jsontest.Name("Structs/Embed/Alloc"),
  6740  		inBuf: `{"E":"","F":"","G":"","A":"","B":"","D":""}`,
  6741  		inVal: new(structEmbedded),
  6742  		want: addr(structEmbedded{
  6743  			X: structEmbeddedL1{
  6744  				X:            &structEmbeddedL2{},
  6745  				StructEmbed1: StructEmbed1{},
  6746  			},
  6747  			StructEmbed2: &StructEmbed2{},
  6748  		}),
  6749  	}, {
  6750  		name:  jsontest.Name("Structs/Embed/NonZero"),
  6751  		inBuf: `{"E":"E3","F":"F3","G":"G3","A":"A1","B":"B1","D":"D2"}`,
  6752  		inVal: new(structEmbedded),
  6753  		want: addr(structEmbedded{
  6754  			X: structEmbeddedL1{
  6755  				X:            &structEmbeddedL2{A: "A1", B: "B1" /* C: "C1" */},
  6756  				StructEmbed1: StructEmbed1{ /* C: "C2" */ D: "D2" /* E: "E2" */},
  6757  			},
  6758  			StructEmbed2: &StructEmbed2{E: "E3", F: "F3", G: "G3"},
  6759  		}),
  6760  	}, {
  6761  		name:  jsontest.Name("Structs/Embed/Merge"),
  6762  		inBuf: `{"E":"E3","F":"F3","G":"G3","A":"A1","B":"B1","D":"D2"}`,
  6763  		inVal: addr(structEmbedded{
  6764  			X: structEmbeddedL1{
  6765  				X:            &structEmbeddedL2{B: "##", C: "C1"},
  6766  				StructEmbed1: StructEmbed1{C: "C2", E: "E2"},
  6767  			},
  6768  			StructEmbed2: &StructEmbed2{E: "##", G: "G3"},
  6769  		}),
  6770  		want: addr(structEmbedded{
  6771  			X: structEmbeddedL1{
  6772  				X:            &structEmbeddedL2{A: "A1", B: "B1", C: "C1"},
  6773  				StructEmbed1: StructEmbed1{C: "C2", D: "D2", E: "E2"},
  6774  			},
  6775  			StructEmbed2: &StructEmbed2{E: "E3", F: "F3", G: "G3"},
  6776  		}),
  6777  	}, {
  6778  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/Noop"),
  6779  		inBuf: `{"A":1,"B":2}`,
  6780  		inVal: new(structEmbedTextValue),
  6781  		want:  addr(structEmbedTextValue{A: 1, X: jsontext.Value(nil), B: 2}),
  6782  	}, {
  6783  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/MergeN1/Nil"),
  6784  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  6785  		inVal: new(structEmbedTextValue),
  6786  		want:  addr(structEmbedTextValue{A: 1, X: jsontext.Value(`{"fizz":"buzz"}`), B: 2}),
  6787  	}, {
  6788  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/MergeN1/Empty"),
  6789  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  6790  		inVal: addr(structEmbedTextValue{X: jsontext.Value{}}),
  6791  		want:  addr(structEmbedTextValue{A: 1, X: jsontext.Value(`{"fizz":"buzz"}`), B: 2}),
  6792  	}, {
  6793  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/MergeN1/Whitespace"),
  6794  		inBuf:   `{"A":1,"fizz":"buzz","B":2}`,
  6795  		inVal:   addr(structEmbedTextValue{X: jsontext.Value("\n\r\t ")}),
  6796  		want:    addr(structEmbedTextValue{A: 1, X: jsontext.Value("")}),
  6797  		wantErr: EU(errRawEmbedNotObject).withPos(`{"A":1,`, "/fizz").withType('"', T[jsontext.Value]()),
  6798  	}, {
  6799  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/MergeN1/Null"),
  6800  		inBuf:   `{"A":1,"fizz":"buzz","B":2}`,
  6801  		inVal:   addr(structEmbedTextValue{X: jsontext.Value("null")}),
  6802  		want:    addr(structEmbedTextValue{A: 1, X: jsontext.Value("null")}),
  6803  		wantErr: EU(errRawEmbedNotObject).withPos(`{"A":1,`, "/fizz").withType('"', T[jsontext.Value]()),
  6804  	}, {
  6805  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/MergeN1/ObjectN0"),
  6806  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  6807  		inVal: addr(structEmbedTextValue{X: jsontext.Value(` { } `)}),
  6808  		want:  addr(structEmbedTextValue{A: 1, X: jsontext.Value(` {"fizz":"buzz"}`), B: 2}),
  6809  	}, {
  6810  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/MergeN2/ObjectN1"),
  6811  		inBuf: `{"A":1,"fizz":"buzz","B":2,"foo": [ 1 , 2 , 3 ]}`,
  6812  		inVal: addr(structEmbedTextValue{X: jsontext.Value(` { "fizz" : "buzz" } `)}),
  6813  		want:  addr(structEmbedTextValue{A: 1, X: jsontext.Value(` { "fizz" : "buzz","fizz":"buzz","foo":[ 1 , 2 , 3 ]}`), B: 2}),
  6814  	}, {
  6815  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/Merge/EndObject"),
  6816  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  6817  		inVal: addr(structEmbedTextValue{X: jsontext.Value(` } `)}),
  6818  		// NOTE: This produces invalid output,
  6819  		// but the value being merged into is already invalid.
  6820  		want: addr(structEmbedTextValue{A: 1, X: jsontext.Value(`,"fizz":"buzz"}`), B: 2}),
  6821  	}, {
  6822  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/MergeInvalidValue"),
  6823  		inBuf:   `{"A":1,"fizz":nil,"B":2}`,
  6824  		inVal:   new(structEmbedTextValue),
  6825  		want:    addr(structEmbedTextValue{A: 1, X: jsontext.Value(`{"fizz":`)}),
  6826  		wantErr: newInvalidCharacterError("i", "in literal null (expecting 'u')", len64(`{"A":1,"fizz":n`), "/fizz"),
  6827  	}, {
  6828  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/CaseSensitive"),
  6829  		inBuf: `{"A":1,"fizz":"buzz","B":2,"a":3}`,
  6830  		inVal: new(structEmbedTextValue),
  6831  		want:  addr(structEmbedTextValue{A: 1, X: jsontext.Value(`{"fizz":"buzz","a":3}`), B: 2}),
  6832  	}, {
  6833  		name:    jsontest.Name("Structs/EmbeddedFallback/TextValue/RejectDuplicateNames"),
  6834  		opts:    []Options{jsontext.AllowDuplicateNames(false)},
  6835  		inBuf:   `{"A":1,"fizz":"buzz","B":2,"fizz":"buzz"}`,
  6836  		inVal:   new(structEmbedTextValue),
  6837  		want:    addr(structEmbedTextValue{A: 1, X: jsontext.Value(`{"fizz":"buzz"}`), B: 2}),
  6838  		wantErr: newDuplicateNameError("", []byte(`"fizz"`), len64(`{"A":1,"fizz":"buzz","B":2,`)),
  6839  	}, {
  6840  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/AllowDuplicateNames"),
  6841  		opts:  []Options{jsontext.AllowDuplicateNames(true)},
  6842  		inBuf: `{"A":1,"fizz":"buzz","B":2,"fizz":"buzz"}`,
  6843  		inVal: new(structEmbedTextValue),
  6844  		want:  addr(structEmbedTextValue{A: 1, X: jsontext.Value(`{"fizz":"buzz","fizz":"buzz"}`), B: 2}),
  6845  	}, {
  6846  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/Nested/Noop"),
  6847  		inBuf: `{}`,
  6848  		inVal: new(structEmbedPointerEmbedTextValue),
  6849  		want:  new(structEmbedPointerEmbedTextValue),
  6850  	}, {
  6851  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/Nested/Alloc"),
  6852  		inBuf: `{"A":1,"fizz":"buzz"}`,
  6853  		inVal: new(structEmbedPointerEmbedTextValue),
  6854  		want: addr(structEmbedPointerEmbedTextValue{
  6855  			X: &struct {
  6856  				A int
  6857  				X jsontext.Value `json:",embed"`
  6858  			}{A: 1, X: jsontext.Value(`{"fizz":"buzz"}`)},
  6859  		}),
  6860  	}, {
  6861  		name:  jsontest.Name("Structs/EmbeddedFallback/TextValue/Nested/Merge"),
  6862  		inBuf: `{"fizz":"buzz"}`,
  6863  		inVal: addr(structEmbedPointerEmbedTextValue{
  6864  			X: &struct {
  6865  				A int
  6866  				X jsontext.Value `json:",embed"`
  6867  			}{A: 1},
  6868  		}),
  6869  		want: addr(structEmbedPointerEmbedTextValue{
  6870  			X: &struct {
  6871  				A int
  6872  				X jsontext.Value `json:",embed"`
  6873  			}{A: 1, X: jsontext.Value(`{"fizz":"buzz"}`)},
  6874  		}),
  6875  	}, {
  6876  		name:  jsontest.Name("Structs/EmbeddedFallback/PointerTextValue/Noop"),
  6877  		inBuf: `{"A":1,"B":2}`,
  6878  		inVal: new(structEmbedPointerTextValue),
  6879  		want:  addr(structEmbedPointerTextValue{A: 1, X: nil, B: 2}),
  6880  	}, {
  6881  		name:  jsontest.Name("Structs/EmbeddedFallback/PointerTextValue/Alloc"),
  6882  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  6883  		inVal: new(structEmbedPointerTextValue),
  6884  		want:  addr(structEmbedPointerTextValue{A: 1, X: addr(jsontext.Value(`{"fizz":"buzz"}`)), B: 2}),
  6885  	}, {
  6886  		name:  jsontest.Name("Structs/EmbeddedFallback/PointerTextValue/Merge"),
  6887  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  6888  		inVal: addr(structEmbedPointerTextValue{X: addr(jsontext.Value(`{"fizz":"buzz"}`))}),
  6889  		want:  addr(structEmbedPointerTextValue{A: 1, X: addr(jsontext.Value(`{"fizz":"buzz","fizz":"buzz"}`)), B: 2}),
  6890  	}, {
  6891  		name:  jsontest.Name("Structs/EmbeddedFallback/PointerTextValue/Nested/Nil"),
  6892  		inBuf: `{"fizz":"buzz"}`,
  6893  		inVal: new(structEmbedEmbedPointerTextValue),
  6894  		want: addr(structEmbedEmbedPointerTextValue{
  6895  			X: struct {
  6896  				X *jsontext.Value `json:",embed"`
  6897  			}{X: addr(jsontext.Value(`{"fizz":"buzz"}`))},
  6898  		}),
  6899  	}, {
  6900  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/Noop"),
  6901  		inBuf: `{"A":1,"B":2}`,
  6902  		inVal: new(structEmbedMapStringAny),
  6903  		want:  addr(structEmbedMapStringAny{A: 1, X: nil, B: 2}),
  6904  	}, {
  6905  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/MergeN1/Nil"),
  6906  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  6907  		inVal: new(structEmbedMapStringAny),
  6908  		want:  addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": "buzz"}, B: 2}),
  6909  	}, {
  6910  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/MergeN1/Empty"),
  6911  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  6912  		inVal: addr(structEmbedMapStringAny{X: jsonObject{}}),
  6913  		want:  addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": "buzz"}, B: 2}),
  6914  	}, {
  6915  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/MergeN1/ObjectN1"),
  6916  		inBuf: `{"A":1,"fizz":{"charlie":"DELTA","echo":"foxtrot"},"B":2}`,
  6917  		inVal: addr(structEmbedMapStringAny{X: jsonObject{"fizz": jsonObject{
  6918  			"alpha":   "bravo",
  6919  			"charlie": "delta",
  6920  		}}}),
  6921  		want: addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": jsonObject{
  6922  			"alpha":   "bravo",
  6923  			"charlie": "DELTA",
  6924  			"echo":    "foxtrot",
  6925  		}}, B: 2}),
  6926  	}, {
  6927  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/MergeN2/ObjectN1"),
  6928  		inBuf: `{"A":1,"fizz":"buzz","B":2,"foo": [ 1 , 2 , 3 ]}`,
  6929  		inVal: addr(structEmbedMapStringAny{X: jsonObject{"fizz": "wuzz"}}),
  6930  		want:  addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": "buzz", "foo": jsonArray{1.0, 2.0, 3.0}}, B: 2}),
  6931  	}, {
  6932  		name:    jsontest.Name("Structs/EmbeddedFallback/MapStringAny/MergeInvalidValue"),
  6933  		inBuf:   `{"A":1,"fizz":nil,"B":2}`,
  6934  		inVal:   new(structEmbedMapStringAny),
  6935  		want:    addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": nil}}),
  6936  		wantErr: newInvalidCharacterError("i", "in literal null (expecting 'u')", len64(`{"A":1,"fizz":n`), "/fizz"),
  6937  	}, {
  6938  		name:    jsontest.Name("Structs/EmbeddedFallback/MapStringAny/MergeInvalidValue/Existing"),
  6939  		inBuf:   `{"A":1,"fizz":nil,"B":2}`,
  6940  		inVal:   addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": true}}),
  6941  		want:    addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": true}}),
  6942  		wantErr: newInvalidCharacterError("i", "in literal null (expecting 'u')", len64(`{"A":1,"fizz":n`), "/fizz"),
  6943  	}, {
  6944  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/CaseSensitive"),
  6945  		inBuf: `{"A":1,"fizz":"buzz","B":2,"a":3}`,
  6946  		inVal: new(structEmbedMapStringAny),
  6947  		want:  addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": "buzz", "a": 3.0}, B: 2}),
  6948  	}, {
  6949  		name:    jsontest.Name("Structs/EmbeddedFallback/MapStringAny/RejectDuplicateNames"),
  6950  		opts:    []Options{jsontext.AllowDuplicateNames(false)},
  6951  		inBuf:   `{"A":1,"fizz":"buzz","B":2,"fizz":"buzz"}`,
  6952  		inVal:   new(structEmbedMapStringAny),
  6953  		want:    addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": "buzz"}, B: 2}),
  6954  		wantErr: newDuplicateNameError("", []byte(`"fizz"`), len64(`{"A":1,"fizz":"buzz","B":2,`)),
  6955  	}, {
  6956  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/AllowDuplicateNames"),
  6957  		opts:  []Options{jsontext.AllowDuplicateNames(true)},
  6958  		inBuf: `{"A":1,"fizz":{"one":1,"two":-2},"B":2,"fizz":{"two":2,"three":3}}`,
  6959  		inVal: new(structEmbedMapStringAny),
  6960  		want:  addr(structEmbedMapStringAny{A: 1, X: jsonObject{"fizz": jsonObject{"one": 1.0, "two": 2.0, "three": 3.0}}, B: 2}),
  6961  	}, {
  6962  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/Nested/Noop"),
  6963  		inBuf: `{}`,
  6964  		inVal: new(structEmbedPointerEmbedMapStringAny),
  6965  		want:  new(structEmbedPointerEmbedMapStringAny),
  6966  	}, {
  6967  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/Nested/Alloc"),
  6968  		inBuf: `{"A":1,"fizz":"buzz"}`,
  6969  		inVal: new(structEmbedPointerEmbedMapStringAny),
  6970  		want: addr(structEmbedPointerEmbedMapStringAny{
  6971  			X: &struct {
  6972  				A int
  6973  				X jsonObject `json:",embed"`
  6974  			}{A: 1, X: jsonObject{"fizz": "buzz"}},
  6975  		}),
  6976  	}, {
  6977  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringAny/Nested/Merge"),
  6978  		inBuf: `{"fizz":"buzz"}`,
  6979  		inVal: addr(structEmbedPointerEmbedMapStringAny{
  6980  			X: &struct {
  6981  				A int
  6982  				X jsonObject `json:",embed"`
  6983  			}{A: 1},
  6984  		}),
  6985  		want: addr(structEmbedPointerEmbedMapStringAny{
  6986  			X: &struct {
  6987  				A int
  6988  				X jsonObject `json:",embed"`
  6989  			}{A: 1, X: jsonObject{"fizz": "buzz"}},
  6990  		}),
  6991  	}, {
  6992  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringInt/UnmarshalFunc"),
  6993  		opts: []Options{
  6994  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *any) error {
  6995  				var err error
  6996  				*v, err = strconv.ParseFloat(string(bytes.Trim(b, `"`)), 64)
  6997  				return err
  6998  			})),
  6999  		},
  7000  		inBuf: `{"D":"1.1","E":"2.2","F":"3.3"}`,
  7001  		inVal: new(structEmbedMapStringAny),
  7002  		want:  addr(structEmbedMapStringAny{X: jsonObject{"D": 1.1, "E": 2.2, "F": 3.3}}),
  7003  	}, {
  7004  		name:  jsontest.Name("Structs/EmbeddedFallback/PointerMapStringAny/Noop"),
  7005  		inBuf: `{"A":1,"B":2}`,
  7006  		inVal: new(structEmbedPointerMapStringAny),
  7007  		want:  addr(structEmbedPointerMapStringAny{A: 1, X: nil, B: 2}),
  7008  	}, {
  7009  		name:  jsontest.Name("Structs/EmbeddedFallback/PointerMapStringAny/Alloc"),
  7010  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  7011  		inVal: new(structEmbedPointerMapStringAny),
  7012  		want:  addr(structEmbedPointerMapStringAny{A: 1, X: addr(jsonObject{"fizz": "buzz"}), B: 2}),
  7013  	}, {
  7014  		name:  jsontest.Name("Structs/EmbeddedFallback/PointerMapStringAny/Merge"),
  7015  		inBuf: `{"A":1,"fizz":"wuzz","B":2}`,
  7016  		inVal: addr(structEmbedPointerMapStringAny{X: addr(jsonObject{"fizz": "buzz"})}),
  7017  		want:  addr(structEmbedPointerMapStringAny{A: 1, X: addr(jsonObject{"fizz": "wuzz"}), B: 2}),
  7018  	}, {
  7019  		name:  jsontest.Name("Structs/EmbeddedFallback/PointerMapStringAny/Nested/Nil"),
  7020  		inBuf: `{"fizz":"buzz"}`,
  7021  		inVal: new(structEmbedEmbedPointerMapStringAny),
  7022  		want: addr(structEmbedEmbedPointerMapStringAny{
  7023  			X: struct {
  7024  				X *jsonObject `json:",embed"`
  7025  			}{X: addr(jsonObject{"fizz": "buzz"})},
  7026  		}),
  7027  	}, {
  7028  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringInt"),
  7029  		inBuf: `{"zero": 0, "one": 1, "two": 2}`,
  7030  		inVal: new(structEmbedMapStringInt),
  7031  		want: addr(structEmbedMapStringInt{
  7032  			X: map[string]int{"zero": 0, "one": 1, "two": 2},
  7033  		}),
  7034  	}, {
  7035  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringInt/Null"),
  7036  		inBuf: `{"zero": 0, "one": null, "two": 2}`,
  7037  		inVal: new(structEmbedMapStringInt),
  7038  		want: addr(structEmbedMapStringInt{
  7039  			X: map[string]int{"zero": 0, "one": 0, "two": 2},
  7040  		}),
  7041  	}, {
  7042  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringInt/Invalid"),
  7043  		inBuf: `{"zero": 0, "one": {}, "two": 2}`,
  7044  		inVal: new(structEmbedMapStringInt),
  7045  		want: addr(structEmbedMapStringInt{
  7046  			X: map[string]int{"zero": 0, "one": 0},
  7047  		}),
  7048  		wantErr: EU(nil).withPos(`{"zero": 0, "one": `, "/one").withType('{', T[int]()),
  7049  	}, {
  7050  		name:  jsontest.Name("Structs/EmbeddedFallback/MapStringInt/StringifiedNumbers"),
  7051  		opts:  []Options{StringifyNumbers(true)},
  7052  		inBuf: `{"zero": "0", "one": "1", "two": "2"}`,
  7053  		inVal: new(structEmbedMapStringInt),
  7054  		want: addr(structEmbedMapStringInt{
  7055  			X: map[string]int{"zero": 0, "one": 1, "two": 2},
  7056  		}),
  7057  	}, {
  7058  		name: jsontest.Name("Structs/EmbeddedFallback/MapStringInt/UnmarshalFunc"),
  7059  		opts: []Options{
  7060  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *int) error {
  7061  				i, err := strconv.ParseInt(string(bytes.Trim(b, `"`)), 10, 64)
  7062  				if err != nil {
  7063  					return err
  7064  				}
  7065  				*v = int(i)
  7066  				return nil
  7067  			})),
  7068  		},
  7069  		inBuf: `{"zero": "0", "one": "1", "two": "2"}`,
  7070  		inVal: new(structEmbedMapStringInt),
  7071  		want: addr(structEmbedMapStringInt{
  7072  			X: map[string]int{"zero": 0, "one": 1, "two": 2},
  7073  		}),
  7074  	}, {
  7075  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringInt"),
  7076  		inBuf: `{"zero": 0, "one": 1, "two": 2}`,
  7077  		inVal: new(structEmbedMapNamedStringInt),
  7078  		want: addr(structEmbedMapNamedStringInt{
  7079  			X: map[namedString]int{"zero": 0, "one": 1, "two": 2},
  7080  		}),
  7081  	}, {
  7082  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringInt/Null"),
  7083  		inBuf: `{"zero": 0, "one": null, "two": 2}`,
  7084  		inVal: new(structEmbedMapNamedStringInt),
  7085  		want: addr(structEmbedMapNamedStringInt{
  7086  			X: map[namedString]int{"zero": 0, "one": 0, "two": 2},
  7087  		}),
  7088  	}, {
  7089  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringInt/Invalid"),
  7090  		inBuf: `{"zero": 0, "one": {}, "two": 2}`,
  7091  		inVal: new(structEmbedMapNamedStringInt),
  7092  		want: addr(structEmbedMapNamedStringInt{
  7093  			X: map[namedString]int{"zero": 0, "one": 0},
  7094  		}),
  7095  		wantErr: EU(nil).withPos(`{"zero": 0, "one": `, "/one").withType('{', T[int]()),
  7096  	}, {
  7097  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringInt/StringifiedNumbers"),
  7098  		opts:  []Options{StringifyNumbers(true)},
  7099  		inBuf: `{"zero": "0", "one": 1, "two": "2"}`,
  7100  		inVal: new(structEmbedMapNamedStringInt),
  7101  		want: addr(structEmbedMapNamedStringInt{
  7102  			X: map[namedString]int{"zero": 0, "one": 0},
  7103  		}),
  7104  		wantErr: EU(nil).withPos(`{"zero": "0", "one": `, "/one").withType('0', T[int]()),
  7105  	}, {
  7106  		name: jsontest.Name("Structs/EmbeddedFallback/MapNamedStringInt/UnmarshalFunc"),
  7107  		opts: []Options{
  7108  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *int) error {
  7109  				i, err := strconv.ParseInt(string(bytes.Trim(b, `"`)), 10, 64)
  7110  				if err != nil {
  7111  					return err
  7112  				}
  7113  				*v = int(i)
  7114  				return nil
  7115  			})),
  7116  		},
  7117  		inBuf: `{"zero": "0", "one": "1", "two": "2"}`,
  7118  		inVal: new(structEmbedMapNamedStringInt),
  7119  		want: addr(structEmbedMapNamedStringInt{
  7120  			X: map[namedString]int{"zero": 0, "one": 1, "two": 2},
  7121  		}),
  7122  	}, {
  7123  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/Noop"),
  7124  		inBuf: `{"A":1,"B":2}`,
  7125  		inVal: new(structEmbedMapNamedStringAny),
  7126  		want:  addr(structEmbedMapNamedStringAny{A: 1, X: nil, B: 2}),
  7127  	}, {
  7128  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/MergeN1/Nil"),
  7129  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  7130  		inVal: new(structEmbedMapNamedStringAny),
  7131  		want:  addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": "buzz"}, B: 2}),
  7132  	}, {
  7133  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/MergeN1/Empty"),
  7134  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  7135  		inVal: addr(structEmbedMapNamedStringAny{X: map[namedString]any{}}),
  7136  		want:  addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": "buzz"}, B: 2}),
  7137  	}, {
  7138  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/MergeN1/ObjectN1"),
  7139  		inBuf: `{"A":1,"fizz":{"charlie":"DELTA","echo":"foxtrot"},"B":2}`,
  7140  		inVal: addr(structEmbedMapNamedStringAny{X: map[namedString]any{"fizz": jsonObject{
  7141  			"alpha":   "bravo",
  7142  			"charlie": "delta",
  7143  		}}}),
  7144  		want: addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": jsonObject{
  7145  			"alpha":   "bravo",
  7146  			"charlie": "DELTA",
  7147  			"echo":    "foxtrot",
  7148  		}}, B: 2}),
  7149  	}, {
  7150  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/MergeN2/ObjectN1"),
  7151  		inBuf: `{"A":1,"fizz":"buzz","B":2,"foo": [ 1 , 2 , 3 ]}`,
  7152  		inVal: addr(structEmbedMapNamedStringAny{X: map[namedString]any{"fizz": "wuzz"}}),
  7153  		want:  addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": "buzz", "foo": jsonArray{1.0, 2.0, 3.0}}, B: 2}),
  7154  	}, {
  7155  		name:    jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/MergeInvalidValue"),
  7156  		inBuf:   `{"A":1,"fizz":nil,"B":2}`,
  7157  		inVal:   new(structEmbedMapNamedStringAny),
  7158  		want:    addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": nil}}),
  7159  		wantErr: newInvalidCharacterError("i", "in literal null (expecting 'u')", len64(`{"A":1,"fizz":n`), "/fizz"),
  7160  	}, {
  7161  		name:    jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/MergeInvalidValue/Existing"),
  7162  		inBuf:   `{"A":1,"fizz":nil,"B":2}`,
  7163  		inVal:   addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": true}}),
  7164  		want:    addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": true}}),
  7165  		wantErr: newInvalidCharacterError("i", "in literal null (expecting 'u')", len64(`{"A":1,"fizz":n`), "/fizz"),
  7166  	}, {
  7167  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/CaseSensitive"),
  7168  		inBuf: `{"A":1,"fizz":"buzz","B":2,"a":3}`,
  7169  		inVal: new(structEmbedMapNamedStringAny),
  7170  		want:  addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": "buzz", "a": 3.0}, B: 2}),
  7171  	}, {
  7172  		name:    jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/RejectDuplicateNames"),
  7173  		opts:    []Options{jsontext.AllowDuplicateNames(false)},
  7174  		inBuf:   `{"A":1,"fizz":"buzz","B":2,"fizz":"buzz"}`,
  7175  		inVal:   new(structEmbedMapNamedStringAny),
  7176  		want:    addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": "buzz"}, B: 2}),
  7177  		wantErr: newDuplicateNameError("", []byte(`"fizz"`), len64(`{"A":1,"fizz":"buzz","B":2,`)),
  7178  	}, {
  7179  		name:  jsontest.Name("Structs/EmbeddedFallback/MapNamedStringAny/AllowDuplicateNames"),
  7180  		opts:  []Options{jsontext.AllowDuplicateNames(true)},
  7181  		inBuf: `{"A":1,"fizz":{"one":1,"two":-2},"B":2,"fizz":{"two":2,"three":3}}`,
  7182  		inVal: new(structEmbedMapNamedStringAny),
  7183  		want:  addr(structEmbedMapNamedStringAny{A: 1, X: map[namedString]any{"fizz": map[string]any{"one": 1.0, "two": 2.0, "three": 3.0}}, B: 2}),
  7184  	}, {
  7185  		name:  jsontest.Name("Structs/EmbeddedFallback/RejectUnknownMembers"),
  7186  		opts:  []Options{RejectUnknownMembers(true)},
  7187  		inBuf: `{"A":1,"fizz":"buzz","B":2}`,
  7188  		inVal: new(structEmbedTextValue),
  7189  		want: addr(structEmbedTextValue{
  7190  			A: 1,
  7191  			X: jsontext.Value(`{"fizz":"buzz"}`),
  7192  			B: 2,
  7193  		}),
  7194  	}, {
  7195  		name:  jsontest.Name("Structs/UnknownIgnored"),
  7196  		opts:  []Options{RejectUnknownMembers(false)},
  7197  		inBuf: `{"unknown":"fizzbuzz"}`,
  7198  		inVal: new(structAll),
  7199  		want:  new(structAll),
  7200  	}, {
  7201  		name:    jsontest.Name("Structs/RejectUnknownMembers"),
  7202  		opts:    []Options{RejectUnknownMembers(true)},
  7203  		inBuf:   `{"unknown":"fizzbuzz"}`,
  7204  		inVal:   new(structAll),
  7205  		want:    new(structAll),
  7206  		wantErr: EU(ErrUnknownName).withPos(`{`, "/unknown").withType('"', T[structAll]()),
  7207  	}, {
  7208  		name:  jsontest.Name("Structs/UnexportedIgnored"),
  7209  		inBuf: `{"ignored":"unused"}`,
  7210  		inVal: new(structUnexportedIgnored),
  7211  		want:  new(structUnexportedIgnored),
  7212  	}, {
  7213  		name:  jsontest.Name("Structs/IgnoredUnexportedEmbedded"),
  7214  		inBuf: `{"namedString":"unused"}`,
  7215  		inVal: new(structIgnoredUnexportedEmbedded),
  7216  		want:  new(structIgnoredUnexportedEmbedded),
  7217  	}, {
  7218  		name:  jsontest.Name("Structs/NoCase/Exact"),
  7219  		inBuf: `{"Aaa":"Aaa","AA_A":"AA_A","AaA":"AaA","AAa":"AAa","AAA":"AAA"}`,
  7220  		inVal: new(structNoCase),
  7221  		want:  addr(structNoCase{AaA: "AaA", AAa: "AAa", Aaa: "Aaa", AAA: "AAA", AA_A: "AA_A"}),
  7222  	}, {
  7223  		name:  jsontest.Name("Structs/NoCase/CaseInsensitiveDefault/Ambiguous"),
  7224  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  7225  		inBuf: `{"aa_a":"aa_a"}`,
  7226  		inVal: new(structNoCase),
  7227  		want:  addr(structNoCase{AaA: "aa_a"}),
  7228  	}, {
  7229  		name:    jsontest.Name("Structs/NoCase/CaseInsensitiveDefault/Ambiguous"),
  7230  		inBuf:   `{"aa_a":"aa_a"}`,
  7231  		inVal:   new(structNoCase),
  7232  		want:    addr(structNoCase{}),
  7233  		wantErr: EU(errAmbiguousName).withPos(`{`, "/aa_a").withType('"', T[structNoCase]()),
  7234  	}, {
  7235  		name:  jsontest.Name("Structs/NoCase/MatchCaseSensitiveDelimiter"),
  7236  		opts:  []Options{jsonflags.MatchCaseSensitiveDelimiter | 1},
  7237  		inBuf: `{"aa_a":"aa_a"}`,
  7238  		inVal: new(structNoCase),
  7239  		want:  addr(structNoCase{}),
  7240  	}, {
  7241  		name:  jsontest.Name("Structs/NoCase/MatchCaseInsensitiveNames+MatchCaseSensitiveDelimiter"),
  7242  		opts:  []Options{MatchCaseInsensitiveNames(true), jsonflags.MatchCaseSensitiveDelimiter | 1},
  7243  		inBuf: `{"aa_a":"aa_a"}`,
  7244  		inVal: new(structNoCase),
  7245  		want:  addr(structNoCase{AA_A: "aa_a"}),
  7246  	}, {
  7247  		name:  jsontest.Name("Structs/NoCase/Merge/AllowDuplicateNames"),
  7248  		opts:  []Options{jsontext.AllowDuplicateNames(true), jsonflags.ReportErrorsWithLegacySemantics | 1},
  7249  		inBuf: `{"AaA":"AaA","aaa":"aaa","aAa":"aAa"}`,
  7250  		inVal: new(structNoCase),
  7251  		want:  addr(structNoCase{AaA: "aAa"}),
  7252  	}, {
  7253  		name:    jsontest.Name("Structs/NoCase/Merge/AllowDuplicateNames/Ambiguous"),
  7254  		opts:    []Options{jsontext.AllowDuplicateNames(true)},
  7255  		inBuf:   `{"AaA":"AaA","aaa":"aaa","aAa":"aAa"}`,
  7256  		inVal:   new(structNoCase),
  7257  		want:    addr(structNoCase{AaA: "AaA"}),
  7258  		wantErr: EU(errAmbiguousName).withPos(`{"AaA":"AaA",`, "/aaa").withType('"', T[structNoCase]()),
  7259  	}, {
  7260  		name:    jsontest.Name("Structs/NoCase/Merge/RejectDuplicateNames/Ambiguous"),
  7261  		opts:    []Options{jsontext.AllowDuplicateNames(false)},
  7262  		inBuf:   `{"AaA":"AaA","aaa":"aaa"}`,
  7263  		inVal:   new(structNoCase),
  7264  		want:    addr(structNoCase{AaA: "AaA"}),
  7265  		wantErr: EU(errAmbiguousName).withPos(`{"AaA":"AaA",`, "/aaa").withType('"', T[structNoCase]()),
  7266  	}, {
  7267  		name:  jsontest.Name("Structs/CaseSensitive"),
  7268  		inBuf: `{"BOOL": true, "STRING": "hello", "BYTES": "AQID", "INT": -64, "UINT": 64, "FLOAT": 3.14159}`,
  7269  		inVal: new(structScalars),
  7270  		want:  addr(structScalars{}),
  7271  	}, {
  7272  		name:  jsontest.Name("Structs/DuplicateName/NoCase/ExactDifferent"),
  7273  		inBuf: `{"AAA":"AAA","AaA":"AaA","AAa":"AAa","Aaa":"Aaa"}`,
  7274  		inVal: addr(structNoCaseEmbedTextValue{}),
  7275  		want:  addr(structNoCaseEmbedTextValue{AAA: "AAA", AaA: "AaA", AAa: "AAa", Aaa: "Aaa"}),
  7276  	}, {
  7277  		name:    jsontest.Name("Structs/DuplicateName/NoCase/ExactConflict"),
  7278  		inBuf:   `{"AAA":"AAA","AAA":"AAA"}`,
  7279  		inVal:   addr(structNoCaseEmbedTextValue{}),
  7280  		want:    addr(structNoCaseEmbedTextValue{AAA: "AAA"}),
  7281  		wantErr: newDuplicateNameError("", []byte(`"AAA"`), len64(`{"AAA":"AAA",`)),
  7282  	}, {
  7283  		name:  jsontest.Name("Structs/DuplicateName/NoCase/OverwriteExact"),
  7284  		inBuf: `{"AAA":"after"}`,
  7285  		inVal: addr(structNoCaseEmbedTextValue{AAA: "before"}),
  7286  		want:  addr(structNoCaseEmbedTextValue{AAA: "after"}),
  7287  	}, {
  7288  		name:    jsontest.Name("Structs/AmbiguousName/NoCase"),
  7289  		inBuf:   `{"aaa":"aaa"}`,
  7290  		inVal:   addr(structNoCaseEmbedTextValue{}),
  7291  		want:    addr(structNoCaseEmbedTextValue{}),
  7292  		wantErr: EU(errAmbiguousName).withPos(`{`, "/aaa").withType('"', T[structNoCaseEmbedTextValue]()),
  7293  	}, {
  7294  		name:  jsontest.Name("Structs/DuplicateName/Embed/Unknown"),
  7295  		inBuf: `{"unknown":""}`,
  7296  		inVal: addr(structNoCaseEmbedTextValue{}),
  7297  		want:  addr(structNoCaseEmbedTextValue{X: jsontext.Value(`{"unknown":""}`)}),
  7298  	}, {
  7299  		name:  jsontest.Name("Structs/DuplicateName/Embed/UnknownMerge"),
  7300  		inBuf: `{"unknown":""}`,
  7301  		inVal: addr(structNoCaseEmbedTextValue{X: jsontext.Value(`{"unknown":""}`)}),
  7302  		want:  addr(structNoCaseEmbedTextValue{X: jsontext.Value(`{"unknown":"","unknown":""}`)}),
  7303  	}, {
  7304  		name:  jsontest.Name("Structs/DuplicateName/Embed/NoCaseOkay"),
  7305  		inBuf: `{"b":"","B":""}`,
  7306  		inVal: addr(structNoCaseEmbedTextValue{}),
  7307  		want:  addr(structNoCaseEmbedTextValue{X: jsontext.Value(`{"b":"","B":""}`)}),
  7308  	}, {
  7309  		name:    jsontest.Name("Structs/DuplicateName/Embed/ExactConflict"),
  7310  		inBuf:   `{"b":"","b":""}`,
  7311  		inVal:   addr(structNoCaseEmbedTextValue{}),
  7312  		want:    addr(structNoCaseEmbedTextValue{X: jsontext.Value(`{"b":""}`)}),
  7313  		wantErr: newDuplicateNameError("", []byte(`"b"`), len64(`{"b":"",`)),
  7314  	}, {
  7315  		name:    jsontest.Name("Structs/Invalid/ErrUnexpectedEOF"),
  7316  		inBuf:   ``,
  7317  		inVal:   addr(structAll{}),
  7318  		want:    addr(structAll{}),
  7319  		wantErr: &jsontext.SyntacticError{Err: io.ErrUnexpectedEOF},
  7320  	}, {
  7321  		name:    jsontest.Name("Structs/Invalid/ErrUnexpectedEOF"),
  7322  		inBuf:   " \n\r\t",
  7323  		inVal:   addr(structAll{}),
  7324  		want:    addr(structAll{}),
  7325  		wantErr: &jsontext.SyntacticError{Err: io.ErrUnexpectedEOF, ByteOffset: len64(" \n\r\t")},
  7326  	}, {
  7327  		name:    jsontest.Name("Structs/Invalid/NestedErrUnexpectedEOF"),
  7328  		inBuf:   `{"Pointer":`,
  7329  		inVal:   addr(structAll{}),
  7330  		want:    addr(structAll{Pointer: new(structAll)}),
  7331  		wantErr: &jsontext.SyntacticError{ByteOffset: len64(`{"Pointer":`), JSONPointer: "/Pointer", Err: io.ErrUnexpectedEOF},
  7332  	}, {
  7333  		name:    jsontest.Name("Structs/Invalid/Conflicting"),
  7334  		inBuf:   `{}`,
  7335  		inVal:   addr(structConflicting{}),
  7336  		want:    addr(structConflicting{}),
  7337  		wantErr: EU(errors.New(`Go struct fields A and B conflict over JSON object name "conflict"`)).withType('{', T[structConflicting]()),
  7338  	}, {
  7339  		name:    jsontest.Name("Structs/Invalid/NoneExported"),
  7340  		inBuf:   ` {}`,
  7341  		inVal:   addr(structNoneExported{}),
  7342  		want:    addr(structNoneExported{}),
  7343  		wantErr: EU(errNoExportedFields).withPos(` `, "").withType('{', T[structNoneExported]()),
  7344  	}, {
  7345  		name:    jsontest.Name("Structs/Invalid/MalformedTag"),
  7346  		inBuf:   `{}`,
  7347  		inVal:   addr(structMalformedTag{}),
  7348  		want:    addr(structMalformedTag{}),
  7349  		wantErr: EU(errors.New("Go struct field Malformed has malformed `json` tag: invalid character '\"' at start of option (expecting Unicode letter)")).withType('{', T[structMalformedTag]()),
  7350  	}, {
  7351  		name:    jsontest.Name("Structs/Invalid/UnexportedTag"),
  7352  		inBuf:   `{}`,
  7353  		inVal:   addr(structUnexportedTag{}),
  7354  		want:    addr(structUnexportedTag{}),
  7355  		wantErr: EU(errors.New("unexported Go struct field unexported cannot have non-ignored `json:\"name\"` tag")).withType('{', T[structUnexportedTag]()),
  7356  	}, {
  7357  		name:    jsontest.Name("Structs/Invalid/ExportedEmbedded"),
  7358  		inBuf:   `{"NamedString":"hello"}`,
  7359  		inVal:   addr(structExportedEmbedded{}),
  7360  		want:    addr(structExportedEmbedded{}),
  7361  		wantErr: EU(errors.New("embedded Go struct field NamedString of non-struct type must be explicitly given a JSON name")).withType('{', T[structExportedEmbedded]()),
  7362  	}, {
  7363  		name:  jsontest.Name("Structs/Valid/ExportedEmbedded"),
  7364  		opts:  []Options{jsonflags.ReportErrorsWithLegacySemantics | 1},
  7365  		inBuf: `{"NamedString":"hello"}`,
  7366  		inVal: addr(structExportedEmbedded{}),
  7367  		want:  addr(structExportedEmbedded{"hello"}),
  7368  	}, {
  7369  		name:  jsontest.Name("Structs/Valid/ExportedEmbeddedTag"),
  7370  		inBuf: `{"name":"hello"}`,
  7371  		inVal: addr(structExportedEmbeddedTag{}),
  7372  		want:  addr(structExportedEmbeddedTag{"hello"}),
  7373  	}, {
  7374  		name:    jsontest.Name("Structs/Invalid/UnexportedEmbedded"),
  7375  		inBuf:   `{}`,
  7376  		inVal:   addr(structUnexportedEmbedded{}),
  7377  		want:    addr(structUnexportedEmbedded{}),
  7378  		wantErr: EU(errors.New("embedded Go struct field namedString of non-struct type must be explicitly given a JSON name")).withType('{', T[structUnexportedEmbedded]()),
  7379  	}, {
  7380  		name:  jsontest.Name("Structs/UnexportedEmbeddedStruct"),
  7381  		inBuf: `{"Bool":true,"FizzBuzz":5,"Addr":"192.168.0.1"}`,
  7382  		inVal: addr(structUnexportedEmbeddedStruct{}),
  7383  		want:  addr(structUnexportedEmbeddedStruct{structOmitZeroAll{Bool: true}, 5, structNestedAddr{netip.AddrFrom4([4]byte{192, 168, 0, 1})}}),
  7384  	}, {
  7385  		name:    jsontest.Name("Structs/UnexportedEmbeddedStructPointer/Nil"),
  7386  		inBuf:   `{"Bool":true,"FizzBuzz":5}`,
  7387  		inVal:   addr(structUnexportedEmbeddedStructPointer{}),
  7388  		wantErr: EU(errNilField).withPos(`{"Bool":`, "/Bool").withType(0, T[structUnexportedEmbeddedStructPointer]()),
  7389  	}, {
  7390  		name:    jsontest.Name("Structs/UnexportedEmbeddedStructPointer/Nil"),
  7391  		inBuf:   `{"FizzBuzz":5,"Addr":"192.168.0.1"}`,
  7392  		inVal:   addr(structUnexportedEmbeddedStructPointer{}),
  7393  		wantErr: EU(errNilField).withPos(`{"FizzBuzz":5,"Addr":`, "/Addr").withType(0, T[structUnexportedEmbeddedStructPointer]()),
  7394  	}, {
  7395  		name:  jsontest.Name("Structs/UnexportedEmbeddedStructPointer/Nil"),
  7396  		inBuf: `{"Bool":true,"FizzBuzz":10,"Addr":"192.168.0.1"}`,
  7397  		inVal: addr(structUnexportedEmbeddedStructPointer{&structOmitZeroAll{Int: 5}, 5, &structNestedAddr{netip.AddrFrom4([4]byte{127, 0, 0, 1})}}),
  7398  		want:  addr(structUnexportedEmbeddedStructPointer{&structOmitZeroAll{Bool: true, Int: 5}, 10, &structNestedAddr{netip.AddrFrom4([4]byte{192, 168, 0, 1})}}),
  7399  	}, {
  7400  		name: jsontest.Name("Structs/Unknown"),
  7401  		inBuf: `{
  7402  	"object0": {},
  7403  	"object1": {"key1": "value"},
  7404  	"object2": {"key1": "value", "key2": "value"},
  7405  	"objects": {"":{"":{"":{}}}},
  7406  	"array0": [],
  7407  	"array1": ["value1"],
  7408  	"array2": ["value1", "value2"],
  7409  	"array": [[[]]],
  7410  	"scalars": [null, false, true, "string", 12.345]
  7411  }`,
  7412  		inVal: addr(struct{}{}),
  7413  		want:  addr(struct{}{}),
  7414  	}, {
  7415  		name:  jsontest.Name("Structs/IgnoreInvalidFormat"),
  7416  		opts:  []Options{invalidFormatOption},
  7417  		inBuf: `{"Field":"Value"}`,
  7418  		inVal: addr(struct{ Field string }{}),
  7419  		want:  addr(struct{ Field string }{"Value"}),
  7420  	}, {
  7421  		name:  jsontest.Name("Slices/Null"),
  7422  		inBuf: `null`,
  7423  		inVal: addr([]string{"something"}),
  7424  		want:  addr([]string(nil)),
  7425  	}, {
  7426  		name:  jsontest.Name("Slices/Bool"),
  7427  		inBuf: `[true,false]`,
  7428  		inVal: new([]bool),
  7429  		want:  addr([]bool{true, false}),
  7430  	}, {
  7431  		name:  jsontest.Name("Slices/String"),
  7432  		inBuf: `["hello","goodbye"]`,
  7433  		inVal: new([]string),
  7434  		want:  addr([]string{"hello", "goodbye"}),
  7435  	}, {
  7436  		name:  jsontest.Name("Slices/Bytes"),
  7437  		inBuf: `["aGVsbG8=","Z29vZGJ5ZQ=="]`,
  7438  		inVal: new([][]byte),
  7439  		want:  addr([][]byte{[]byte("hello"), []byte("goodbye")}),
  7440  	}, {
  7441  		name:  jsontest.Name("Slices/Int"),
  7442  		inBuf: `[-2,-1,0,1,2]`,
  7443  		inVal: new([]int),
  7444  		want:  addr([]int{-2, -1, 0, 1, 2}),
  7445  	}, {
  7446  		name:  jsontest.Name("Slices/Uint"),
  7447  		inBuf: `[0,1,2,3,4]`,
  7448  		inVal: new([]uint),
  7449  		want:  addr([]uint{0, 1, 2, 3, 4}),
  7450  	}, {
  7451  		name:  jsontest.Name("Slices/Float"),
  7452  		inBuf: `[3.14159,12.34]`,
  7453  		inVal: new([]float64),
  7454  		want:  addr([]float64{3.14159, 12.34}),
  7455  	}, {
  7456  		// NOTE: The semantics differs from v1, where the slice length is reset
  7457  		// and new elements are appended to the end.
  7458  		// See https://go.dev/issue/21092.
  7459  		name:  jsontest.Name("Slices/Merge"),
  7460  		inBuf: `[{"k3":"v3"},{"k4":"v4"}]`,
  7461  		inVal: addr([]map[string]string{{"k1": "v1"}, {"k2": "v2"}}[:1]),
  7462  		want:  addr([]map[string]string{{"k3": "v3"}, {"k4": "v4"}}),
  7463  	}, {
  7464  		name:    jsontest.Name("Slices/Invalid/Channel"),
  7465  		inBuf:   `["hello"]`,
  7466  		inVal:   new([]chan string),
  7467  		want:    addr([]chan string{nil}),
  7468  		wantErr: EU(nil).withPos(`[`, "/0").withType(0, T[chan string]()),
  7469  	}, {
  7470  		name:  jsontest.Name("Slices/RecursiveSlice"),
  7471  		inBuf: `[[],[],[[]],[[],[]]]`,
  7472  		inVal: new(recursiveSlice),
  7473  		want: addr(recursiveSlice{
  7474  			{},
  7475  			{},
  7476  			{{}},
  7477  			{{}, {}},
  7478  		}),
  7479  	}, {
  7480  		name:    jsontest.Name("Slices/Invalid/Bool"),
  7481  		inBuf:   `true`,
  7482  		inVal:   addr([]string{"nochange"}),
  7483  		want:    addr([]string{"nochange"}),
  7484  		wantErr: EU(nil).withType('t', T[[]string]()),
  7485  	}, {
  7486  		name:    jsontest.Name("Slices/Invalid/String"),
  7487  		inBuf:   `""`,
  7488  		inVal:   addr([]string{"nochange"}),
  7489  		want:    addr([]string{"nochange"}),
  7490  		wantErr: EU(nil).withType('"', T[[]string]()),
  7491  	}, {
  7492  		name:    jsontest.Name("Slices/Invalid/Number"),
  7493  		inBuf:   `0`,
  7494  		inVal:   addr([]string{"nochange"}),
  7495  		want:    addr([]string{"nochange"}),
  7496  		wantErr: EU(nil).withType('0', T[[]string]()),
  7497  	}, {
  7498  		name:    jsontest.Name("Slices/Invalid/Object"),
  7499  		inBuf:   `{}`,
  7500  		inVal:   addr([]string{"nochange"}),
  7501  		want:    addr([]string{"nochange"}),
  7502  		wantErr: EU(nil).withType('{', T[[]string]()),
  7503  	}, {
  7504  		name:  jsontest.Name("Slices/IgnoreInvalidFormat"),
  7505  		opts:  []Options{invalidFormatOption},
  7506  		inBuf: `[false,true]`,
  7507  		inVal: addr([]bool{true, false}),
  7508  		want:  addr([]bool{false, true}),
  7509  	}, {
  7510  		name:  jsontest.Name("Arrays/Null"),
  7511  		inBuf: `null`,
  7512  		inVal: addr([1]string{"something"}),
  7513  		want:  addr([1]string{}),
  7514  	}, {
  7515  		name:  jsontest.Name("Arrays/Bool"),
  7516  		inBuf: `[true,false]`,
  7517  		inVal: new([2]bool),
  7518  		want:  addr([2]bool{true, false}),
  7519  	}, {
  7520  		name:  jsontest.Name("Arrays/String"),
  7521  		inBuf: `["hello","goodbye"]`,
  7522  		inVal: new([2]string),
  7523  		want:  addr([2]string{"hello", "goodbye"}),
  7524  	}, {
  7525  		name:  jsontest.Name("Arrays/Bytes"),
  7526  		inBuf: `["aGVsbG8=","Z29vZGJ5ZQ=="]`,
  7527  		inVal: new([2][]byte),
  7528  		want:  addr([2][]byte{[]byte("hello"), []byte("goodbye")}),
  7529  	}, {
  7530  		name:  jsontest.Name("Arrays/Int"),
  7531  		inBuf: `[-2,-1,0,1,2]`,
  7532  		inVal: new([5]int),
  7533  		want:  addr([5]int{-2, -1, 0, 1, 2}),
  7534  	}, {
  7535  		name:  jsontest.Name("Arrays/Uint"),
  7536  		inBuf: `[0,1,2,3,4]`,
  7537  		inVal: new([5]uint),
  7538  		want:  addr([5]uint{0, 1, 2, 3, 4}),
  7539  	}, {
  7540  		name:  jsontest.Name("Arrays/Float"),
  7541  		inBuf: `[3.14159,12.34]`,
  7542  		inVal: new([2]float64),
  7543  		want:  addr([2]float64{3.14159, 12.34}),
  7544  	}, {
  7545  		// NOTE: The semantics differs from v1, where elements are not merged.
  7546  		// This is to maintain consistent merge semantics with slices.
  7547  		name:  jsontest.Name("Arrays/Merge"),
  7548  		inBuf: `[{"k3":"v3"},{"k4":"v4"}]`,
  7549  		inVal: addr([2]map[string]string{{"k1": "v1"}, {"k2": "v2"}}),
  7550  		want:  addr([2]map[string]string{{"k3": "v3"}, {"k4": "v4"}}),
  7551  	}, {
  7552  		name:    jsontest.Name("Arrays/Invalid/Channel"),
  7553  		inBuf:   `["hello"]`,
  7554  		inVal:   new([1]chan string),
  7555  		want:    new([1]chan string),
  7556  		wantErr: EU(nil).withPos(`[`, "/0").withType(0, T[chan string]()),
  7557  	}, {
  7558  		name:    jsontest.Name("Arrays/Invalid/Underflow"),
  7559  		inBuf:   `{"F":[   ]}`,
  7560  		inVal:   new(struct{ F [1]string }),
  7561  		want:    addr(struct{ F [1]string }{}),
  7562  		wantErr: EU(errArrayUnderflow).withPos(`{"F":[   `, "/F").withType(']', T[[1]string]()),
  7563  	}, {
  7564  		name:  jsontest.Name("Arrays/Invalid/Underflow/UnmarshalArrayFromAnyLength"),
  7565  		opts:  []Options{jsonflags.UnmarshalArrayFromAnyLength | 1},
  7566  		inBuf: `[-1,-2]`,
  7567  		inVal: addr([4]int{1, 2, 3, 4}),
  7568  		want:  addr([4]int{-1, -2, 0, 0}),
  7569  	}, {
  7570  		name:    jsontest.Name("Arrays/Invalid/Overflow"),
  7571  		inBuf:   `["1","2"]`,
  7572  		inVal:   new([1]string),
  7573  		want:    addr([1]string{"1"}),
  7574  		wantErr: EU(errArrayOverflow).withPos(`["1","2"`, "").withType(']', T[[1]string]()),
  7575  	}, {
  7576  		name:  jsontest.Name("Arrays/Invalid/Overflow/UnmarshalArrayFromAnyLength"),
  7577  		opts:  []Options{jsonflags.UnmarshalArrayFromAnyLength | 1},
  7578  		inBuf: `[-1,-2,-3,-4,-5,-6]`,
  7579  		inVal: addr([4]int{1, 2, 3, 4}),
  7580  		want:  addr([4]int{-1, -2, -3, -4}),
  7581  	}, {
  7582  		name:    jsontest.Name("Arrays/Invalid/Bool"),
  7583  		inBuf:   `true`,
  7584  		inVal:   addr([1]string{"nochange"}),
  7585  		want:    addr([1]string{"nochange"}),
  7586  		wantErr: EU(nil).withType('t', T[[1]string]()),
  7587  	}, {
  7588  		name:    jsontest.Name("Arrays/Invalid/String"),
  7589  		inBuf:   `""`,
  7590  		inVal:   addr([1]string{"nochange"}),
  7591  		want:    addr([1]string{"nochange"}),
  7592  		wantErr: EU(nil).withType('"', T[[1]string]()),
  7593  	}, {
  7594  		name:    jsontest.Name("Arrays/Invalid/Number"),
  7595  		inBuf:   `0`,
  7596  		inVal:   addr([1]string{"nochange"}),
  7597  		want:    addr([1]string{"nochange"}),
  7598  		wantErr: EU(nil).withType('0', T[[1]string]()),
  7599  	}, {
  7600  		name:    jsontest.Name("Arrays/Invalid/Object"),
  7601  		inBuf:   `{}`,
  7602  		inVal:   addr([1]string{"nochange"}),
  7603  		want:    addr([1]string{"nochange"}),
  7604  		wantErr: EU(nil).withType('{', T[[1]string]()),
  7605  	}, {
  7606  		name:  jsontest.Name("Arrays/IgnoreInvalidFormat"),
  7607  		opts:  []Options{invalidFormatOption},
  7608  		inBuf: `[false,true]`,
  7609  		inVal: addr([2]bool{true, false}),
  7610  		want:  addr([2]bool{false, true}),
  7611  	}, {
  7612  		name:  jsontest.Name("Pointers/NullL0"),
  7613  		inBuf: `null`,
  7614  		inVal: new(*string),
  7615  		want:  addr((*string)(nil)),
  7616  	}, {
  7617  		name:  jsontest.Name("Pointers/NullL1"),
  7618  		inBuf: `null`,
  7619  		inVal: addr(new(*string)),
  7620  		want:  addr((**string)(nil)),
  7621  	}, {
  7622  		name:  jsontest.Name("Pointers/Bool"),
  7623  		inBuf: `true`,
  7624  		inVal: addr(new(bool)),
  7625  		want:  addr(addr(true)),
  7626  	}, {
  7627  		name:  jsontest.Name("Pointers/String"),
  7628  		inBuf: `"hello"`,
  7629  		inVal: addr(new(string)),
  7630  		want:  addr(addr("hello")),
  7631  	}, {
  7632  		name:  jsontest.Name("Pointers/Bytes"),
  7633  		inBuf: `"aGVsbG8="`,
  7634  		inVal: addr(new([]byte)),
  7635  		want:  addr(addr([]byte("hello"))),
  7636  	}, {
  7637  		name:  jsontest.Name("Pointers/Int"),
  7638  		inBuf: `-123`,
  7639  		inVal: addr(new(int)),
  7640  		want:  addr(addr(int(-123))),
  7641  	}, {
  7642  		name:  jsontest.Name("Pointers/Uint"),
  7643  		inBuf: `123`,
  7644  		inVal: addr(new(int)),
  7645  		want:  addr(addr(int(123))),
  7646  	}, {
  7647  		name:  jsontest.Name("Pointers/Float"),
  7648  		inBuf: `123.456`,
  7649  		inVal: addr(new(float64)),
  7650  		want:  addr(addr(float64(123.456))),
  7651  	}, {
  7652  		name:  jsontest.Name("Pointers/Allocate"),
  7653  		inBuf: `"hello"`,
  7654  		inVal: addr((*string)(nil)),
  7655  		want:  addr(addr("hello")),
  7656  	}, {
  7657  		name:  jsontest.Name("Points/IgnoreInvalidFormat"),
  7658  		opts:  []Options{invalidFormatOption},
  7659  		inBuf: `true`,
  7660  		inVal: addr(new(bool)),
  7661  		want:  addr(addr(true)),
  7662  	}, {
  7663  		name:  jsontest.Name("Interfaces/Empty/Null"),
  7664  		inBuf: `null`,
  7665  		inVal: new(any),
  7666  		want:  new(any),
  7667  	}, {
  7668  		name:  jsontest.Name("Interfaces/NonEmpty/Null"),
  7669  		inBuf: `null`,
  7670  		inVal: new(io.Reader),
  7671  		want:  new(io.Reader),
  7672  	}, {
  7673  		name:    jsontest.Name("Interfaces/NonEmpty/Invalid"),
  7674  		inBuf:   `"hello"`,
  7675  		inVal:   new(io.Reader),
  7676  		want:    new(io.Reader),
  7677  		wantErr: EU(internal.ErrNilInterface).withType(0, T[io.Reader]()),
  7678  	}, {
  7679  		name:  jsontest.Name("Interfaces/Empty/False"),
  7680  		inBuf: `false`,
  7681  		inVal: new(any),
  7682  		want: func() any {
  7683  			var vi any = false
  7684  			return &vi
  7685  		}(),
  7686  	}, {
  7687  		name:  jsontest.Name("Interfaces/Empty/True"),
  7688  		inBuf: `true`,
  7689  		inVal: new(any),
  7690  		want: func() any {
  7691  			var vi any = true
  7692  			return &vi
  7693  		}(),
  7694  	}, {
  7695  		name:  jsontest.Name("Interfaces/Empty/String"),
  7696  		inBuf: `"string"`,
  7697  		inVal: new(any),
  7698  		want: func() any {
  7699  			var vi any = "string"
  7700  			return &vi
  7701  		}(),
  7702  	}, {
  7703  		name:  jsontest.Name("Interfaces/Empty/Number"),
  7704  		inBuf: `3.14159`,
  7705  		inVal: new(any),
  7706  		want: func() any {
  7707  			var vi any = 3.14159
  7708  			return &vi
  7709  		}(),
  7710  	}, {
  7711  		name:  jsontest.Name("Interfaces/Empty/Object"),
  7712  		inBuf: `{"k":"v"}`,
  7713  		inVal: new(any),
  7714  		want: func() any {
  7715  			var vi any = map[string]any{"k": "v"}
  7716  			return &vi
  7717  		}(),
  7718  	}, {
  7719  		name:  jsontest.Name("Interfaces/Empty/Array"),
  7720  		inBuf: `["v"]`,
  7721  		inVal: new(any),
  7722  		want: func() any {
  7723  			var vi any = []any{"v"}
  7724  			return &vi
  7725  		}(),
  7726  	}, {
  7727  		name:  jsontest.Name("Interfaces/NamedAny/String"),
  7728  		inBuf: `"string"`,
  7729  		inVal: new(namedAny),
  7730  		want: func() namedAny {
  7731  			var vi namedAny = "string"
  7732  			return &vi
  7733  		}(),
  7734  	}, {
  7735  		name:    jsontest.Name("Interfaces/Invalid"),
  7736  		inBuf:   `]`,
  7737  		inVal:   new(any),
  7738  		want:    new(any),
  7739  		wantErr: newInvalidCharacterError("]", "at start of value", 0, ""),
  7740  	}, {
  7741  		// NOTE: The semantics differs from v1,
  7742  		// where existing map entries were not merged into.
  7743  		// See https://go.dev/issue/26946.
  7744  		// See https://go.dev/issue/33993.
  7745  		name:  jsontest.Name("Interfaces/Merge/Map"),
  7746  		inBuf: `{"k2":"v2"}`,
  7747  		inVal: func() any {
  7748  			var vi any = map[string]string{"k1": "v1"}
  7749  			return &vi
  7750  		}(),
  7751  		want: func() any {
  7752  			var vi any = map[string]string{"k1": "v1", "k2": "v2"}
  7753  			return &vi
  7754  		}(),
  7755  	}, {
  7756  		name:  jsontest.Name("Interfaces/Merge/Struct"),
  7757  		inBuf: `{"Array":["goodbye"]}`,
  7758  		inVal: func() any {
  7759  			var vi any = structAll{String: "hello"}
  7760  			return &vi
  7761  		}(),
  7762  		want: func() any {
  7763  			var vi any = structAll{String: "hello", Array: [1]string{"goodbye"}}
  7764  			return &vi
  7765  		}(),
  7766  	}, {
  7767  		name:  jsontest.Name("Interfaces/Merge/NamedInt"),
  7768  		inBuf: `64`,
  7769  		inVal: func() any {
  7770  			var vi any = namedInt64(-64)
  7771  			return &vi
  7772  		}(),
  7773  		want: func() any {
  7774  			var vi any = namedInt64(+64)
  7775  			return &vi
  7776  		}(),
  7777  	}, {
  7778  		name:  jsontest.Name("Interfaces/IgnoreInvalidFormat"),
  7779  		opts:  []Options{invalidFormatOption},
  7780  		inBuf: `true`,
  7781  		inVal: new(any),
  7782  		want: func() any {
  7783  			var vi any = true
  7784  			return &vi
  7785  		}(),
  7786  	}, {
  7787  		name:  jsontest.Name("Interfaces/Any"),
  7788  		inBuf: `{"X":[null,false,true,"",0,{},[]]}`,
  7789  		inVal: new(struct{ X any }),
  7790  		want:  addr(struct{ X any }{[]any{nil, false, true, "", 0.0, map[string]any{}, []any{}}}),
  7791  	}, {
  7792  		name:  jsontest.Name("Interfaces/Any/Named"),
  7793  		inBuf: `{"X":[null,false,true,"",0,{},[]]}`,
  7794  		inVal: new(struct{ X namedAny }),
  7795  		want:  addr(struct{ X namedAny }{[]any{nil, false, true, "", 0.0, map[string]any{}, []any{}}}),
  7796  	}, {
  7797  		name:  jsontest.Name("Interfaces/Any/Stringified"),
  7798  		opts:  []Options{StringifyNumbers(true)},
  7799  		inBuf: `{"X":"0"}`,
  7800  		inVal: new(struct{ X any }),
  7801  		want:  addr(struct{ X any }{"0"}),
  7802  	}, {
  7803  		name: jsontest.Name("Interfaces/Any/UnmarshalFunc/Any"),
  7804  		opts: []Options{
  7805  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *any) error {
  7806  				*v = "called"
  7807  				return nil
  7808  			})),
  7809  		},
  7810  		inBuf: `{"X":[null,false,true,"",0,{},[]]}`,
  7811  		inVal: new(struct{ X any }),
  7812  		want:  addr(struct{ X any }{"called"}),
  7813  	}, {
  7814  		name: jsontest.Name("Interfaces/Any/UnmarshalFunc/Bool"),
  7815  		opts: []Options{
  7816  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *bool) error {
  7817  				*v = string(b) != "true"
  7818  				return nil
  7819  			})),
  7820  		},
  7821  		inBuf: `{"X":[null,false,true,"",0,{},[]]}`,
  7822  		inVal: new(struct{ X any }),
  7823  		want:  addr(struct{ X any }{[]any{nil, true, false, "", 0.0, map[string]any{}, []any{}}}),
  7824  	}, {
  7825  		name: jsontest.Name("Interfaces/Any/UnmarshalFunc/String"),
  7826  		opts: []Options{
  7827  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *string) error {
  7828  				*v = "called"
  7829  				return nil
  7830  			})),
  7831  		},
  7832  		inBuf: `{"X":[null,false,true,"",0,{},[]]}`,
  7833  		inVal: new(struct{ X any }),
  7834  		want:  addr(struct{ X any }{[]any{nil, false, true, "called", 0.0, map[string]any{}, []any{}}}),
  7835  	}, {
  7836  		name: jsontest.Name("Interfaces/Any/UnmarshalFunc/Float64"),
  7837  		opts: []Options{
  7838  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *float64) error {
  7839  				*v = 3.14159
  7840  				return nil
  7841  			})),
  7842  		},
  7843  		inBuf: `{"X":[null,false,true,"",0,{},[]]}`,
  7844  		inVal: new(struct{ X any }),
  7845  		want:  addr(struct{ X any }{[]any{nil, false, true, "", 3.14159, map[string]any{}, []any{}}}),
  7846  	}, {
  7847  		name: jsontest.Name("Interfaces/Any/UnmarshalFunc/MapStringAny"),
  7848  		opts: []Options{
  7849  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *map[string]any) error {
  7850  				*v = map[string]any{"called": nil}
  7851  				return nil
  7852  			})),
  7853  		},
  7854  		inBuf: `{"X":[null,false,true,"",0,{},[]]}`,
  7855  		inVal: new(struct{ X any }),
  7856  		want:  addr(struct{ X any }{[]any{nil, false, true, "", 0.0, map[string]any{"called": nil}, []any{}}}),
  7857  	}, {
  7858  		name: jsontest.Name("Interfaces/Any/UnmarshalFunc/SliceAny"),
  7859  		opts: []Options{
  7860  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *[]any) error {
  7861  				*v = []any{"called"}
  7862  				return nil
  7863  			})),
  7864  		},
  7865  		inBuf: `{"X":[null,false,true,"",0,{},[]]}`,
  7866  		inVal: new(struct{ X any }),
  7867  		want:  addr(struct{ X any }{[]any{"called"}}),
  7868  	}, {
  7869  		name:  jsontest.Name("Interfaces/Any/Maps/NonEmpty"),
  7870  		inBuf: `{"X":{"fizz":"buzz"}}`,
  7871  		inVal: new(struct{ X any }),
  7872  		want:  addr(struct{ X any }{map[string]any{"fizz": "buzz"}}),
  7873  	}, {
  7874  		name:    jsontest.Name("Interfaces/Any/Maps/RejectDuplicateNames"),
  7875  		inBuf:   `{"X":{"fizz":"buzz","fizz":true}}`,
  7876  		inVal:   new(struct{ X any }),
  7877  		want:    addr(struct{ X any }{map[string]any{"fizz": "buzz"}}),
  7878  		wantErr: newDuplicateNameError("/X", []byte(`"fizz"`), len64(`{"X":{"fizz":"buzz",`)),
  7879  	}, {
  7880  		name:    jsontest.Name("Interfaces/Any/Maps/AllowDuplicateNames"),
  7881  		opts:    []Options{jsontext.AllowDuplicateNames(true)},
  7882  		inBuf:   `{"X":{"fizz":"buzz","fizz":true}}`,
  7883  		inVal:   new(struct{ X any }),
  7884  		want:    addr(struct{ X any }{map[string]any{"fizz": "buzz"}}),
  7885  		wantErr: EU(nil).withPos(`{"X":{"fizz":"buzz","fizz":`, "/X/fizz").withType('t', T[string]()),
  7886  	}, {
  7887  		name:  jsontest.Name("Interfaces/Any/Slices/NonEmpty"),
  7888  		inBuf: `{"X":["fizz","buzz"]}`,
  7889  		inVal: new(struct{ X any }),
  7890  		want:  addr(struct{ X any }{[]any{"fizz", "buzz"}}),
  7891  	}, {
  7892  		name:  jsontest.Name("Methods/NilPointer/Null"),
  7893  		inBuf: `{"X":null}`,
  7894  		inVal: addr(struct{ X *allMethods }{X: (*allMethods)(nil)}),
  7895  		want:  addr(struct{ X *allMethods }{X: (*allMethods)(nil)}), // method should not be called
  7896  	}, {
  7897  		name:  jsontest.Name("Methods/NilPointer/Value"),
  7898  		inBuf: `{"X":"value"}`,
  7899  		inVal: addr(struct{ X *allMethods }{X: (*allMethods)(nil)}),
  7900  		want:  addr(struct{ X *allMethods }{X: &allMethods{method: "UnmarshalJSONFrom", value: []byte(`"value"`)}}),
  7901  	}, {
  7902  		name:  jsontest.Name("Methods/NilInterface/Null"),
  7903  		inBuf: `{"X":null}`,
  7904  		inVal: addr(struct{ X MarshalerTo }{X: (*allMethods)(nil)}),
  7905  		want:  addr(struct{ X MarshalerTo }{X: nil}), // interface value itself is nil'd out
  7906  	}, {
  7907  		name:  jsontest.Name("Methods/NilInterface/Value"),
  7908  		inBuf: `{"X":"value"}`,
  7909  		inVal: addr(struct{ X MarshalerTo }{X: (*allMethods)(nil)}),
  7910  		want:  addr(struct{ X MarshalerTo }{X: &allMethods{method: "UnmarshalJSONFrom", value: []byte(`"value"`)}}),
  7911  	}, {
  7912  		name:  jsontest.Name("Methods/AllMethods"),
  7913  		inBuf: `{"X":"hello"}`,
  7914  		inVal: new(struct{ X *allMethods }),
  7915  		want:  addr(struct{ X *allMethods }{X: &allMethods{method: "UnmarshalJSONFrom", value: []byte(`"hello"`)}}),
  7916  	}, {
  7917  		name:  jsontest.Name("Methods/AllMethodsExceptJSONv2"),
  7918  		inBuf: `{"X":"hello"}`,
  7919  		inVal: new(struct{ X *allMethodsExceptJSONv2 }),
  7920  		want:  addr(struct{ X *allMethodsExceptJSONv2 }{X: &allMethodsExceptJSONv2{allMethods: allMethods{method: "UnmarshalJSON", value: []byte(`"hello"`)}}}),
  7921  	}, {
  7922  		name:  jsontest.Name("Methods/AllMethodsExceptJSONv1"),
  7923  		inBuf: `{"X":"hello"}`,
  7924  		inVal: new(struct{ X *allMethodsExceptJSONv1 }),
  7925  		want:  addr(struct{ X *allMethodsExceptJSONv1 }{X: &allMethodsExceptJSONv1{allMethods: allMethods{method: "UnmarshalJSONFrom", value: []byte(`"hello"`)}}}),
  7926  	}, {
  7927  		name:  jsontest.Name("Methods/AllMethodsExceptText"),
  7928  		inBuf: `{"X":"hello"}`,
  7929  		inVal: new(struct{ X *allMethodsExceptText }),
  7930  		want:  addr(struct{ X *allMethodsExceptText }{X: &allMethodsExceptText{allMethods: allMethods{method: "UnmarshalJSONFrom", value: []byte(`"hello"`)}}}),
  7931  	}, {
  7932  		name:  jsontest.Name("Methods/OnlyMethodJSONv2"),
  7933  		inBuf: `{"X":"hello"}`,
  7934  		inVal: new(struct{ X *onlyMethodJSONv2 }),
  7935  		want:  addr(struct{ X *onlyMethodJSONv2 }{X: &onlyMethodJSONv2{allMethods: allMethods{method: "UnmarshalJSONFrom", value: []byte(`"hello"`)}}}),
  7936  	}, {
  7937  		name:  jsontest.Name("Methods/OnlyMethodJSONv1"),
  7938  		inBuf: `{"X":"hello"}`,
  7939  		inVal: new(struct{ X *onlyMethodJSONv1 }),
  7940  		want:  addr(struct{ X *onlyMethodJSONv1 }{X: &onlyMethodJSONv1{allMethods: allMethods{method: "UnmarshalJSON", value: []byte(`"hello"`)}}}),
  7941  	}, {
  7942  		name:  jsontest.Name("Methods/OnlyMethodText"),
  7943  		inBuf: `{"X":"hello"}`,
  7944  		inVal: new(struct{ X *onlyMethodText }),
  7945  		want:  addr(struct{ X *onlyMethodText }{X: &onlyMethodText{allMethods: allMethods{method: "UnmarshalText", value: []byte(`hello`)}}}),
  7946  	}, {
  7947  		name:  jsontest.Name("Methods/Text/Null"),
  7948  		inBuf: `{"X":null}`,
  7949  		inVal: addr(struct{ X unmarshalTextFunc }{unmarshalTextFunc(func(b []byte) error {
  7950  			return errMustNotCall
  7951  		})}),
  7952  		want: addr(struct{ X unmarshalTextFunc }{nil}),
  7953  	}, {
  7954  		name:  jsontest.Name("Methods/IP"),
  7955  		inBuf: `"192.168.0.100"`,
  7956  		inVal: new(net.IP),
  7957  		want:  addr(net.IPv4(192, 168, 0, 100)),
  7958  	}, {
  7959  		// NOTE: Fixes https://go.dev/issue/46516.
  7960  		name:  jsontest.Name("Methods/Anonymous"),
  7961  		inBuf: `{"X":"hello"}`,
  7962  		inVal: new(struct{ X struct{ allMethods } }),
  7963  		want:  addr(struct{ X struct{ allMethods } }{X: struct{ allMethods }{allMethods{method: "UnmarshalJSONFrom", value: []byte(`"hello"`)}}}),
  7964  	}, {
  7965  		// NOTE: Fixes https://go.dev/issue/22967.
  7966  		name:  jsontest.Name("Methods/Addressable"),
  7967  		inBuf: `{"V":"hello","M":{"K":"hello"},"I":"hello"}`,
  7968  		inVal: addr(struct {
  7969  			V allMethods
  7970  			M map[string]allMethods
  7971  			I any
  7972  		}{
  7973  			I: allMethods{}, // need to initialize with concrete value
  7974  		}),
  7975  		want: addr(struct {
  7976  			V allMethods
  7977  			M map[string]allMethods
  7978  			I any
  7979  		}{
  7980  			V: allMethods{method: "UnmarshalJSONFrom", value: []byte(`"hello"`)},
  7981  			M: map[string]allMethods{"K": {method: "UnmarshalJSONFrom", value: []byte(`"hello"`)}},
  7982  			I: allMethods{method: "UnmarshalJSONFrom", value: []byte(`"hello"`)},
  7983  		}),
  7984  	}, {
  7985  		// NOTE: Fixes https://go.dev/issue/29732.
  7986  		name:  jsontest.Name("Methods/MapKey/JSONv2"),
  7987  		inBuf: `{"k1":"v1b","k2":"v2"}`,
  7988  		inVal: addr(map[structMethodJSONv2]string{{"k1"}: "v1a", {"k3"}: "v3"}),
  7989  		want:  addr(map[structMethodJSONv2]string{{"k1"}: "v1b", {"k2"}: "v2", {"k3"}: "v3"}),
  7990  	}, {
  7991  		// NOTE: Fixes https://go.dev/issue/29732.
  7992  		name:  jsontest.Name("Methods/MapKey/JSONv1"),
  7993  		inBuf: `{"k1":"v1b","k2":"v2"}`,
  7994  		inVal: addr(map[structMethodJSONv1]string{{"k1"}: "v1a", {"k3"}: "v3"}),
  7995  		want:  addr(map[structMethodJSONv1]string{{"k1"}: "v1b", {"k2"}: "v2", {"k3"}: "v3"}),
  7996  	}, {
  7997  		name:  jsontest.Name("Methods/MapKey/Text"),
  7998  		inBuf: `{"k1":"v1b","k2":"v2"}`,
  7999  		inVal: addr(map[structMethodText]string{{"k1"}: "v1a", {"k3"}: "v3"}),
  8000  		want:  addr(map[structMethodText]string{{"k1"}: "v1b", {"k2"}: "v2", {"k3"}: "v3"}),
  8001  	}, {
  8002  		name:  jsontest.Name("Methods/JSONv2/ErrUnsupported"),
  8003  		inBuf: `{"fizz":123}`,
  8004  		inVal: addr(unsupportedMethodJSONv2{}),
  8005  		want:  addr(unsupportedMethodJSONv2{"called": 1, "fizz": 123}),
  8006  	}, {
  8007  		name:  jsontest.Name("Methods/Invalid/JSONv2/Error"),
  8008  		inBuf: `{}`,
  8009  		inVal: addr(unmarshalJSONv2Func(func(*jsontext.Decoder) error {
  8010  			return errSomeError
  8011  		})),
  8012  		wantErr: EU(errSomeError).withType(0, T[unmarshalJSONv2Func]()),
  8013  	}, {
  8014  		name:  jsontest.Name("Methods/Invalid/JSONv2/TooFew"),
  8015  		inBuf: `{}`,
  8016  		inVal: addr(unmarshalJSONv2Func(func(*jsontext.Decoder) error {
  8017  			return nil // do nothing
  8018  		})),
  8019  		wantErr: EU(errNonSingularValue).withType(0, T[unmarshalJSONv2Func]()),
  8020  	}, {
  8021  		name:  jsontest.Name("Methods/Invalid/JSONv2/TooMany"),
  8022  		inBuf: `{}{}`,
  8023  		inVal: addr(unmarshalJSONv2Func(func(dec *jsontext.Decoder) error {
  8024  			dec.ReadValue()
  8025  			dec.ReadValue()
  8026  			return nil
  8027  		})),
  8028  		wantErr: EU(errNonSingularValue).withPos(`{}`, "").withType(0, T[unmarshalJSONv2Func]()),
  8029  	}, {
  8030  		name:  jsontest.Name("Methods/Invalid/JSONv2/ErrUnsupported"),
  8031  		inBuf: `{}`,
  8032  		inVal: addr(unmarshalJSONv2Func(func(*jsontext.Decoder) error {
  8033  			return errors.ErrUnsupported
  8034  		})),
  8035  		wantErr: EU(nil).withType(0, T[unmarshalJSONv2Func]()),
  8036  	}, {
  8037  		name:  jsontest.Name("Methods/Invalid/JSONv1/Error"),
  8038  		inBuf: `{}`,
  8039  		inVal: addr(unmarshalJSONv1Func(func([]byte) error {
  8040  			return errSomeError
  8041  		})),
  8042  		wantErr: EU(errSomeError).withType('{', T[unmarshalJSONv1Func]()),
  8043  	}, {
  8044  		name:  jsontest.Name("Methods/Invalid/JSONv1/ErrUnsupported"),
  8045  		inBuf: `{}`,
  8046  		inVal: addr(unmarshalJSONv1Func(func([]byte) error {
  8047  			return errors.ErrUnsupported
  8048  		})),
  8049  		wantErr: EU(wrapErrUnsupported(errors.ErrUnsupported, "UnmarshalJSON method")).withType('{', T[unmarshalJSONv1Func]()),
  8050  	}, {
  8051  		name:  jsontest.Name("Methods/Invalid/Text/Error"),
  8052  		inBuf: `"value"`,
  8053  		inVal: addr(unmarshalTextFunc(func([]byte) error {
  8054  			return errSomeError
  8055  		})),
  8056  		wantErr: EU(errSomeError).withType('"', T[unmarshalTextFunc]()),
  8057  	}, {
  8058  		name:  jsontest.Name("Methods/Invalid/Text/Syntax"),
  8059  		inBuf: `{}`,
  8060  		inVal: addr(unmarshalTextFunc(func([]byte) error {
  8061  			panic("should not be called")
  8062  		})),
  8063  		wantErr: EU(errNonStringValue).withType('{', T[unmarshalTextFunc]()),
  8064  	}, {
  8065  		name:  jsontest.Name("Methods/Invalid/Text/ErrUnsupported"),
  8066  		inBuf: `"value"`,
  8067  		inVal: addr(unmarshalTextFunc(func([]byte) error {
  8068  			return errors.ErrUnsupported
  8069  		})),
  8070  		wantErr: EU(wrapErrUnsupported(errors.ErrUnsupported, "UnmarshalText method")).withType('"', T[unmarshalTextFunc]()),
  8071  	}, {
  8072  		name: jsontest.Name("Functions/String/V1"),
  8073  		opts: []Options{
  8074  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *string) error {
  8075  				if string(b) != `""` {
  8076  					return fmt.Errorf("got %s, want %s", b, `""`)
  8077  				}
  8078  				*v = "called"
  8079  				return nil
  8080  			})),
  8081  		},
  8082  		inBuf: `""`,
  8083  		inVal: addr(""),
  8084  		want:  addr("called"),
  8085  	}, {
  8086  		name:  jsontest.Name("Functions/String/Empty"),
  8087  		opts:  []Options{WithUnmarshalers(nil)},
  8088  		inBuf: `"hello"`,
  8089  		inVal: addr(""),
  8090  		want:  addr("hello"),
  8091  	}, {
  8092  		name: jsontest.Name("Functions/NamedString/V1/NoMatch"),
  8093  		opts: []Options{
  8094  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *namedString) error {
  8095  				panic("should not be called")
  8096  			})),
  8097  		},
  8098  		inBuf: `""`,
  8099  		inVal: addr(""),
  8100  		want:  addr(""),
  8101  	}, {
  8102  		name: jsontest.Name("Functions/NamedString/V1/Match"),
  8103  		opts: []Options{
  8104  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *namedString) error {
  8105  				if string(b) != `""` {
  8106  					return fmt.Errorf("got %s, want %s", b, `""`)
  8107  				}
  8108  				*v = "called"
  8109  				return nil
  8110  			})),
  8111  		},
  8112  		inBuf: `""`,
  8113  		inVal: addr(namedString("")),
  8114  		want:  addr(namedString("called")),
  8115  	}, {
  8116  		name: jsontest.Name("Functions/String/V2"),
  8117  		opts: []Options{
  8118  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8119  				switch b, err := dec.ReadValue(); {
  8120  				case err != nil:
  8121  					return err
  8122  				case string(b) != `""`:
  8123  					return fmt.Errorf("got %s, want %s", b, `""`)
  8124  				}
  8125  				*v = "called"
  8126  				return nil
  8127  			})),
  8128  		},
  8129  		inBuf: `""`,
  8130  		inVal: addr(""),
  8131  		want:  addr("called"),
  8132  	}, {
  8133  		name: jsontest.Name("Functions/NamedString/V2/NoMatch"),
  8134  		opts: []Options{
  8135  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *namedString) error {
  8136  				panic("should not be called")
  8137  			})),
  8138  		},
  8139  		inBuf: `""`,
  8140  		inVal: addr(""),
  8141  		want:  addr(""),
  8142  	}, {
  8143  		name: jsontest.Name("Functions/NamedString/V2/Match"),
  8144  		opts: []Options{
  8145  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *namedString) error {
  8146  				switch t, err := dec.ReadToken(); {
  8147  				case err != nil:
  8148  					return err
  8149  				case t.String() != ``:
  8150  					return fmt.Errorf("got %q, want %q", t, ``)
  8151  				}
  8152  				*v = "called"
  8153  				return nil
  8154  			})),
  8155  		},
  8156  		inBuf: `""`,
  8157  		inVal: addr(namedString("")),
  8158  		want:  addr(namedString("called")),
  8159  	}, {
  8160  		name: jsontest.Name("Functions/String/Empty1/NoMatch"),
  8161  		opts: []Options{
  8162  			WithUnmarshalers(new(Unmarshalers)),
  8163  		},
  8164  		inBuf: `""`,
  8165  		inVal: addr(""),
  8166  		want:  addr(""),
  8167  	}, {
  8168  		name: jsontest.Name("Functions/String/Empty2/NoMatch"),
  8169  		opts: []Options{
  8170  			WithUnmarshalers(JoinUnmarshalers()),
  8171  		},
  8172  		inBuf: `""`,
  8173  		inVal: addr(""),
  8174  		want:  addr(""),
  8175  	}, {
  8176  		name: jsontest.Name("Functions/String/V1/DirectError"),
  8177  		opts: []Options{
  8178  			WithUnmarshalers(UnmarshalFunc(func([]byte, *string) error {
  8179  				return errSomeError
  8180  			})),
  8181  		},
  8182  		inBuf:   `""`,
  8183  		inVal:   addr(""),
  8184  		want:    addr(""),
  8185  		wantErr: EU(errSomeError).withType('"', reflect.PointerTo(stringType)),
  8186  	}, {
  8187  		name: jsontest.Name("Functions/String/V1/SkipError"),
  8188  		opts: []Options{
  8189  			WithUnmarshalers(UnmarshalFunc(func([]byte, *string) error {
  8190  				return errors.ErrUnsupported
  8191  			})),
  8192  		},
  8193  		inBuf:   `""`,
  8194  		inVal:   addr(""),
  8195  		want:    addr(""),
  8196  		wantErr: EU(wrapErrUnsupported(errors.ErrUnsupported, "unmarshal function of type func([]byte, T) error")).withType('"', reflect.PointerTo(stringType)),
  8197  	}, {
  8198  		name: jsontest.Name("Functions/String/V2/DirectError"),
  8199  		opts: []Options{
  8200  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8201  				return errSomeError
  8202  			})),
  8203  		},
  8204  		inBuf:   `""`,
  8205  		inVal:   addr(""),
  8206  		want:    addr(""),
  8207  		wantErr: EU(errSomeError).withType(0, reflect.PointerTo(stringType)),
  8208  	}, {
  8209  		name: jsontest.Name("Functions/String/V2/TooFew"),
  8210  		opts: []Options{
  8211  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8212  				return nil
  8213  			})),
  8214  		},
  8215  		inBuf:   `""`,
  8216  		inVal:   addr(""),
  8217  		want:    addr(""),
  8218  		wantErr: EU(errNonSingularValue).withType(0, reflect.PointerTo(stringType)),
  8219  	}, {
  8220  		name: jsontest.Name("Functions/String/V2/TooMany"),
  8221  		opts: []Options{
  8222  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8223  				if _, err := dec.ReadValue(); err != nil {
  8224  					return err
  8225  				}
  8226  				if _, err := dec.ReadValue(); err != nil {
  8227  					return err
  8228  				}
  8229  				return nil
  8230  			})),
  8231  		},
  8232  		inBuf:   `{"X":["",""]}`,
  8233  		inVal:   addr(struct{ X []string }{}),
  8234  		want:    addr(struct{ X []string }{[]string{""}}),
  8235  		wantErr: EU(errNonSingularValue).withPos(`{"X":["",`, "/X").withType(0, reflect.PointerTo(stringType)),
  8236  	}, {
  8237  		name: jsontest.Name("Functions/String/V2/Skipped"),
  8238  		opts: []Options{
  8239  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8240  				return errors.ErrUnsupported
  8241  			})),
  8242  		},
  8243  		inBuf: `""`,
  8244  		inVal: addr(""),
  8245  		want:  addr(""),
  8246  	}, {
  8247  		name: jsontest.Name("Functions/String/V2/ProcessBeforeSkip"),
  8248  		opts: []Options{
  8249  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8250  				if _, err := dec.ReadValue(); err != nil {
  8251  					return err
  8252  				}
  8253  				return errors.ErrUnsupported
  8254  			})),
  8255  		},
  8256  		inBuf:   `""`,
  8257  		inVal:   addr(""),
  8258  		want:    addr(""),
  8259  		wantErr: EU(errUnsupportedMutation).withType(0, reflect.PointerTo(stringType)),
  8260  	}, {
  8261  		name: jsontest.Name("Functions/String/V2/WrappedUnsupported"),
  8262  		opts: []Options{
  8263  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8264  				return fmt.Errorf("wrap: %w", errors.ErrUnsupported)
  8265  			})),
  8266  		},
  8267  		inBuf: `""`,
  8268  		inVal: addr(""),
  8269  		want:  addr(""),
  8270  	}, {
  8271  		name: jsontest.Name("Functions/Map/Key/NoCaseString/V1"),
  8272  		opts: []Options{
  8273  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *nocaseString) error {
  8274  				if string(b) != `"hello"` {
  8275  					return fmt.Errorf("got %s, want %s", b, `"hello"`)
  8276  				}
  8277  				*v = "called"
  8278  				return nil
  8279  			})),
  8280  		},
  8281  		inBuf: `{"hello":"world"}`,
  8282  		inVal: addr(map[nocaseString]string{}),
  8283  		want:  addr(map[nocaseString]string{"called": "world"}),
  8284  	}, {
  8285  		name: jsontest.Name("Functions/Map/Key/TextMarshaler/V1"),
  8286  		opts: []Options{
  8287  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v encoding.TextMarshaler) error {
  8288  				if string(b) != `"hello"` {
  8289  					return fmt.Errorf("got %s, want %s", b, `"hello"`)
  8290  				}
  8291  				*v.(*nocaseString) = "called"
  8292  				return nil
  8293  			})),
  8294  		},
  8295  		inBuf: `{"hello":"world"}`,
  8296  		inVal: addr(map[nocaseString]string{}),
  8297  		want:  addr(map[nocaseString]string{"called": "world"}),
  8298  	}, {
  8299  		name: jsontest.Name("Functions/Map/Key/NoCaseString/V2"),
  8300  		opts: []Options{
  8301  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *nocaseString) error {
  8302  				switch t, err := dec.ReadToken(); {
  8303  				case err != nil:
  8304  					return err
  8305  				case t.String() != "hello":
  8306  					return fmt.Errorf("got %q, want %q", t, "hello")
  8307  				}
  8308  				*v = "called"
  8309  				return nil
  8310  			})),
  8311  		},
  8312  		inBuf: `{"hello":"world"}`,
  8313  		inVal: addr(map[nocaseString]string{}),
  8314  		want:  addr(map[nocaseString]string{"called": "world"}),
  8315  	}, {
  8316  		name: jsontest.Name("Functions/Map/Key/TextMarshaler/V2"),
  8317  		opts: []Options{
  8318  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v encoding.TextMarshaler) error {
  8319  				switch b, err := dec.ReadValue(); {
  8320  				case err != nil:
  8321  					return err
  8322  				case string(b) != `"hello"`:
  8323  					return fmt.Errorf("got %s, want %s", b, `"hello"`)
  8324  				}
  8325  				*v.(*nocaseString) = "called"
  8326  				return nil
  8327  			})),
  8328  		},
  8329  		inBuf: `{"hello":"world"}`,
  8330  		inVal: addr(map[nocaseString]string{}),
  8331  		want:  addr(map[nocaseString]string{"called": "world"}),
  8332  	}, {
  8333  		name: jsontest.Name("Functions/Map/Key/String/V1/DuplicateName"),
  8334  		opts: []Options{
  8335  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8336  				if _, err := dec.ReadValue(); err != nil {
  8337  					return err
  8338  				}
  8339  				xd := export.Decoder(dec)
  8340  				*v = fmt.Sprintf("%d-%d", len(xd.Tokens.Stack), xd.Tokens.Last.Length())
  8341  				return nil
  8342  			})),
  8343  		},
  8344  		inBuf:   `{"name":"value","name":"value"}`,
  8345  		inVal:   addr(map[string]string{}),
  8346  		want:    addr(map[string]string{"1-1": "1-2"}),
  8347  		wantErr: newDuplicateNameError("", []byte(`"name"`), len64(`{"name":"value",`)),
  8348  	}, {
  8349  		name: jsontest.Name("Functions/Map/Value/NoCaseString/V1"),
  8350  		opts: []Options{
  8351  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *nocaseString) error {
  8352  				if string(b) != `"world"` {
  8353  					return fmt.Errorf("got %s, want %s", b, `"world"`)
  8354  				}
  8355  				*v = "called"
  8356  				return nil
  8357  			})),
  8358  		},
  8359  		inBuf: `{"hello":"world"}`,
  8360  		inVal: addr(map[string]nocaseString{}),
  8361  		want:  addr(map[string]nocaseString{"hello": "called"}),
  8362  	}, {
  8363  		name: jsontest.Name("Functions/Map/Value/TextMarshaler/V1"),
  8364  		opts: []Options{
  8365  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v encoding.TextMarshaler) error {
  8366  				if string(b) != `"world"` {
  8367  					return fmt.Errorf("got %s, want %s", b, `"world"`)
  8368  				}
  8369  				*v.(*nocaseString) = "called"
  8370  				return nil
  8371  			})),
  8372  		},
  8373  		inBuf: `{"hello":"world"}`,
  8374  		inVal: addr(map[string]nocaseString{}),
  8375  		want:  addr(map[string]nocaseString{"hello": "called"}),
  8376  	}, {
  8377  		name: jsontest.Name("Functions/Map/Value/NoCaseString/V2"),
  8378  		opts: []Options{
  8379  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *nocaseString) error {
  8380  				switch t, err := dec.ReadToken(); {
  8381  				case err != nil:
  8382  					return err
  8383  				case t.String() != "world":
  8384  					return fmt.Errorf("got %q, want %q", t, "world")
  8385  				}
  8386  				*v = "called"
  8387  				return nil
  8388  			})),
  8389  		},
  8390  		inBuf: `{"hello":"world"}`,
  8391  		inVal: addr(map[string]nocaseString{}),
  8392  		want:  addr(map[string]nocaseString{"hello": "called"}),
  8393  	}, {
  8394  		name: jsontest.Name("Functions/Map/Value/TextMarshaler/V2"),
  8395  		opts: []Options{
  8396  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v encoding.TextMarshaler) error {
  8397  				switch b, err := dec.ReadValue(); {
  8398  				case err != nil:
  8399  					return err
  8400  				case string(b) != `"world"`:
  8401  					return fmt.Errorf("got %s, want %s", b, `"world"`)
  8402  				}
  8403  				*v.(*nocaseString) = "called"
  8404  				return nil
  8405  			})),
  8406  		},
  8407  		inBuf: `{"hello":"world"}`,
  8408  		inVal: addr(map[string]nocaseString{}),
  8409  		want:  addr(map[string]nocaseString{"hello": "called"}),
  8410  	}, {
  8411  		name: jsontest.Name("Funtions/Struct/Fields"),
  8412  		opts: []Options{
  8413  			WithUnmarshalers(JoinUnmarshalers(
  8414  				UnmarshalFunc(func(b []byte, v *bool) error {
  8415  					if string(b) != `"called1"` {
  8416  						return fmt.Errorf("got %s, want %s", b, `"called1"`)
  8417  					}
  8418  					*v = true
  8419  					return nil
  8420  				}),
  8421  				UnmarshalFunc(func(b []byte, v *string) error {
  8422  					if string(b) != `"called2"` {
  8423  						return fmt.Errorf("got %s, want %s", b, `"called2"`)
  8424  					}
  8425  					*v = "called2"
  8426  					return nil
  8427  				}),
  8428  				UnmarshalFromFunc(func(dec *jsontext.Decoder, v *[]byte) error {
  8429  					switch t, err := dec.ReadToken(); {
  8430  					case err != nil:
  8431  						return err
  8432  					case t.String() != "called3":
  8433  						return fmt.Errorf("got %q, want %q", t, "called3")
  8434  					}
  8435  					*v = []byte("called3")
  8436  					return nil
  8437  				}),
  8438  				UnmarshalFromFunc(func(dec *jsontext.Decoder, v *int64) error {
  8439  					switch b, err := dec.ReadValue(); {
  8440  					case err != nil:
  8441  						return err
  8442  					case string(b) != `"called4"`:
  8443  						return fmt.Errorf("got %s, want %s", b, `"called4"`)
  8444  					}
  8445  					*v = 123
  8446  					return nil
  8447  				}),
  8448  			)),
  8449  		},
  8450  		inBuf: `{"Bool":"called1","String":"called2","Bytes":"called3","Int":"called4","Uint":456,"Float":789}`,
  8451  		inVal: addr(structScalars{}),
  8452  		want:  addr(structScalars{Bool: true, String: "called2", Bytes: []byte("called3"), Int: 123, Uint: 456, Float: 789}),
  8453  	}, {
  8454  		name: jsontest.Name("Functions/Struct/Embedded"),
  8455  		opts: []Options{
  8456  			WithUnmarshalers(JoinUnmarshalers(
  8457  				UnmarshalFunc(func([]byte, *structEmbeddedL1) error {
  8458  					panic("should not be called")
  8459  				}),
  8460  				UnmarshalFromFunc(func(dec *jsontext.Decoder, v *StructEmbed2) error {
  8461  					panic("should not be called")
  8462  				}),
  8463  			)),
  8464  		},
  8465  		inBuf: `{"E":"E3","F":"F3","G":"G3","A":"A1","B":"B1","D":"D2"}`,
  8466  		inVal: new(structEmbedded),
  8467  		want: addr(structEmbedded{
  8468  			X: structEmbeddedL1{
  8469  				X:            &structEmbeddedL2{A: "A1", B: "B1" /* C: "C1" */},
  8470  				StructEmbed1: StructEmbed1{ /* C: "C2" */ D: "D2" /* E: "E2" */},
  8471  			},
  8472  			StructEmbed2: &StructEmbed2{E: "E3", F: "F3", G: "G3"},
  8473  		}),
  8474  	}, {
  8475  		name: jsontest.Name("Functions/Slice/Elem"),
  8476  		opts: []Options{
  8477  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *string) error {
  8478  				*v = strings.Trim(strings.ToUpper(string(b)), `"`)
  8479  				return nil
  8480  			})),
  8481  		},
  8482  		inBuf: `["hello","World"]`,
  8483  		inVal: addr([]string{}),
  8484  		want:  addr([]string{"HELLO", "WORLD"}),
  8485  	}, {
  8486  		name: jsontest.Name("Functions/Array/Elem"),
  8487  		opts: []Options{
  8488  			WithUnmarshalers(UnmarshalFunc(func(b []byte, v *string) error {
  8489  				*v = strings.Trim(strings.ToUpper(string(b)), `"`)
  8490  				return nil
  8491  			})),
  8492  		},
  8493  		inBuf: `["hello","World"]`,
  8494  		inVal: addr([2]string{}),
  8495  		want:  addr([2]string{"HELLO", "WORLD"}),
  8496  	}, {
  8497  		name: jsontest.Name("Functions/Pointer/Nil"),
  8498  		opts: []Options{
  8499  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8500  				t, err := dec.ReadToken()
  8501  				*v = strings.ToUpper(t.String())
  8502  				return err
  8503  			})),
  8504  		},
  8505  		inBuf: `{"X":"hello"}`,
  8506  		inVal: addr(struct{ X *string }{nil}),
  8507  		want:  addr(struct{ X *string }{addr("HELLO")}),
  8508  	}, {
  8509  		name: jsontest.Name("Functions/Pointer/NonNil"),
  8510  		opts: []Options{
  8511  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8512  				t, err := dec.ReadToken()
  8513  				*v = strings.ToUpper(t.String())
  8514  				return err
  8515  			})),
  8516  		},
  8517  		inBuf: `{"X":"hello"}`,
  8518  		inVal: addr(struct{ X *string }{addr("")}),
  8519  		want:  addr(struct{ X *string }{addr("HELLO")}),
  8520  	}, {
  8521  		name: jsontest.Name("Functions/Interface/Nil"),
  8522  		opts: []Options{
  8523  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v fmt.Stringer) error {
  8524  				panic("should not be called")
  8525  			})),
  8526  		},
  8527  		inBuf:   `{"X":"hello"}`,
  8528  		inVal:   addr(struct{ X fmt.Stringer }{nil}),
  8529  		want:    addr(struct{ X fmt.Stringer }{nil}),
  8530  		wantErr: EU(internal.ErrNilInterface).withPos(`{"X":`, "/X").withType(0, T[fmt.Stringer]()),
  8531  	}, {
  8532  		name: jsontest.Name("Functions/Interface/NetIP"),
  8533  		opts: []Options{
  8534  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *fmt.Stringer) error {
  8535  				*v = net.IP{}
  8536  				return errors.ErrUnsupported
  8537  			})),
  8538  		},
  8539  		inBuf: `{"X":"1.1.1.1"}`,
  8540  		inVal: addr(struct{ X fmt.Stringer }{nil}),
  8541  		want:  addr(struct{ X fmt.Stringer }{net.IPv4(1, 1, 1, 1)}),
  8542  	}, {
  8543  		name: jsontest.Name("Functions/Interface/NewPointerNetIP"),
  8544  		opts: []Options{
  8545  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *fmt.Stringer) error {
  8546  				*v = new(net.IP)
  8547  				return errors.ErrUnsupported
  8548  			})),
  8549  		},
  8550  		inBuf: `{"X":"1.1.1.1"}`,
  8551  		inVal: addr(struct{ X fmt.Stringer }{nil}),
  8552  		want:  addr(struct{ X fmt.Stringer }{addr(net.IPv4(1, 1, 1, 1))}),
  8553  	}, {
  8554  		name: jsontest.Name("Functions/Interface/NilPointerNetIP"),
  8555  		opts: []Options{
  8556  			WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, v *fmt.Stringer) error {
  8557  				*v = (*net.IP)(nil)
  8558  				return errors.ErrUnsupported
  8559  			})),
  8560  		},
  8561  		inBuf: `{"X":"1.1.1.1"}`,
  8562  		inVal: addr(struct{ X fmt.Stringer }{nil}),
  8563  		want:  addr(struct{ X fmt.Stringer }{addr(net.IPv4(1, 1, 1, 1))}),
  8564  	}, {
  8565  		name: jsontest.Name("Functions/Interface/NilPointerNetIP/Override"),
  8566  		opts: []Options{
  8567  			WithUnmarshalers(JoinUnmarshalers(
  8568  				UnmarshalFromFunc(func(dec *jsontext.Decoder, v *fmt.Stringer) error {
  8569  					*v = (*net.IP)(nil)
  8570  					return errors.ErrUnsupported
  8571  				}),
  8572  				UnmarshalFunc(func(b []byte, v *net.IP) error {
  8573  					b = bytes.ReplaceAll(b, []byte(`1`), []byte(`8`))
  8574  					return v.UnmarshalText(bytes.Trim(b, `"`))
  8575  				}),
  8576  			)),
  8577  		},
  8578  		inBuf: `{"X":"1.1.1.1"}`,
  8579  		inVal: addr(struct{ X fmt.Stringer }{nil}),
  8580  		want:  addr(struct{ X fmt.Stringer }{addr(net.IPv4(8, 8, 8, 8))}),
  8581  	}, {
  8582  		name: jsontest.Name("Functions/Interface/Any"),
  8583  		opts: []Options{
  8584  			WithUnmarshalers(func() *Unmarshalers {
  8585  				type P struct {
  8586  					D int
  8587  					N int64
  8588  				}
  8589  				type PV struct {
  8590  					P P
  8591  					V any
  8592  				}
  8593  
  8594  				var lastChecks []func() error
  8595  				checkLast := func() error {
  8596  					for _, fn := range lastChecks {
  8597  						if err := fn(); err != nil {
  8598  							return err
  8599  						}
  8600  					}
  8601  					return errors.ErrUnsupported
  8602  				}
  8603  				makeValueChecker := func(name string, want []PV) func(d *jsontext.Decoder, v any) error {
  8604  					checkNext := func(d *jsontext.Decoder, v any) error {
  8605  						xd := export.Decoder(d)
  8606  						p := P{len(xd.Tokens.Stack), xd.Tokens.Last.Length()}
  8607  						rv := reflect.ValueOf(v)
  8608  						pv := PV{p, v}
  8609  						switch {
  8610  						case len(want) == 0:
  8611  							return fmt.Errorf("%s: %v: got more values than expected", name, p)
  8612  						case !rv.IsValid() || rv.Kind() != reflect.Pointer || rv.IsNil():
  8613  							return fmt.Errorf("%s: %v: got %#v, want non-nil pointer type", name, p, v)
  8614  						case !reflect.DeepEqual(pv, want[0]):
  8615  							return fmt.Errorf("%s:\n\tgot  %#v\n\twant %#v", name, pv, want[0])
  8616  						default:
  8617  							want = want[1:]
  8618  							return errors.ErrUnsupported
  8619  						}
  8620  					}
  8621  					lastChecks = append(lastChecks, func() error {
  8622  						if len(want) > 0 {
  8623  							return fmt.Errorf("%s: did not get enough values, want %d more", name, len(want))
  8624  						}
  8625  						return nil
  8626  					})
  8627  					return checkNext
  8628  				}
  8629  				makePositionChecker := func(name string, want []P) func(d *jsontext.Decoder, v any) error {
  8630  					checkNext := func(d *jsontext.Decoder, v any) error {
  8631  						xd := export.Decoder(d)
  8632  						p := P{len(xd.Tokens.Stack), xd.Tokens.Last.Length()}
  8633  						switch {
  8634  						case len(want) == 0:
  8635  							return fmt.Errorf("%s: %v: got more values than wanted", name, p)
  8636  						case p != want[0]:
  8637  							return fmt.Errorf("%s: got %v, want %v", name, p, want[0])
  8638  						default:
  8639  							want = want[1:]
  8640  							return errors.ErrUnsupported
  8641  						}
  8642  					}
  8643  					lastChecks = append(lastChecks, func() error {
  8644  						if len(want) > 0 {
  8645  							return fmt.Errorf("%s: did not get enough values, want %d more", name, len(want))
  8646  						}
  8647  						return nil
  8648  					})
  8649  					return checkNext
  8650  				}
  8651  
  8652  				// In contrast to marshal, unmarshal automatically allocates for
  8653  				// nil pointers, which causes unmarshal to visit more values.
  8654  				wantAny := []PV{
  8655  					{P{1, 0}, addr(any(nil))},
  8656  					{P{1, 1}, addr(any(valueStringer{}))},
  8657  					{P{1, 1}, addr(valueStringer{})},
  8658  					{P{1, 2}, addr(any((*valueStringer)(nil)))},
  8659  					{P{1, 2}, addr((*valueStringer)(nil))},
  8660  					{P{1, 2}, addr(valueStringer{})},
  8661  					{P{1, 3}, addr(any(addr(valueStringer{})))},
  8662  					{P{1, 3}, addr(addr(valueStringer{}))},
  8663  					{P{1, 3}, addr(valueStringer{})},
  8664  					{P{1, 4}, addr(any((**valueStringer)(nil)))},
  8665  					{P{1, 4}, addr((**valueStringer)(nil))},
  8666  					{P{1, 4}, addr((*valueStringer)(nil))},
  8667  					{P{1, 4}, addr(valueStringer{})},
  8668  					{P{1, 5}, addr(any(addr((*valueStringer)(nil))))},
  8669  					{P{1, 5}, addr(addr((*valueStringer)(nil)))},
  8670  					{P{1, 5}, addr((*valueStringer)(nil))},
  8671  					{P{1, 5}, addr(valueStringer{})},
  8672  					{P{1, 6}, addr(any(addr(addr(valueStringer{}))))},
  8673  					{P{1, 6}, addr(addr(addr(valueStringer{})))},
  8674  					{P{1, 6}, addr(addr(valueStringer{}))},
  8675  					{P{1, 6}, addr(valueStringer{})},
  8676  					{P{1, 7}, addr(any(pointerStringer{}))},
  8677  					{P{1, 7}, addr(pointerStringer{})},
  8678  					{P{1, 8}, addr(any((*pointerStringer)(nil)))},
  8679  					{P{1, 8}, addr((*pointerStringer)(nil))},
  8680  					{P{1, 8}, addr(pointerStringer{})},
  8681  					{P{1, 9}, addr(any(addr(pointerStringer{})))},
  8682  					{P{1, 9}, addr(addr(pointerStringer{}))},
  8683  					{P{1, 9}, addr(pointerStringer{})},
  8684  					{P{1, 10}, addr(any((**pointerStringer)(nil)))},
  8685  					{P{1, 10}, addr((**pointerStringer)(nil))},
  8686  					{P{1, 10}, addr((*pointerStringer)(nil))},
  8687  					{P{1, 10}, addr(pointerStringer{})},
  8688  					{P{1, 11}, addr(any(addr((*pointerStringer)(nil))))},
  8689  					{P{1, 11}, addr(addr((*pointerStringer)(nil)))},
  8690  					{P{1, 11}, addr((*pointerStringer)(nil))},
  8691  					{P{1, 11}, addr(pointerStringer{})},
  8692  					{P{1, 12}, addr(any(addr(addr(pointerStringer{}))))},
  8693  					{P{1, 12}, addr(addr(addr(pointerStringer{})))},
  8694  					{P{1, 12}, addr(addr(pointerStringer{}))},
  8695  					{P{1, 12}, addr(pointerStringer{})},
  8696  					{P{1, 13}, addr(any("LAST"))},
  8697  					{P{1, 13}, addr("LAST")},
  8698  				}
  8699  				checkAny := makeValueChecker("any", wantAny)
  8700  				anyUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v any) error {
  8701  					return checkAny(dec, v)
  8702  				})
  8703  
  8704  				var wantPointerAny []PV
  8705  				for _, v := range wantAny {
  8706  					if _, ok := v.V.(*any); ok {
  8707  						wantPointerAny = append(wantPointerAny, v)
  8708  					}
  8709  				}
  8710  				checkPointerAny := makeValueChecker("*any", wantPointerAny)
  8711  				pointerAnyUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v *any) error {
  8712  					return checkPointerAny(dec, v)
  8713  				})
  8714  
  8715  				checkNamedAny := makeValueChecker("namedAny", wantAny)
  8716  				namedAnyUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v namedAny) error {
  8717  					return checkNamedAny(dec, v)
  8718  				})
  8719  
  8720  				checkPointerNamedAny := makeValueChecker("*namedAny", nil)
  8721  				pointerNamedAnyUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v *namedAny) error {
  8722  					return checkPointerNamedAny(dec, v)
  8723  				})
  8724  
  8725  				type stringer = fmt.Stringer
  8726  				var wantStringer []PV
  8727  				for _, v := range wantAny {
  8728  					if _, ok := v.V.(stringer); ok {
  8729  						wantStringer = append(wantStringer, v)
  8730  					}
  8731  				}
  8732  				checkStringer := makeValueChecker("stringer", wantStringer)
  8733  				stringerUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v stringer) error {
  8734  					return checkStringer(dec, v)
  8735  				})
  8736  
  8737  				checkPointerStringer := makeValueChecker("*stringer", nil)
  8738  				pointerStringerUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v *stringer) error {
  8739  					return checkPointerStringer(dec, v)
  8740  				})
  8741  
  8742  				wantValueStringer := []P{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}}
  8743  				checkPointerValueStringer := makePositionChecker("*valueStringer", wantValueStringer)
  8744  				pointerValueStringerUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v *valueStringer) error {
  8745  					return checkPointerValueStringer(dec, v)
  8746  				})
  8747  
  8748  				wantPointerStringer := []P{{1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {1, 12}}
  8749  				checkPointerPointerStringer := makePositionChecker("*pointerStringer", wantPointerStringer)
  8750  				pointerPointerStringerUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v *pointerStringer) error {
  8751  					return checkPointerPointerStringer(dec, v)
  8752  				})
  8753  
  8754  				lastUnmarshaler := UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8755  					return checkLast()
  8756  				})
  8757  
  8758  				return JoinUnmarshalers(
  8759  					// This is just like unmarshaling into a Go array,
  8760  					// but avoids zeroing the element before calling unmarshal.
  8761  					UnmarshalFromFunc(func(dec *jsontext.Decoder, v *[14]any) error {
  8762  						if _, err := dec.ReadToken(); err != nil {
  8763  							return err
  8764  						}
  8765  						for i := range len(*v) {
  8766  							if err := UnmarshalDecode(dec, &(*v)[i]); err != nil {
  8767  								return err
  8768  							}
  8769  						}
  8770  						if _, err := dec.ReadToken(); err != nil {
  8771  							return err
  8772  						}
  8773  						return nil
  8774  					}),
  8775  
  8776  					anyUnmarshaler,
  8777  					pointerAnyUnmarshaler,
  8778  					namedAnyUnmarshaler,
  8779  					pointerNamedAnyUnmarshaler, // never called
  8780  					stringerUnmarshaler,
  8781  					pointerStringerUnmarshaler, // never called
  8782  					pointerValueStringerUnmarshaler,
  8783  					pointerPointerStringerUnmarshaler,
  8784  					lastUnmarshaler,
  8785  				)
  8786  			}()),
  8787  		},
  8788  		inBuf: `[null,{},{},{},{},{},{},{},{},{},{},{},{},"LAST"]`,
  8789  		inVal: addr([...]any{
  8790  			nil,                           // nil
  8791  			valueStringer{},               // T
  8792  			(*valueStringer)(nil),         // *T
  8793  			addr(valueStringer{}),         // *T
  8794  			(**valueStringer)(nil),        // **T
  8795  			addr((*valueStringer)(nil)),   // **T
  8796  			addr(addr(valueStringer{})),   // **T
  8797  			pointerStringer{},             // T
  8798  			(*pointerStringer)(nil),       // *T
  8799  			addr(pointerStringer{}),       // *T
  8800  			(**pointerStringer)(nil),      // **T
  8801  			addr((*pointerStringer)(nil)), // **T
  8802  			addr(addr(pointerStringer{})), // **T
  8803  			"LAST",
  8804  		}),
  8805  	}, {
  8806  		name: jsontest.Name("Functions/Precedence/V1First"),
  8807  		opts: []Options{
  8808  			WithUnmarshalers(JoinUnmarshalers(
  8809  				UnmarshalFunc(func(b []byte, v *string) error {
  8810  					if string(b) != `"called"` {
  8811  						return fmt.Errorf("got %s, want %s", b, `"called"`)
  8812  					}
  8813  					*v = "called"
  8814  					return nil
  8815  				}),
  8816  				UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8817  					panic("should not be called")
  8818  				}),
  8819  			)),
  8820  		},
  8821  		inBuf: `"called"`,
  8822  		inVal: addr(""),
  8823  		want:  addr("called"),
  8824  	}, {
  8825  		name: jsontest.Name("Functions/Precedence/V2First"),
  8826  		opts: []Options{
  8827  			WithUnmarshalers(JoinUnmarshalers(
  8828  				UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8829  					switch t, err := dec.ReadToken(); {
  8830  					case err != nil:
  8831  						return err
  8832  					case t.String() != "called":
  8833  						return fmt.Errorf("got %q, want %q", t, "called")
  8834  					}
  8835  					*v = "called"
  8836  					return nil
  8837  				}),
  8838  				UnmarshalFunc(func([]byte, *string) error {
  8839  					panic("should not be called")
  8840  				}),
  8841  			)),
  8842  		},
  8843  		inBuf: `"called"`,
  8844  		inVal: addr(""),
  8845  		want:  addr("called"),
  8846  	}, {
  8847  		name: jsontest.Name("Functions/Precedence/V2Skipped"),
  8848  		opts: []Options{
  8849  			WithUnmarshalers(JoinUnmarshalers(
  8850  				UnmarshalFromFunc(func(dec *jsontext.Decoder, v *string) error {
  8851  					return errors.ErrUnsupported
  8852  				}),
  8853  				UnmarshalFunc(func(b []byte, v *string) error {
  8854  					if string(b) != `"called"` {
  8855  						return fmt.Errorf("got %s, want %s", b, `"called"`)
  8856  					}
  8857  					*v = "called"
  8858  					return nil
  8859  				}),
  8860  			)),
  8861  		},
  8862  		inBuf: `"called"`,
  8863  		inVal: addr(""),
  8864  		want:  addr("called"),
  8865  	}, {
  8866  		name: jsontest.Name("Functions/Precedence/NestedFirst"),
  8867  		opts: []Options{
  8868  			WithUnmarshalers(JoinUnmarshalers(
  8869  				JoinUnmarshalers(
  8870  					UnmarshalFunc(func(b []byte, v *string) error {
  8871  						if string(b) != `"called"` {
  8872  							return fmt.Errorf("got %s, want %s", b, `"called"`)
  8873  						}
  8874  						*v = "called"
  8875  						return nil
  8876  					}),
  8877  				),
  8878  				UnmarshalFunc(func([]byte, *string) error {
  8879  					panic("should not be called")
  8880  				}),
  8881  			)),
  8882  		},
  8883  		inBuf: `"called"`,
  8884  		inVal: addr(""),
  8885  		want:  addr("called"),
  8886  	}, {
  8887  		name: jsontest.Name("Functions/Precedence/NestedLast"),
  8888  		opts: []Options{
  8889  			WithUnmarshalers(JoinUnmarshalers(
  8890  				UnmarshalFunc(func(b []byte, v *string) error {
  8891  					if string(b) != `"called"` {
  8892  						return fmt.Errorf("got %s, want %s", b, `"called"`)
  8893  					}
  8894  					*v = "called"
  8895  					return nil
  8896  				}),
  8897  				JoinUnmarshalers(
  8898  					UnmarshalFunc(func([]byte, *string) error {
  8899  						panic("should not be called")
  8900  					}),
  8901  				),
  8902  			)),
  8903  		},
  8904  		inBuf: `"called"`,
  8905  		inVal: addr(""),
  8906  		want:  addr("called"),
  8907  	}, {
  8908  		name:  jsontest.Name("Duration/Null"),
  8909  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  8910  		inBuf: `{"D1":null,"D2":null}`,
  8911  		inVal: addr(struct {
  8912  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  8913  			D2 time.Duration `json:",format:nano"`
  8914  		}{1, 1}),
  8915  		want: addr(struct {
  8916  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  8917  			D2 time.Duration `json:",format:nano"`
  8918  		}{0, 0}),
  8919  	}, {
  8920  		name:  jsontest.Name("Duration/Zero"),
  8921  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  8922  		inBuf: `{"D1":"0s","D2":0}`,
  8923  		inVal: addr(struct {
  8924  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  8925  			D2 time.Duration `json:",format:nano"`
  8926  		}{1, 1}),
  8927  		want: addr(struct {
  8928  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  8929  			D2 time.Duration `json:",format:nano"`
  8930  		}{0, 0}),
  8931  	}, {
  8932  		name:  jsontest.Name("Duration/Positive"),
  8933  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  8934  		inBuf: `{"D1":"34293h33m9.123456789s","D2":123456789123456789}`,
  8935  		inVal: new(struct {
  8936  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  8937  			D2 time.Duration `json:",format:nano"`
  8938  		}),
  8939  		want: addr(struct {
  8940  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  8941  			D2 time.Duration `json:",format:nano"`
  8942  		}{
  8943  			123456789123456789,
  8944  			123456789123456789,
  8945  		}),
  8946  	}, {
  8947  		name:  jsontest.Name("Duration/Negative"),
  8948  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  8949  		inBuf: `{"D1":"-34293h33m9.123456789s","D2":-123456789123456789}`,
  8950  		inVal: new(struct {
  8951  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  8952  			D2 time.Duration `json:",format:nano"`
  8953  		}),
  8954  		want: addr(struct {
  8955  			D1 time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  8956  			D2 time.Duration `json:",format:nano"`
  8957  		}{
  8958  			-123456789123456789,
  8959  			-123456789123456789,
  8960  		}),
  8961  	}, {
  8962  		name:  jsontest.Name("Duration/Nanos/String"),
  8963  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  8964  		inBuf: `{"D":"12345"}`,
  8965  		inVal: addr(struct {
  8966  			D time.Duration `json:",string,format:nano"`
  8967  		}{1}),
  8968  		want: addr(struct {
  8969  			D time.Duration `json:",string,format:nano"`
  8970  		}{12345}),
  8971  	}, {
  8972  		name:  jsontest.Name("Duration/Nanos/String/Invalid"),
  8973  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  8974  		inBuf: `{"D":"+12345"}`,
  8975  		inVal: addr(struct {
  8976  			D time.Duration `json:",string,format:nano"`
  8977  		}{1}),
  8978  		want: addr(struct {
  8979  			D time.Duration `json:",string,format:nano"`
  8980  		}{1}),
  8981  		wantErr: EU(fmt.Errorf(`invalid duration "+12345": %w`, strconv.ErrSyntax)).withPos(`{"D":`, "/D").withType('"', timeDurationType),
  8982  	}, {
  8983  		name:  jsontest.Name("Duration/Nanos/Mismatch"),
  8984  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  8985  		inBuf: `{"D":"34293h33m9.123456789s"}`,
  8986  		inVal: addr(struct {
  8987  			D time.Duration `json:",format:nano"`
  8988  		}{1}),
  8989  		want: addr(struct {
  8990  			D time.Duration `json:",format:nano"`
  8991  		}{1}),
  8992  		wantErr: EU(nil).withPos(`{"D":`, "/D").withType('"', timeDurationType),
  8993  	}, {
  8994  		name:  jsontest.Name("Duration/Nanos"),
  8995  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  8996  		inBuf: `{"D":1.324}`,
  8997  		inVal: addr(struct {
  8998  			D time.Duration `json:",format:nano"`
  8999  		}{-1}),
  9000  		want: addr(struct {
  9001  			D time.Duration `json:",format:nano"`
  9002  		}{1}),
  9003  	}, {
  9004  		name:  jsontest.Name("Duration/String/Mismatch"),
  9005  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9006  		inBuf: `{"D":-123456789123456789}`,
  9007  		inVal: addr(struct {
  9008  			D time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  9009  		}{1}),
  9010  		want: addr(struct {
  9011  			D time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  9012  		}{1}),
  9013  		wantErr: EU(nil).withPos(`{"D":`, "/D").withType('0', timeDurationType),
  9014  	}, {
  9015  		name:  jsontest.Name("Duration/String/Invalid"),
  9016  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9017  		inBuf: `{"D":"5minkutes"}`,
  9018  		inVal: addr(struct {
  9019  			D time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  9020  		}{1}),
  9021  		want: addr(struct {
  9022  			D time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  9023  		}{1}),
  9024  		wantErr: EU(func() error {
  9025  			_, err := time.ParseDuration("5minkutes")
  9026  			return err
  9027  		}()).withPos(`{"D":`, "/D").withType('"', timeDurationType),
  9028  	}, {
  9029  		name:  jsontest.Name("Duration/Syntax/Invalid"),
  9030  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9031  		inBuf: `{"D":x}`,
  9032  		inVal: addr(struct {
  9033  			D time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  9034  		}{1}),
  9035  		want: addr(struct {
  9036  			D time.Duration `json:",format:units"` // TODO(https://go.dev/issue/71631): Remove the format flag.
  9037  		}{1}),
  9038  		wantErr: newInvalidCharacterError("x", "at start of value", len64(`{"D":`), "/D"),
  9039  	}, {
  9040  		name: jsontest.Name("Duration/Format"),
  9041  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9042  		inBuf: `{
  9043  			"D1": "12h34m56.078090012s",
  9044  			"D2": "12h34m56.078090012s",
  9045  			"D3": 45296.078090012,
  9046  			"D4": "45296.078090012",
  9047  			"D5": 45296078.090012,
  9048  			"D6": "45296078.090012",
  9049  			"D7": 45296078090.012,
  9050  			"D8": "45296078090.012",
  9051  			"D9": 45296078090012,
  9052  			"D10": "45296078090012",
  9053  			"D11": "PT12H34M56.078090012S"
  9054          }`,
  9055  		inVal: new(structDurationFormat),
  9056  		want: addr(structDurationFormat{
  9057  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9058  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9059  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9060  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9061  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9062  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9063  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9064  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9065  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9066  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9067  			12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9068  		}),
  9069  	}, {
  9070  		name:  jsontest.Name("Duration/Format/Invalid"),
  9071  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9072  		inBuf: `{"D":"0s"}`,
  9073  		inVal: addr(struct {
  9074  			D time.Duration `json:",format:invalid"`
  9075  		}{1}),
  9076  		want: addr(struct {
  9077  			D time.Duration `json:",format:invalid"`
  9078  		}{1}),
  9079  		wantErr: EU(errInvalidFormatFlag).withPos(`{"D":`, "/D").withType(0, timeDurationType),
  9080  	}, {
  9081  		/* TODO(https://go.dev/issue/71631): Re-enable this test case.
  9082  		name:  jsontest.Name("Duration/Format/Legacy"),
  9083  		opts:  []Options{jsonflags.FormatDurationAsNano | 1},
  9084  		inBuf: `{"D1":45296078090012,"D2":"12h34m56.078090012s"}`,
  9085  		inVal: new(structDurationFormat),
  9086  		want: addr(structDurationFormat{
  9087  			D1: 12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9088  			D2: 12*time.Hour + 34*time.Minute + 56*time.Second + 78*time.Millisecond + 90*time.Microsecond + 12*time.Nanosecond,
  9089  		}),
  9090  		}, { */
  9091  		/* TODO(https://go.dev/issue/71631): Re-enable this test case.
  9092  		name:  jsontest.Name("Duration/MapKey"),
  9093  		inBuf: `{"1s":""}`,
  9094  		inVal: new(map[time.Duration]string),
  9095  		want:  addr(map[time.Duration]string{time.Second: ""}),
  9096  		}, { */
  9097  		name:  jsontest.Name("Duration/MapKey/Legacy"),
  9098  		opts:  []Options{jsonflags.FormatDurationAsNano | 1},
  9099  		inBuf: `{"1000000000":""}`,
  9100  		inVal: new(map[time.Duration]string),
  9101  		want:  addr(map[time.Duration]string{time.Second: ""}),
  9102  	}, {
  9103  		/* TODO(https://go.dev/issue/71631): Re-enable this test case.
  9104  		name:  jsontest.Name("Duration/IgnoreInvalidFormat"),
  9105  		opts:  []Options{invalidFormatOption},
  9106  		inBuf: `"1s"`,
  9107  		inVal: addr(time.Duration(0)),
  9108  		want:  addr(time.Second),
  9109  		}, { */
  9110  		name:  jsontest.Name("Time/Zero"),
  9111  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9112  		inBuf: `{"T1":"0001-01-01T00:00:00Z","T2":"01 Jan 01 00:00 UTC","T3":"0001-01-01","T4":"0001-01-01T00:00:00Z","T5":"0001-01-01T00:00:00Z"}`,
  9113  		inVal: new(struct {
  9114  			T1 time.Time
  9115  			T2 time.Time `json:",format:RFC822"`
  9116  			T3 time.Time `json:",format:'2006-01-02'"`
  9117  			T4 time.Time `json:",omitzero"`
  9118  			T5 time.Time `json:",omitempty"`
  9119  		}),
  9120  		want: addr(struct {
  9121  			T1 time.Time
  9122  			T2 time.Time `json:",format:RFC822"`
  9123  			T3 time.Time `json:",format:'2006-01-02'"`
  9124  			T4 time.Time `json:",omitzero"`
  9125  			T5 time.Time `json:",omitempty"`
  9126  		}{
  9127  			mustParseTime(time.RFC3339Nano, "0001-01-01T00:00:00Z"),
  9128  			mustParseTime(time.RFC822, "01 Jan 01 00:00 UTC"),
  9129  			mustParseTime("2006-01-02", "0001-01-01"),
  9130  			mustParseTime(time.RFC3339Nano, "0001-01-01T00:00:00Z"),
  9131  			mustParseTime(time.RFC3339Nano, "0001-01-01T00:00:00Z"),
  9132  		}),
  9133  	}, {
  9134  		name: jsontest.Name("Time/Format"),
  9135  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9136  		inBuf: `{
  9137  			"T1": "1234-01-02T03:04:05.000000006Z",
  9138  			"T2": "Mon Jan  2 03:04:05 1234",
  9139  			"T3": "Mon Jan  2 03:04:05 UTC 1234",
  9140  			"T4": "Mon Jan 02 03:04:05 +0000 1234",
  9141  			"T5": "02 Jan 34 03:04 UTC",
  9142  			"T6": "02 Jan 34 03:04 +0000",
  9143  			"T7": "Monday, 02-Jan-34 03:04:05 UTC",
  9144  			"T8": "Mon, 02 Jan 1234 03:04:05 UTC",
  9145  			"T9": "Mon, 02 Jan 1234 03:04:05 +0000",
  9146  			"T10": "1234-01-02T03:04:05Z",
  9147  			"T11": "1234-01-02T03:04:05.000000006Z",
  9148  			"T12": "3:04AM",
  9149  			"T13": "Jan  2 03:04:05",
  9150  			"T14": "Jan  2 03:04:05.000",
  9151  			"T15": "Jan  2 03:04:05.000000",
  9152  			"T16": "Jan  2 03:04:05.000000006",
  9153  			"T17": "1234-01-02 03:04:05",
  9154  			"T18": "1234-01-02",
  9155  			"T19": "03:04:05",
  9156  			"T20": "1234-01-02",
  9157  			"T21": "\"weird\"1234",
  9158  			"T22": -23225777754.999999994,
  9159  			"T23": "-23225777754.999999994",
  9160  			"T24": -23225777754999.999994,
  9161  			"T25": "-23225777754999.999994",
  9162  			"T26": -23225777754999999.994,
  9163  			"T27": "-23225777754999999.994",
  9164  			"T28": -23225777754999999994,
  9165  			"T29": "-23225777754999999994"
  9166  		}`,
  9167  		inVal: new(structTimeFormat),
  9168  		want: addr(structTimeFormat{
  9169  			mustParseTime(time.RFC3339Nano, "1234-01-02T03:04:05.000000006Z"),
  9170  			mustParseTime(time.ANSIC, "Mon Jan  2 03:04:05 1234"),
  9171  			mustParseTime(time.UnixDate, "Mon Jan  2 03:04:05 UTC 1234"),
  9172  			mustParseTime(time.RubyDate, "Mon Jan 02 03:04:05 +0000 1234"),
  9173  			mustParseTime(time.RFC822, "02 Jan 34 03:04 UTC"),
  9174  			mustParseTime(time.RFC822Z, "02 Jan 34 03:04 +0000"),
  9175  			mustParseTime(time.RFC850, "Monday, 02-Jan-34 03:04:05 UTC"),
  9176  			mustParseTime(time.RFC1123, "Mon, 02 Jan 1234 03:04:05 UTC"),
  9177  			mustParseTime(time.RFC1123Z, "Mon, 02 Jan 1234 03:04:05 +0000"),
  9178  			mustParseTime(time.RFC3339, "1234-01-02T03:04:05Z"),
  9179  			mustParseTime(time.RFC3339Nano, "1234-01-02T03:04:05.000000006Z"),
  9180  			mustParseTime(time.Kitchen, "3:04AM"),
  9181  			mustParseTime(time.Stamp, "Jan  2 03:04:05"),
  9182  			mustParseTime(time.StampMilli, "Jan  2 03:04:05.000"),
  9183  			mustParseTime(time.StampMicro, "Jan  2 03:04:05.000000"),
  9184  			mustParseTime(time.StampNano, "Jan  2 03:04:05.000000006"),
  9185  			mustParseTime(time.DateTime, "1234-01-02 03:04:05"),
  9186  			mustParseTime(time.DateOnly, "1234-01-02"),
  9187  			mustParseTime(time.TimeOnly, "03:04:05"),
  9188  			mustParseTime("2006-01-02", "1234-01-02"),
  9189  			mustParseTime(`\"weird\"2006`, `\"weird\"1234`),
  9190  			time.Unix(-23225777755, 6).UTC(),
  9191  			time.Unix(-23225777755, 6).UTC(),
  9192  			time.Unix(-23225777755, 6).UTC(),
  9193  			time.Unix(-23225777755, 6).UTC(),
  9194  			time.Unix(-23225777755, 6).UTC(),
  9195  			time.Unix(-23225777755, 6).UTC(),
  9196  			time.Unix(-23225777755, 6).UTC(),
  9197  			time.Unix(-23225777755, 6).UTC(),
  9198  		}),
  9199  	}, {
  9200  		name:    jsontest.Name("Time/Format/String/Invalid"),
  9201  		opts:    []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9202  		inBuf:   `{"T":"2023-01-01T00:00:00Z"}`,
  9203  		inVal:   new(structTimeFormatStringInvalid),
  9204  		want:    new(structTimeFormatStringInvalid),
  9205  		wantErr: EU(errInvalidStringTag).withPos(`{"T":`, "/T").withType(0, timeTimeType),
  9206  	}, {
  9207  		name: jsontest.Name("Time/Format/UnixString/InvalidNumber"),
  9208  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9209  		inBuf: `{
  9210  			"T23": -23225777754.999999994,
  9211  			"T25": -23225777754999.999994,
  9212  			"T27": -23225777754999999.994,
  9213  			"T29": -23225777754999999994
  9214  		}`,
  9215  		inVal:   new(structTimeFormat),
  9216  		want:    new(structTimeFormat),
  9217  		wantErr: EU(nil).withPos(`{`+"\n\t\t\t"+`"T23": `, "/T23").withType('0', timeTimeType),
  9218  	}, {
  9219  		name: jsontest.Name("Time/Format/UnixString/InvalidString"),
  9220  		opts: []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9221  		inBuf: `{
  9222  			"T22": "-23225777754.999999994",
  9223  			"T24": "-23225777754999.999994",
  9224  			"T26": "-23225777754999999.994",
  9225  			"T28": "-23225777754999999994"
  9226  		}`,
  9227  		inVal:   new(structTimeFormat),
  9228  		want:    new(structTimeFormat),
  9229  		wantErr: EU(nil).withPos(`{`+"\n\t\t\t"+`"T22": `, "/T22").withType('"', timeTimeType),
  9230  	}, {
  9231  		name:  jsontest.Name("Time/Format/Null"),
  9232  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9233  		inBuf: `{"T1":null,"T2":null,"T3":null,"T4":null,"T5":null,"T6":null,"T7":null,"T8":null,"T9":null,"T10":null,"T11":null,"T12":null,"T13":null,"T14":null,"T15":null,"T16":null,"T17":null,"T18":null,"T19":null,"T20":null,"T21":null,"T22":null,"T23":null,"T24":null,"T25":null,"T26":null,"T27":null,"T28":null,"T29":null}`,
  9234  		inVal: addr(structTimeFormat{
  9235  			mustParseTime(time.RFC3339Nano, "1234-01-02T03:04:05.000000006Z"),
  9236  			mustParseTime(time.ANSIC, "Mon Jan  2 03:04:05 1234"),
  9237  			mustParseTime(time.UnixDate, "Mon Jan  2 03:04:05 UTC 1234"),
  9238  			mustParseTime(time.RubyDate, "Mon Jan 02 03:04:05 +0000 1234"),
  9239  			mustParseTime(time.RFC822, "02 Jan 34 03:04 UTC"),
  9240  			mustParseTime(time.RFC822Z, "02 Jan 34 03:04 +0000"),
  9241  			mustParseTime(time.RFC850, "Monday, 02-Jan-34 03:04:05 UTC"),
  9242  			mustParseTime(time.RFC1123, "Mon, 02 Jan 1234 03:04:05 UTC"),
  9243  			mustParseTime(time.RFC1123Z, "Mon, 02 Jan 1234 03:04:05 +0000"),
  9244  			mustParseTime(time.RFC3339, "1234-01-02T03:04:05Z"),
  9245  			mustParseTime(time.RFC3339Nano, "1234-01-02T03:04:05.000000006Z"),
  9246  			mustParseTime(time.Kitchen, "3:04AM"),
  9247  			mustParseTime(time.Stamp, "Jan  2 03:04:05"),
  9248  			mustParseTime(time.StampMilli, "Jan  2 03:04:05.000"),
  9249  			mustParseTime(time.StampMicro, "Jan  2 03:04:05.000000"),
  9250  			mustParseTime(time.StampNano, "Jan  2 03:04:05.000000006"),
  9251  			mustParseTime(time.DateTime, "1234-01-02 03:04:05"),
  9252  			mustParseTime(time.DateOnly, "1234-01-02"),
  9253  			mustParseTime(time.TimeOnly, "03:04:05"),
  9254  			mustParseTime("2006-01-02", "1234-01-02"),
  9255  			mustParseTime(`\"weird\"2006`, `\"weird\"1234`),
  9256  			time.Unix(-23225777755, 6).UTC(),
  9257  			time.Unix(-23225777755, 6).UTC(),
  9258  			time.Unix(-23225777755, 6).UTC(),
  9259  			time.Unix(-23225777755, 6).UTC(),
  9260  			time.Unix(-23225777755, 6).UTC(),
  9261  			time.Unix(-23225777755, 6).UTC(),
  9262  			time.Unix(-23225777755, 6).UTC(),
  9263  			time.Unix(-23225777755, 6).UTC(),
  9264  		}),
  9265  		want: new(structTimeFormat),
  9266  	}, {
  9267  		name:  jsontest.Name("Time/RFC3339/Mismatch"),
  9268  		inBuf: `{"T":1234}`,
  9269  		inVal: new(struct {
  9270  			T time.Time
  9271  		}),
  9272  		wantErr: EU(nil).withPos(`{"T":`, "/T").withType('0', timeTimeType),
  9273  	}, {
  9274  		name:  jsontest.Name("Time/RFC3339/ParseError"),
  9275  		inBuf: `{"T":"2021-09-29T12:44:52"}`,
  9276  		inVal: new(struct {
  9277  			T time.Time
  9278  		}),
  9279  		wantErr: EU(func() error {
  9280  			_, err := time.Parse(time.RFC3339, "2021-09-29T12:44:52")
  9281  			return err
  9282  		}()).withPos(`{"T":`, "/T").withType('"', timeTimeType),
  9283  	}, {
  9284  		name:  jsontest.Name("Time/Format/Invalid"),
  9285  		opts:  []Options{jsonopts.ExperimentalSupportFormatTag(true)},
  9286  		inBuf: `{"T":""}`,
  9287  		inVal: new(struct {
  9288  			T time.Time `json:",format:UndefinedConstant"`
  9289  		}),
  9290  		wantErr: EU(errors.New(`invalid format flag "UndefinedConstant"`)).withPos(`{"T":`, "/T").withType(0, timeTimeType),
  9291  	}, {
  9292  		name:    jsontest.Name("Time/Format/SingleDigitHour"),
  9293  		inBuf:   `{"T":"2000-01-01T1:12:34Z"}`,
  9294  		inVal:   new(struct{ T time.Time }),
  9295  		wantErr: EU(newParseTimeError(time.RFC3339, "2000-01-01T1:12:34Z", "15", "1", "")).withPos(`{"T":`, "/T").withType('"', timeTimeType),
  9296  	}, {
  9297  		name:    jsontest.Name("Time/Format/SubsecondComma"),
  9298  		inBuf:   `{"T":"2000-01-01T00:00:00,000Z"}`,
  9299  		inVal:   new(struct{ T time.Time }),
  9300  		wantErr: EU(newParseTimeError(time.RFC3339, "2000-01-01T00:00:00,000Z", ".", ",", "")).withPos(`{"T":`, "/T").withType('"', timeTimeType),
  9301  	}, {
  9302  		name:    jsontest.Name("Time/Format/TimezoneHourOverflow"),
  9303  		inBuf:   `{"T":"2000-01-01T00:00:00+24:00"}`,
  9304  		inVal:   new(struct{ T time.Time }),
  9305  		wantErr: EU(newParseTimeError(time.RFC3339, "2000-01-01T00:00:00+24:00", "Z07:00", "+24:00", ": timezone hour out of range")).withPos(`{"T":`, "/T").withType('"', timeTimeType),
  9306  	}, {
  9307  		name:    jsontest.Name("Time/Format/TimezoneMinuteOverflow"),
  9308  		inBuf:   `{"T":"2000-01-01T00:00:00+00:60"}`,
  9309  		inVal:   new(struct{ T time.Time }),
  9310  		wantErr: EU(newParseTimeError(time.RFC3339, "2000-01-01T00:00:00+00:60", "Z07:00", "+00:60", ": timezone minute out of range")).withPos(`{"T":`, "/T").withType('"', timeTimeType),
  9311  	}, {
  9312  		name:  jsontest.Name("Time/Syntax/Invalid"),
  9313  		inBuf: `{"T":x}`,
  9314  		inVal: new(struct {
  9315  			T time.Time
  9316  		}),
  9317  		wantErr: newInvalidCharacterError("x", "at start of value", len64(`{"T":`), "/T"),
  9318  	}, {
  9319  		name:  jsontest.Name("Time/IgnoreInvalidFormat"),
  9320  		opts:  []Options{invalidFormatOption},
  9321  		inBuf: `"2000-01-01T00:00:00Z"`,
  9322  		inVal: addr(time.Time{}),
  9323  		want:  addr(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)),
  9324  	}}
  9325  
  9326  	for _, tt := range tests {
  9327  		if tt.skip {
  9328  			continue
  9329  		}
  9330  		t.Run(tt.name.Name, func(t *testing.T) {
  9331  			got := tt.inVal
  9332  			gotErr := Unmarshal([]byte(tt.inBuf), got, tt.opts...)
  9333  			if !reflect.DeepEqual(got, tt.want) && tt.want != nil {
  9334  				t.Errorf("%s: Unmarshal output mismatch:\ngot  %v\nwant %v", tt.name.Where, got, tt.want)
  9335  			}
  9336  			if !reflect.DeepEqual(gotErr, tt.wantErr) {
  9337  				t.Errorf("%s: Unmarshal error mismatch:\ngot  %v\nwant %v", tt.name.Where, gotErr, tt.wantErr)
  9338  			}
  9339  		})
  9340  	}
  9341  }
  9342  
  9343  func TestMarshalInvalidNamespace(t *testing.T) {
  9344  	tests := []struct {
  9345  		name jsontest.CaseName
  9346  		val  any
  9347  	}{
  9348  		{jsontest.Name("Map"), map[string]string{"X": "\xde\xad\xbe\xef"}},
  9349  		{jsontest.Name("Struct"), struct{ X string }{"\xde\xad\xbe\xef"}},
  9350  		{jsontest.Name("MapBadKey"), map[string]int{"\xde\xad\xbe\xef": 0}},
  9351  	}
  9352  	for _, tt := range tests {
  9353  		t.Run(tt.name.Name, func(t *testing.T) {
  9354  			enc := jsontext.NewEncoder(new(bytes.Buffer))
  9355  			if err := MarshalEncode(enc, tt.val); err == nil {
  9356  				t.Fatalf("%s: MarshalEncode error is nil, want non-nil", tt.name.Where)
  9357  			}
  9358  			for _, tok := range []jsontext.Token{
  9359  				jsontext.Null, jsontext.String(""), jsontext.Int(0), jsontext.BeginObject, jsontext.EndObject, jsontext.BeginArray, jsontext.EndArray,
  9360  			} {
  9361  				if err := enc.WriteToken(tok); err == nil {
  9362  					t.Fatalf("%s: WriteToken error is nil, want non-nil", tt.name.Where)
  9363  				}
  9364  			}
  9365  			for _, val := range []string{`null`, `""`, `0`, `{}`, `[]`} {
  9366  				if err := enc.WriteValue([]byte(val)); err == nil {
  9367  					t.Fatalf("%s: WriteToken error is nil, want non-nil", tt.name.Where)
  9368  				}
  9369  			}
  9370  		})
  9371  	}
  9372  }
  9373  
  9374  // TestMarshalEncodeInvalidNamespaceAtName verifies that MarshalEncode at an
  9375  // object-name position with an invalidated namespace surfaces the underlying
  9376  // namespace error rather than wrapping nil.
  9377  func TestMarshalEncodeInvalidNamespaceAtName(t *testing.T) {
  9378  	enc := jsontext.NewEncoder(new(bytes.Buffer))
  9379  
  9380  	// The bad-UTF-8 key fails the map marshal at the key-write step,
  9381  	// leaving the encoder at an object-name position with the namespace
  9382  	// invalidated.
  9383  	if err := MarshalEncode(enc, map[string]int{"\xde\xad\xbe\xef": 0}); err == nil {
  9384  		t.Fatal("MarshalEncode error is nil, want non-nil")
  9385  	}
  9386  
  9387  	var serr *jsontext.SyntacticError
  9388  	if err := MarshalEncode(enc, 0); !errors.As(err, &serr) || serr.Err == nil {
  9389  		t.Fatalf("MarshalEncode error = %v, want *jsontext.SyntacticError wrapping a non-nil error", err)
  9390  	}
  9391  }
  9392  
  9393  func TestUnmarshalInvalidNamespace(t *testing.T) {
  9394  	tests := []struct {
  9395  		name jsontest.CaseName
  9396  		val  any
  9397  	}{
  9398  		{jsontest.Name("Map"), addr(map[string]int{})},
  9399  		{jsontest.Name("Struct"), addr(struct{ X int }{})},
  9400  	}
  9401  	for _, tt := range tests {
  9402  		t.Run(tt.name.Name, func(t *testing.T) {
  9403  			dec := jsontext.NewDecoder(strings.NewReader(`{"X":""}`))
  9404  			if err := UnmarshalDecode(dec, tt.val); err == nil {
  9405  				t.Fatalf("%s: UnmarshalDecode error is nil, want non-nil", tt.name.Where)
  9406  			}
  9407  			if _, err := dec.ReadToken(); err == nil {
  9408  				t.Fatalf("%s: ReadToken error is nil, want non-nil", tt.name.Where)
  9409  			}
  9410  			if _, err := dec.ReadValue(); err == nil {
  9411  				t.Fatalf("%s: ReadValue error is nil, want non-nil", tt.name.Where)
  9412  			}
  9413  		})
  9414  	}
  9415  }
  9416  
  9417  func TestUnmarshalReuse(t *testing.T) {
  9418  	t.Run("Bytes", func(t *testing.T) {
  9419  		in := make([]byte, 3)
  9420  		want := &in[0]
  9421  		if err := Unmarshal([]byte(`"AQID"`), &in); err != nil {
  9422  			t.Fatalf("Unmarshal error: %v", err)
  9423  		}
  9424  		got := &in[0]
  9425  		if got != want {
  9426  			t.Errorf("input buffer was not reused")
  9427  		}
  9428  	})
  9429  	t.Run("Slices", func(t *testing.T) {
  9430  		in := make([]int, 3)
  9431  		want := &in[0]
  9432  		if err := Unmarshal([]byte(`[0,1,2]`), &in); err != nil {
  9433  			t.Fatalf("Unmarshal error: %v", err)
  9434  		}
  9435  		got := &in[0]
  9436  		if got != want {
  9437  			t.Errorf("input slice was not reused")
  9438  		}
  9439  	})
  9440  	t.Run("Maps", func(t *testing.T) {
  9441  		in := make(map[string]string)
  9442  		want := reflect.ValueOf(in).Pointer()
  9443  		if err := Unmarshal([]byte(`{"key":"value"}`), &in); err != nil {
  9444  			t.Fatalf("Unmarshal error: %v", err)
  9445  		}
  9446  		got := reflect.ValueOf(in).Pointer()
  9447  		if got != want {
  9448  			t.Errorf("input map was not reused")
  9449  		}
  9450  	})
  9451  	t.Run("Pointers", func(t *testing.T) {
  9452  		in := addr(addr(addr("hello")))
  9453  		want := **in
  9454  		if err := Unmarshal([]byte(`"goodbye"`), &in); err != nil {
  9455  			t.Fatalf("Unmarshal error: %v", err)
  9456  		}
  9457  		got := **in
  9458  		if got != want {
  9459  			t.Errorf("input pointer was not reused")
  9460  		}
  9461  	})
  9462  }
  9463  
  9464  type unmarshalerEOF struct{}
  9465  
  9466  func (unmarshalerEOF) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
  9467  	return io.EOF // should be wrapped and converted by Unmarshal to io.ErrUnexpectedEOF
  9468  }
  9469  
  9470  // TestUnmarshalEOF verifies that io.EOF is only ever returned by
  9471  // UnmarshalDecode for a top-level value.
  9472  func TestUnmarshalEOF(t *testing.T) {
  9473  	opts := WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, _ *struct{}) error {
  9474  		return io.EOF // should be wrapped and converted by Unmarshal to io.ErrUnexpectedEOF
  9475  	}))
  9476  
  9477  	for _, in := range []string{"", "[", "[null", "[null]"} {
  9478  		for _, newOut := range []func() any{
  9479  			func() any { return new(unmarshalerEOF) },
  9480  			func() any { return new([]unmarshalerEOF) },
  9481  			func() any { return new(struct{}) },
  9482  			func() any { return new([]struct{}) },
  9483  		} {
  9484  			wantErr := io.ErrUnexpectedEOF
  9485  			if gotErr := Unmarshal([]byte(in), newOut(), opts); !errors.Is(gotErr, wantErr) {
  9486  				t.Errorf("Unmarshal = %v, want %v", gotErr, wantErr)
  9487  			}
  9488  			if gotErr := UnmarshalRead(strings.NewReader(in), newOut(), opts); !errors.Is(gotErr, wantErr) {
  9489  				t.Errorf("Unmarshal = %v, want %v", gotErr, wantErr)
  9490  			}
  9491  			switch gotErr := UnmarshalDecode(jsontext.NewDecoder(strings.NewReader(in)), newOut(), opts); {
  9492  			case in != "" && !errors.Is(gotErr, wantErr):
  9493  				t.Errorf("Unmarshal = %v, want %v", gotErr, wantErr)
  9494  			case in == "" && gotErr != io.EOF:
  9495  				t.Errorf("Unmarshal = %v, want %v", gotErr, io.EOF)
  9496  			}
  9497  		}
  9498  	}
  9499  }
  9500  
  9501  type ReaderFunc func([]byte) (int, error)
  9502  
  9503  func (f ReaderFunc) Read(b []byte) (int, error) { return f(b) }
  9504  
  9505  type WriterFunc func([]byte) (int, error)
  9506  
  9507  func (f WriterFunc) Write(b []byte) (int, error) { return f(b) }
  9508  
  9509  func TestCoderBufferGrowth(t *testing.T) {
  9510  	// The growth rate of the internal buffer should be exponential,
  9511  	// but should not grow unbounded.
  9512  	checkGrowth := func(ns []int) {
  9513  		t.Helper()
  9514  		var sumBytes, sumRates, numGrows float64
  9515  		prev := ns[0]
  9516  		for i := 1; i < len(ns)-1; i++ {
  9517  			n := ns[i]
  9518  			if n != prev {
  9519  				sumRates += float64(n) / float64(prev)
  9520  				numGrows++
  9521  				prev = n
  9522  			}
  9523  			if n > 1<<20 {
  9524  				t.Fatalf("single Read/Write too large: %d", n)
  9525  			}
  9526  			sumBytes += float64(n)
  9527  		}
  9528  		if mean := sumBytes / float64(len(ns)); mean < 1<<10 {
  9529  			t.Fatalf("average Read/Write too small: %0.1f", mean)
  9530  		}
  9531  		switch mean := sumRates / numGrows; {
  9532  		case mean < 1.25:
  9533  			t.Fatalf("average growth rate too slow: %0.3f", mean)
  9534  		case mean > 2.00:
  9535  			t.Fatalf("average growth rate too fast: %0.3f", mean)
  9536  		}
  9537  	}
  9538  
  9539  	// bb is identical to bytes.Buffer,
  9540  	// but a different type to avoid any optimizations for bytes.Buffer.
  9541  	bb := struct{ *bytes.Buffer }{new(bytes.Buffer)}
  9542  
  9543  	var writeSizes []int
  9544  	if err := MarshalWrite(WriterFunc(func(b []byte) (int, error) {
  9545  		n, err := bb.Write(b)
  9546  		writeSizes = append(writeSizes, n)
  9547  		return n, err
  9548  	}), make([]struct{}, 1e6)); err != nil {
  9549  		t.Fatalf("MarshalWrite error: %v", err)
  9550  	}
  9551  	checkGrowth(writeSizes)
  9552  
  9553  	var readSizes []int
  9554  	if err := UnmarshalRead(ReaderFunc(func(b []byte) (int, error) {
  9555  		n, err := bb.Read(b)
  9556  		readSizes = append(readSizes, n)
  9557  		return n, err
  9558  	}), new([]struct{})); err != nil {
  9559  		t.Fatalf("UnmarshalRead error: %v", err)
  9560  	}
  9561  	checkGrowth(readSizes)
  9562  }
  9563  
  9564  func TestUintSet(t *testing.T) {
  9565  	type operation any // has | insert
  9566  	type has struct {
  9567  		in   uint
  9568  		want bool
  9569  	}
  9570  	type insert struct {
  9571  		in   uint
  9572  		want bool
  9573  	}
  9574  
  9575  	// Sequence of operations to perform (order matters).
  9576  	ops := []operation{
  9577  		has{0, false},
  9578  		has{63, false},
  9579  		has{64, false},
  9580  		has{1234, false},
  9581  		insert{3, true},
  9582  		has{2, false},
  9583  		has{3, true},
  9584  		has{4, false},
  9585  		has{63, false},
  9586  		insert{3, false},
  9587  		insert{63, true},
  9588  		has{63, true},
  9589  		insert{64, true},
  9590  		insert{64, false},
  9591  		has{64, true},
  9592  		insert{3264, true},
  9593  		has{3264, true},
  9594  		insert{3, false},
  9595  		has{3, true},
  9596  	}
  9597  
  9598  	var us uintSet
  9599  	for i, op := range ops {
  9600  		switch op := op.(type) {
  9601  		case has:
  9602  			if got := us.has(op.in); got != op.want {
  9603  				t.Fatalf("%d: uintSet.has(%v) = %v, want %v", i, op.in, got, op.want)
  9604  			}
  9605  		case insert:
  9606  			if got := us.insert(op.in); got != op.want {
  9607  				t.Fatalf("%d: uintSet.insert(%v) = %v, want %v", i, op.in, got, op.want)
  9608  			}
  9609  		default:
  9610  			panic(fmt.Sprintf("unknown operation: %T", op))
  9611  		}
  9612  	}
  9613  }
  9614  
  9615  func TestUnmarshalDecodeOptions(t *testing.T) {
  9616  	var calledFuncs int
  9617  	var calledOptions Options
  9618  	in := strings.NewReader(strings.Repeat("\"\xde\xad\xbe\xef\"\n", 5))
  9619  	dec := jsontext.NewDecoder(in,
  9620  		jsontext.AllowInvalidUTF8(true), // decoder-specific option
  9621  		WithUnmarshalers(UnmarshalFromFunc(func(dec *jsontext.Decoder, _ any) error {
  9622  			opts := dec.Options()
  9623  			if v, _ := GetOption(opts, jsontext.AllowInvalidUTF8); !v {
  9624  				t.Errorf("nested Options.AllowInvalidUTF8 = false, want true")
  9625  			}
  9626  			calledFuncs++
  9627  			calledOptions = opts
  9628  			return errors.ErrUnsupported
  9629  		})), // unmarshal-specific option; only relevant for UnmarshalDecode
  9630  	)
  9631  
  9632  	if err := UnmarshalDecode(dec, new(string)); err != nil {
  9633  		t.Fatalf("UnmarshalDecode: %v", err)
  9634  	}
  9635  	if calledFuncs != 1 {
  9636  		t.Fatalf("calledFuncs = %d, want 1", calledFuncs)
  9637  	}
  9638  	if err := UnmarshalDecode(dec, new(string), calledOptions); err != nil {
  9639  		t.Fatalf("UnmarshalDecode: %v", err)
  9640  	}
  9641  	if calledFuncs != 2 {
  9642  		t.Fatalf("calledFuncs = %d, want 2", calledFuncs)
  9643  	}
  9644  	if err := UnmarshalDecode(dec, new(string),
  9645  		jsontext.AllowInvalidUTF8(false), // expect to see invalid UTF-8 error
  9646  		WithUnmarshalers(nil),            // avoid calling previously registered unmarshalers
  9647  	); !errors.Is(err, jsonwire.ErrInvalidUTF8) {
  9648  		t.Fatalf("UnmarshalDecode = %v, want %v", err, jsonwire.ErrInvalidUTF8)
  9649  	}
  9650  	if err := UnmarshalDecode(dec, new(string),
  9651  		WithUnmarshalers(nil),
  9652  	); err != nil {
  9653  		t.Fatalf("UnmarshalDecode: %v", err)
  9654  	}
  9655  	if calledFuncs != 2 {
  9656  		t.Fatalf("calledFuncs = %d, want 2", calledFuncs)
  9657  	}
  9658  	if err := UnmarshalDecode(dec, new(string)); err != nil {
  9659  		t.Fatalf("UnmarshalDecode: %v", err)
  9660  	}
  9661  	if calledFuncs != 3 {
  9662  		t.Fatalf("calledFuncs = %d, want 3", calledFuncs)
  9663  	}
  9664  	if err := UnmarshalDecode(dec, new(string), JoinOptions(
  9665  		WithUnmarshalers(UnmarshalFromFunc(func(_ *jsontext.Decoder, _ any) error {
  9666  			opts := dec.Options()
  9667  			if v, _ := GetOption(opts, jsontext.AllowInvalidUTF8); !v {
  9668  				t.Errorf("nested Options.AllowInvalidUTF8 = false, want true")
  9669  			}
  9670  			calledFuncs = math.MaxInt
  9671  			return errors.ErrUnsupported
  9672  		})), // should override
  9673  	)); err != nil {
  9674  		t.Fatalf("UnmarshalDecode: %v", err)
  9675  	}
  9676  	if calledFuncs != math.MaxInt {
  9677  		t.Fatalf("calledFuncs = %d, want %d", calledFuncs, math.MaxInt)
  9678  	}
  9679  
  9680  	// Reset with the decoder options as part of the arguments should not
  9681  	// observe mutations to the options until after Reset is done.
  9682  	opts := dec.Options()                                 // AllowInvalidUTF8 is currently true
  9683  	dec.Reset(in, jsontext.AllowInvalidUTF8(false), opts) // earlier AllowInvalidUTF8(false) should be overridden by latter AllowInvalidUTF8(true) in opts
  9684  	if v, _ := GetOption(dec.Options(), jsontext.AllowInvalidUTF8); v == false {
  9685  		t.Errorf("Options.AllowInvalidUTF8 = false, want true")
  9686  	}
  9687  
  9688  	// Verify that AllowInvalidUTF8 and AllowDuplicateNames cannot be changed
  9689  	// when positioned at a JSON object name, but can be changed for the value.
  9690  	{
  9691  		dec2 := jsontext.NewDecoder(strings.NewReader(`{"name":{"dupe":"value","dupe":"value"}}`))
  9692  		if tok, err := dec2.ReadToken(); tok.Kind() != '{' || err != nil {
  9693  			t.Fatalf("ReadToken = (%v, %v), want ('{', nil)", tok.Kind(), err)
  9694  		}
  9695  		var name string
  9696  		if err := UnmarshalDecode(dec2, &name, jsontext.AllowDuplicateNames(true)); !errors.Is(err, errChangingDuplicateNames) {
  9697  			t.Errorf("UnmarshalDecode(name) = %v, want %v", err, errChangingDuplicateNames)
  9698  		}
  9699  		if err := UnmarshalDecode(dec2, &name, jsontext.AllowInvalidUTF8(true)); !errors.Is(err, errChangingInvalidUTF8) {
  9700  			t.Errorf("UnmarshalDecode(name) = %v, want %v", err, errChangingInvalidUTF8)
  9701  		}
  9702  		// Setting the same option value does not report an error.
  9703  		if err := UnmarshalDecode(dec2, &name, jsontext.AllowDuplicateNames(false)); err != nil {
  9704  			t.Errorf("UnmarshalDecode(name) = %v, want nil", err)
  9705  		} else if name != "name" {
  9706  			t.Errorf("UnmarshalDecode(name) = %q, want %q", name, "name")
  9707  		}
  9708  		// At value position, changing AllowDuplicateNames is allowed.
  9709  		var value jsontext.Value
  9710  		if err := UnmarshalDecode(dec2, &value, jsontext.AllowDuplicateNames(true)); err != nil {
  9711  			t.Errorf("UnmarshalDecode(value) = %v, want nil", err)
  9712  		}
  9713  		const want = `{"dupe":"value","dupe":"value"}`
  9714  		if string(value) != string(want) {
  9715  			t.Errorf("UnmarshalDecode(value) = %s, want %s", value, want)
  9716  		}
  9717  	}
  9718  }
  9719  
  9720  func TestUnmarshalDecodeStream(t *testing.T) {
  9721  	tests := []struct {
  9722  		in   string
  9723  		want []any
  9724  		err  error
  9725  	}{
  9726  		{in: ``, err: io.EOF},
  9727  		{in: `{`, err: &jsontext.SyntacticError{ByteOffset: len64(`{`), Err: io.ErrUnexpectedEOF}},
  9728  		{in: `{"`, err: &jsontext.SyntacticError{ByteOffset: len64(`{"`), Err: io.ErrUnexpectedEOF}},
  9729  		{in: `{"k"`, err: &jsontext.SyntacticError{ByteOffset: len64(`{"k"`), JSONPointer: "/k", Err: io.ErrUnexpectedEOF}},
  9730  		{in: `{"k":`, err: &jsontext.SyntacticError{ByteOffset: len64(`{"k":`), JSONPointer: "/k", Err: io.ErrUnexpectedEOF}},
  9731  		{in: `{"k",`, err: &jsontext.SyntacticError{ByteOffset: len64(`{"k"`), JSONPointer: "/k", Err: jsonwire.NewInvalidCharacterError(",", "after object name (expecting ':')")}},
  9732  		{in: `{"k"}`, err: &jsontext.SyntacticError{ByteOffset: len64(`{"k"`), JSONPointer: "/k", Err: jsonwire.NewInvalidCharacterError("}", "after object name (expecting ':')")}},
  9733  		{in: `[`, err: &jsontext.SyntacticError{ByteOffset: len64(`[`), Err: io.ErrUnexpectedEOF}},
  9734  		{in: `[0`, err: &jsontext.SyntacticError{ByteOffset: len64(`[0`), Err: io.ErrUnexpectedEOF}},
  9735  		{in: ` [0`, err: &jsontext.SyntacticError{ByteOffset: len64(` [0`), Err: io.ErrUnexpectedEOF}},
  9736  		{in: `[0.`, err: &jsontext.SyntacticError{ByteOffset: len64(`[`), JSONPointer: "/0", Err: io.ErrUnexpectedEOF}},
  9737  		{in: `[0. `, err: &jsontext.SyntacticError{ByteOffset: len64(`[0.`), JSONPointer: "/0", Err: jsonwire.NewInvalidCharacterError(" ", "in number (expecting digit)")}},
  9738  		{in: `[0,`, err: &jsontext.SyntacticError{ByteOffset: len64(`[0,`), Err: io.ErrUnexpectedEOF}},
  9739  		{in: `[0:`, err: &jsontext.SyntacticError{ByteOffset: len64(`[0`), Err: jsonwire.NewInvalidCharacterError(":", "after array element (expecting ',' or ']')")}},
  9740  		{in: `n`, err: &jsontext.SyntacticError{ByteOffset: len64(`n`), Err: io.ErrUnexpectedEOF}},
  9741  		{in: `nul`, err: &jsontext.SyntacticError{ByteOffset: len64(`nul`), Err: io.ErrUnexpectedEOF}},
  9742  		{in: `fal `, err: &jsontext.SyntacticError{ByteOffset: len64(`fal`), Err: jsonwire.NewInvalidCharacterError(" ", "in literal false (expecting 's')")}},
  9743  		{in: `false`, want: []any{false}, err: io.EOF},
  9744  		{in: `false0.0[]null`, want: []any{false, 0.0, []any{}, nil}, err: io.EOF},
  9745  	}
  9746  	for _, tt := range tests {
  9747  		d := jsontext.NewDecoder(strings.NewReader(tt.in))
  9748  		var got []any
  9749  		for {
  9750  			var v any
  9751  			if err := UnmarshalDecode(d, &v); err != nil {
  9752  				if !reflect.DeepEqual(err, tt.err) {
  9753  					t.Errorf("`%s`: UnmarshalDecode error = %v, want %v", tt.in, err, tt.err)
  9754  				}
  9755  				break
  9756  			}
  9757  			got = append(got, v)
  9758  		}
  9759  		if !reflect.DeepEqual(got, tt.want) {
  9760  			t.Errorf("`%s`: UnmarshalDecode = %v, want %v", tt.in, got, tt.want)
  9761  		}
  9762  	}
  9763  }
  9764  
  9765  // BenchmarkUnmarshalDecodeOptions is a minimal decode operation to measure
  9766  // the overhead options setup before the unmarshal operation.
  9767  func BenchmarkUnmarshalDecodeOptions(b *testing.B) {
  9768  	var i int
  9769  	in := new(bytes.Buffer)
  9770  	dec := jsontext.NewDecoder(in)
  9771  	makeBench := func(opts ...Options) func(*testing.B) {
  9772  		return func(b *testing.B) {
  9773  			for range b.N {
  9774  				in.WriteString("0 ")
  9775  			}
  9776  			dec.Reset(in)
  9777  			b.ResetTimer()
  9778  			for range b.N {
  9779  				UnmarshalDecode(dec, &i, opts...)
  9780  			}
  9781  		}
  9782  	}
  9783  	b.Run("None", makeBench())
  9784  	b.Run("Same", makeBench(&export.Decoder(dec).Struct))
  9785  	b.Run("New", makeBench(DefaultOptionsV2()))
  9786  }
  9787  
  9788  func TestMarshalEncodeOptions(t *testing.T) {
  9789  	var calledFuncs int
  9790  	var calledOptions Options
  9791  	out := new(bytes.Buffer)
  9792  	enc := jsontext.NewEncoder(
  9793  		out,
  9794  		jsontext.AllowInvalidUTF8(true), // encoder-specific option
  9795  		WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, _ any) error {
  9796  			opts := enc.Options()
  9797  			if v, _ := GetOption(opts, jsontext.AllowInvalidUTF8); !v {
  9798  				t.Errorf("nested Options.AllowInvalidUTF8 = false, want true")
  9799  			}
  9800  			calledFuncs++
  9801  			calledOptions = opts
  9802  			return errors.ErrUnsupported
  9803  		})), // marshal-specific option; only relevant for MarshalEncode
  9804  	)
  9805  
  9806  	if err := MarshalEncode(enc, "\xde\xad\xbe\xef"); err != nil {
  9807  		t.Fatalf("MarshalEncode: %v", err)
  9808  	}
  9809  	if calledFuncs != 1 {
  9810  		t.Fatalf("calledFuncs = %d, want 1", calledFuncs)
  9811  	}
  9812  	if err := MarshalEncode(enc, "\xde\xad\xbe\xef", calledOptions); err != nil {
  9813  		t.Fatalf("MarshalEncode: %v", err)
  9814  	}
  9815  	if calledFuncs != 2 {
  9816  		t.Fatalf("calledFuncs = %d, want 2", calledFuncs)
  9817  	}
  9818  	if err := MarshalEncode(enc, "\xde\xad\xbe\xef",
  9819  		jsontext.AllowInvalidUTF8(false), // expect to see invalid UTF-8 error
  9820  		WithMarshalers(nil),              // avoid calling previously registered marshalers
  9821  	); !errors.Is(err, jsonwire.ErrInvalidUTF8) {
  9822  		t.Fatalf("MarshalEncode = %v, want %v", err, jsonwire.ErrInvalidUTF8)
  9823  	}
  9824  	if err := MarshalEncode(enc, "\xde\xad\xbe\xef",
  9825  		WithMarshalers(nil), // should override
  9826  	); err != nil {
  9827  		t.Fatalf("MarshalEncode: %v", err)
  9828  	}
  9829  	if calledFuncs != 2 {
  9830  		t.Fatalf("calledFuncs = %d, want 2", calledFuncs)
  9831  	}
  9832  	if err := MarshalEncode(enc, "\xde\xad\xbe\xef"); err != nil {
  9833  		t.Fatalf("MarshalEncode: %v", err)
  9834  	}
  9835  	if calledFuncs != 3 {
  9836  		t.Fatalf("calledFuncs = %d, want 3", calledFuncs)
  9837  	}
  9838  	if err := MarshalEncode(enc, "\xde\xad\xbe\xef", JoinOptions(
  9839  		WithMarshalers(MarshalToFunc(func(enc *jsontext.Encoder, _ any) error {
  9840  			opts := enc.Options()
  9841  			if v, _ := GetOption(opts, jsontext.AllowInvalidUTF8); !v {
  9842  				t.Errorf("nested Options.AllowInvalidUTF8 = false, want true")
  9843  			}
  9844  			calledFuncs = math.MaxInt
  9845  			return errors.ErrUnsupported
  9846  		})), // should override
  9847  	)); err != nil {
  9848  		t.Fatalf("MarshalEncode: %v", err)
  9849  	}
  9850  	if calledFuncs != math.MaxInt {
  9851  		t.Fatalf("calledFuncs = %d, want %d", calledFuncs, math.MaxInt)
  9852  	}
  9853  	if out.String() != strings.Repeat("\"\xde\xad\ufffd\ufffd\"\n", 5) {
  9854  		t.Fatalf("output mismatch:\n\tgot:  %s\n\twant: %s", out.String(), strings.Repeat("\"\xde\xad\xbe\xef\"\n", 5))
  9855  	}
  9856  
  9857  	// Reset with the encoder options as part of the arguments should not
  9858  	// observe mutations to the options until after Reset is done.
  9859  	opts := enc.Options()                                  // AllowInvalidUTF8 is currently true
  9860  	enc.Reset(out, jsontext.AllowInvalidUTF8(false), opts) // earlier AllowInvalidUTF8(false) should be overridden by latter AllowInvalidUTF8(true) in opts
  9861  	if v, _ := GetOption(enc.Options(), jsontext.AllowInvalidUTF8); v == false {
  9862  		t.Errorf("Options.AllowInvalidUTF8 = false, want true")
  9863  	}
  9864  
  9865  	// Verify that AllowInvalidUTF8 and AllowDuplicateNames cannot be changed
  9866  	// when positioned at a JSON object name, but can be changed for the value.
  9867  	{
  9868  		var buf2 bytes.Buffer
  9869  		enc2 := jsontext.NewEncoder(&buf2)
  9870  		if err := enc2.WriteToken(jsontext.BeginObject); err != nil {
  9871  			t.Fatalf("WriteToken(BeginObject) = %v, want nil", err)
  9872  		}
  9873  
  9874  		// Verify that you cannot change AllowDuplicateNames or AllowInvalidUTF8 settings for the JSON member name.
  9875  		if err := MarshalEncode(enc2, "name", jsontext.AllowDuplicateNames(true)); !errors.Is(err, errChangingDuplicateNames) {
  9876  			t.Errorf("MarshalEncode(name) = %v, want %v", err, errChangingDuplicateNames)
  9877  		}
  9878  		if err := MarshalEncode(enc2, "name", jsontext.AllowInvalidUTF8(true)); !errors.Is(err, errChangingInvalidUTF8) {
  9879  			t.Errorf("MarshalEncode(name) = %v, want %v", err, errChangingInvalidUTF8)
  9880  		}
  9881  		// Setting the same option value does not report an error.
  9882  		if err := MarshalEncode(enc2, "name", jsontext.AllowDuplicateNames(false)); err != nil {
  9883  			t.Errorf("MarshalEncode(name) = %v, want nil", err)
  9884  		}
  9885  		// At value position, changing AllowDuplicateNames is allowed.
  9886  		if err := MarshalEncode(enc2, jsontext.Value(`{"dupe":"value","dupe":"value"}`), jsontext.AllowDuplicateNames(true)); err != nil {
  9887  			t.Errorf("MarshalEncode(value) = %v, want nil", err)
  9888  		}
  9889  
  9890  		// Verify that you can change AllowInvalidUTF8 for the JSON member value.
  9891  		if err := MarshalEncode(enc2, "name2"); err != nil {
  9892  			t.Errorf("MarshalEncode(name) = %v, want nil", err)
  9893  		}
  9894  		if err := MarshalEncode(enc2, "value\xde\xad\xbe\xef"); !errors.Is(err, jsonwire.ErrInvalidUTF8) {
  9895  			t.Errorf("MarshalEncode(value) = %v, want %v", err, jsonwire.ErrInvalidUTF8)
  9896  		}
  9897  		if err := MarshalEncode(enc2, "value\xde\xad\xbe\xef", jsontext.AllowInvalidUTF8(true)); err != nil {
  9898  			t.Errorf("MarshalEncode(value) = %v, want nil", err)
  9899  		}
  9900  
  9901  		if err := enc2.WriteToken(jsontext.EndObject); err != nil {
  9902  			t.Errorf("WriteToken(EndObject) = %v, want nil", err)
  9903  		}
  9904  	}
  9905  
  9906  	// Verify that whitespace options cannot change within a MarshalEncode call,
  9907  	// but setting them to identical values is allowed.
  9908  	{
  9909  		var buf3 bytes.Buffer
  9910  		enc3 := jsontext.NewEncoder(&buf3, jsontext.WithIndent("\t"))
  9911  		if err := MarshalEncode(enc3, "value", jsontext.Multiline(false)); !errors.Is(err, errChangingWhitespace) {
  9912  			t.Errorf("MarshalEncode = %v, want %v", err, errChangingWhitespace)
  9913  		}
  9914  		if err := MarshalEncode(enc3, "value", jsontext.WithIndent("  ")); !errors.Is(err, errChangingWhitespace) {
  9915  			t.Errorf("MarshalEncode = %v, want %v", err, errChangingWhitespace)
  9916  		}
  9917  		// Setting identical whitespace options does not report an error.
  9918  		if err := MarshalEncode(enc3, "value", enc3.Options()); err != nil {
  9919  			t.Errorf("MarshalEncode = %v, want nil", err)
  9920  		}
  9921  	}
  9922  }
  9923  
  9924  // BenchmarkMarshalEncodeOptions is a minimal encode operation to measure
  9925  // the overhead of options setup before the marshal operation.
  9926  func BenchmarkMarshalEncodeOptions(b *testing.B) {
  9927  	var i int
  9928  	out := new(bytes.Buffer)
  9929  	enc := jsontext.NewEncoder(out)
  9930  	makeBench := func(opts ...Options) func(*testing.B) {
  9931  		return func(b *testing.B) {
  9932  			out.Reset()
  9933  			enc.Reset(out)
  9934  			b.ResetTimer()
  9935  			for range b.N {
  9936  				MarshalEncode(enc, &i, opts...)
  9937  			}
  9938  		}
  9939  	}
  9940  	b.Run("None", makeBench())
  9941  	b.Run("Same", makeBench(&export.Encoder(enc).Struct))
  9942  	b.Run("New", makeBench(DefaultOptionsV2()))
  9943  }
  9944  

View as plain text