Source file src/encoding/json/v2/arshal.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  	"io"
    13  	"reflect"
    14  	"sync"
    15  	"time"
    16  
    17  	"encoding/json/internal"
    18  	"encoding/json/internal/jsonflags"
    19  	"encoding/json/internal/jsonopts"
    20  	"encoding/json/jsontext"
    21  )
    22  
    23  // Reference encoding and time packages to assist pkgsite
    24  // in being able to hotlink references to those packages.
    25  var (
    26  	_ encoding.TextMarshaler
    27  	_ encoding.TextAppender
    28  	_ encoding.TextUnmarshaler
    29  	_ time.Time
    30  	_ time.Duration
    31  )
    32  
    33  // export exposes internal functionality of the "jsontext" package.
    34  var export = jsontext.Internal.Export(&internal.AllowInternalUse)
    35  
    36  // Marshal serializes a Go value as a []byte according to the provided
    37  // marshal and encode options (while ignoring unmarshal or decode options).
    38  // It does not terminate the output with a newline.
    39  //
    40  // Type-specific marshal functions and methods take precedence
    41  // over the default representation of a value.
    42  // Functions or methods that operate on *T are only called when encoding
    43  // a value of type T (by taking its address) or a non-nil value of *T.
    44  // Marshal ensures that a value is always addressable
    45  // (by boxing it on the heap if necessary) so that
    46  // these functions and methods can be consistently called. For performance,
    47  // it is recommended that Marshal be passed a non-nil pointer to the value.
    48  //
    49  // The input value is encoded as JSON according the following rules:
    50  //
    51  //   - If any type-specific functions in a [WithMarshalers] option match
    52  //     the value type, then those functions are called to encode the value.
    53  //     If all applicable functions return [errors.ErrUnsupported],
    54  //     then the value is encoded according to subsequent rules.
    55  //
    56  //   - If the value type implements [MarshalerTo],
    57  //     then the MarshalJSONTo method is called to encode the value.
    58  //     If the method returns [errors.ErrUnsupported],
    59  //     then the input is encoded according to subsequent rules.
    60  //
    61  //   - If the value type implements [Marshaler],
    62  //     then the MarshalJSON method is called to encode the value.
    63  //
    64  //   - If the value type implements [encoding.TextAppender],
    65  //     then the AppendText method is called to encode the value and
    66  //     subsequently encode its result as a JSON string.
    67  //
    68  //   - If the value type implements [encoding.TextMarshaler],
    69  //     then the MarshalText method is called to encode the value and
    70  //     subsequently encode its result as a JSON string.
    71  //
    72  //   - Otherwise, the value is encoded according to the value's type
    73  //     as described in detail below.
    74  //
    75  // Most Go types have a default JSON representation.
    76  // Certain types support specialized formatting according to
    77  // a format flag optionally specified in the Go struct tag
    78  // for the struct field that contains the current value
    79  // (see the “JSON Representation of Go structs” section for more details).
    80  //
    81  // The representation of each type is as follows:
    82  //
    83  //   - A Go boolean is encoded as a JSON boolean (e.g., true or false).
    84  //     It does not support any custom format flags.
    85  //
    86  //   - A Go string is encoded as a JSON string.
    87  //     It does not support any custom format flags.
    88  //
    89  //   - A Go []byte or [N]byte is encoded as a JSON string containing
    90  //     the binary value encoded using RFC 4648.
    91  //     If the format is "base64" or unspecified, then this uses RFC 4648, section 4.
    92  //     If the format is "base64url", then this uses RFC 4648, section 5.
    93  //     If the format is "base32", then this uses RFC 4648, section 6.
    94  //     If the format is "base32hex", then this uses RFC 4648, section 7.
    95  //     If the format is "base16" or "hex", then this uses RFC 4648, section 8.
    96  //     If the format is "array", then the bytes value is encoded as a JSON array
    97  //     where each byte is recursively JSON-encoded as each JSON array element.
    98  //
    99  //   - A Go integer is encoded as a JSON number without fractions or exponents.
   100  //     If [StringifyNumbers] is specified or encoding a JSON object name,
   101  //     then the JSON number is encoded within a JSON string.
   102  //     It does not support any custom format flags.
   103  //
   104  //   - A Go float is encoded as a JSON number.
   105  //     If [StringifyNumbers] is specified or encoding a JSON object name,
   106  //     then the JSON number is encoded within a JSON string.
   107  //     If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as
   108  //     the JSON strings "NaN", "Infinity", and "-Infinity", respectively.
   109  //     Otherwise, the presence of non-finite numbers results in a [SemanticError].
   110  //
   111  //   - A Go map is encoded as a JSON object, where each Go map key and value
   112  //     is recursively encoded as a name and value pair in the JSON object.
   113  //     The Go map key must encode as a JSON string, otherwise this results
   114  //     in a [SemanticError]. The Go map is traversed in a non-deterministic order.
   115  //     For deterministic encoding, consider using the [Deterministic] option.
   116  //     If the format is "emitnull", then a nil map is encoded as a JSON null.
   117  //     If the format is "emitempty", then a nil map is encoded as an empty JSON object,
   118  //     regardless of whether [FormatNilMapAsNull] is specified.
   119  //     Otherwise by default, a nil map is encoded as an empty JSON object.
   120  //
   121  //   - A Go struct is encoded as a JSON object.
   122  //     See the “JSON Representation of Go structs” section
   123  //     in the package-level documentation for more details.
   124  //
   125  //   - A Go slice is encoded as a JSON array, where each Go slice element
   126  //     is recursively JSON-encoded as the elements of the JSON array.
   127  //     If the format is "emitnull", then a nil slice is encoded as a JSON null.
   128  //     If the format is "emitempty", then a nil slice is encoded as an empty JSON array,
   129  //     regardless of whether [FormatNilSliceAsNull] is specified.
   130  //     Otherwise by default, a nil slice is encoded as an empty JSON array.
   131  //
   132  //   - A Go array is encoded as a JSON array, where each Go array element
   133  //     is recursively JSON-encoded as the elements of the JSON array.
   134  //     The JSON array length is always identical to the Go array length.
   135  //     It does not support any custom format flags.
   136  //
   137  //   - A Go pointer is encoded as a JSON null if nil, otherwise it is
   138  //     the recursively JSON-encoded representation of the underlying value.
   139  //     Format flags are forwarded to the encoding of the underlying value.
   140  //
   141  //   - A Go interface is encoded as a JSON null if nil, otherwise it is
   142  //     the recursively JSON-encoded representation of the underlying value.
   143  //     It does not support any custom format flags.
   144  //
   145  //   - A Go [time.Time] is encoded as a JSON string containing the timestamp
   146  //     formatted in RFC 3339 with nanosecond precision.
   147  //     If the format matches one of the format constants declared
   148  //     in the time package (e.g., RFC1123), then that format is used.
   149  //     If the format is "unix", "unixmilli", "unixmicro", or "unixnano",
   150  //     then the timestamp is encoded as a possibly fractional JSON number
   151  //     of the number of seconds (or milliseconds, microseconds, or nanoseconds)
   152  //     since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.
   153  //     To avoid a fractional component, round the timestamp to the relevant unit.
   154  //     Otherwise, the format is used as-is with [time.Time.Format] if non-empty.
   155  //
   156  //   - A Go [time.Duration] currently has no default representation and
   157  //     requires an explicit format to be specified.
   158  //     If the format is "sec", "milli", "micro", or "nano",
   159  //     then the duration is encoded as a possibly fractional JSON number
   160  //     of the number of seconds (or milliseconds, microseconds, or nanoseconds).
   161  //     To avoid a fractional component, round the duration to the relevant unit.
   162  //     If the format is "units", it is encoded as a JSON string formatted using
   163  //     [time.Duration.String] (e.g., "1h30m" for 1 hour 30 minutes).
   164  //     If the format is "iso8601", it is encoded as a JSON string using the
   165  //     ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)
   166  //     using only accurate units of hours, minutes, and seconds.
   167  //
   168  //   - All other Go types (e.g., complex numbers, channels, and functions)
   169  //     have no default representation and result in a [SemanticError].
   170  //
   171  // JSON cannot represent cyclic data structures and Marshal does not handle them.
   172  // Passing cyclic structures will result in an error.
   173  func Marshal(in any, opts ...Options) (out []byte, err error) {
   174  	enc := export.GetBufferedEncoder(opts...)
   175  	defer export.PutBufferedEncoder(enc)
   176  	xe := export.Encoder(enc)
   177  	xe.Flags.Set(jsonflags.OmitTopLevelNewline | 1)
   178  	err = marshalEncode(enc, in, &xe.Struct)
   179  	if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   180  		return nil, internal.TransformMarshalError(in, err)
   181  	}
   182  	return bytes.Clone(xe.Buf), err
   183  }
   184  
   185  // MarshalWrite serializes a Go value into an [io.Writer] according to the provided
   186  // marshal and encode options (while ignoring unmarshal or decode options).
   187  // It does not terminate the output with a newline.
   188  // See [Marshal] for details about the conversion of a Go value into JSON.
   189  func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) {
   190  	enc := export.GetStreamingEncoder(out, opts...)
   191  	defer export.PutStreamingEncoder(enc)
   192  	xe := export.Encoder(enc)
   193  	xe.Flags.Set(jsonflags.OmitTopLevelNewline | 1)
   194  	err = marshalEncode(enc, in, &xe.Struct)
   195  	if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   196  		return internal.TransformMarshalError(in, err)
   197  	}
   198  	return err
   199  }
   200  
   201  // MarshalEncode serializes a Go value into an [jsontext.Encoder] according to
   202  // the provided marshal options (while ignoring unmarshal, encode, or decode options).
   203  // Any marshal-relevant options already specified on the [jsontext.Encoder]
   204  // take lower precedence than the set of options provided by the caller.
   205  // Unlike [Marshal] and [MarshalWrite], encode options are ignored because
   206  // they must have already been specified on the provided [jsontext.Encoder].
   207  //
   208  // See [Marshal] for details about the conversion of a Go value into JSON.
   209  func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) {
   210  	xe := export.Encoder(out)
   211  	if len(opts) > 0 {
   212  		optsOriginal := xe.Struct
   213  		defer func() { xe.Struct = optsOriginal }()
   214  		xe.Struct.JoinWithoutCoderOptions(opts...)
   215  	}
   216  	err = marshalEncode(out, in, &xe.Struct)
   217  	if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   218  		return internal.TransformMarshalError(in, err)
   219  	}
   220  	return err
   221  }
   222  
   223  func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err error) {
   224  	v := reflect.ValueOf(in)
   225  	if !v.IsValid() || (v.Kind() == reflect.Pointer && v.IsNil()) {
   226  		return out.WriteToken(jsontext.Null)
   227  	}
   228  	// Shallow copy non-pointer values to obtain an addressable value.
   229  	// It is beneficial to performance to always pass pointers to avoid this.
   230  	forceAddr := v.Kind() != reflect.Pointer
   231  	if forceAddr {
   232  		v2 := reflect.New(v.Type())
   233  		v2.Elem().Set(v)
   234  		v = v2
   235  	}
   236  	va := addressableValue{v.Elem(), forceAddr} // dereferenced pointer is always addressable
   237  	t := va.Type()
   238  
   239  	// Lookup and call the marshal function for this type.
   240  	marshal := lookupArshaler(t).marshal
   241  	if mo.Marshalers != nil {
   242  		marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t)
   243  	}
   244  	if err := marshal(out, va, mo); err != nil {
   245  		if !mo.Flags.Get(jsonflags.AllowDuplicateNames) {
   246  			export.Encoder(out).Tokens.InvalidateDisabledNamespaces()
   247  		}
   248  		return err
   249  	}
   250  	return nil
   251  }
   252  
   253  // Unmarshal decodes a []byte input into a Go value according to the provided
   254  // unmarshal and decode options (while ignoring marshal or encode options).
   255  // The input must be a single JSON value with optional whitespace interspersed.
   256  // The output must be a non-nil pointer.
   257  //
   258  // Type-specific unmarshal functions and methods take precedence
   259  // over the default representation of a value.
   260  // Functions or methods that operate on *T are only called when decoding
   261  // a value of type T (by taking its address) or a non-nil value of *T.
   262  // Unmarshal ensures that a value is always addressable
   263  // (by boxing it on the heap if necessary) so that
   264  // these functions and methods can be consistently called.
   265  //
   266  // The input is decoded into the output according the following rules:
   267  //
   268  //   - If any type-specific functions in a [WithUnmarshalers] option match
   269  //     the value type, then those functions are called to decode the JSON
   270  //     value. If all applicable functions return [errors.ErrUnsupported],
   271  //     then the input is decoded according to subsequent rules.
   272  //
   273  //   - If the value type implements [UnmarshalerFrom],
   274  //     then the UnmarshalJSONFrom method is called to decode the JSON value.
   275  //     If the method returns [errors.ErrUnsupported],
   276  //     then the input is decoded according to subsequent rules.
   277  //
   278  //   - If the value type implements [Unmarshaler],
   279  //     then the UnmarshalJSON method is called to decode the JSON value.
   280  //
   281  //   - If the value type implements [encoding.TextUnmarshaler],
   282  //     then the input is decoded as a JSON string and
   283  //     the UnmarshalText method is called with the decoded string value.
   284  //     This fails with a [SemanticError] if the input is not a JSON string.
   285  //
   286  //   - Otherwise, the JSON value is decoded according to the value's type
   287  //     as described in detail below.
   288  //
   289  // Most Go types have a default JSON representation.
   290  // Certain types support specialized formatting according to
   291  // a format flag optionally specified in the Go struct tag
   292  // for the struct field that contains the current value
   293  // (see the “JSON Representation of Go structs” section for more details).
   294  // A JSON null may be decoded into every supported Go value where
   295  // it is equivalent to storing the zero value of the Go value.
   296  // If the input JSON kind is not handled by the current Go value type,
   297  // then this fails with a [SemanticError]. Unless otherwise specified,
   298  // the decoded value replaces any pre-existing value.
   299  //
   300  // The representation of each type is as follows:
   301  //
   302  //   - A Go boolean is decoded from a JSON boolean (e.g., true or false).
   303  //     It does not support any custom format flags.
   304  //
   305  //   - A Go string is decoded from a JSON string.
   306  //     It does not support any custom format flags.
   307  //
   308  //   - A Go []byte or [N]byte is decoded from a JSON string
   309  //     containing the binary value encoded using RFC 4648.
   310  //     If the format is "base64" or unspecified, then this uses RFC 4648, section 4.
   311  //     If the format is "base64url", then this uses RFC 4648, section 5.
   312  //     If the format is "base32", then this uses RFC 4648, section 6.
   313  //     If the format is "base32hex", then this uses RFC 4648, section 7.
   314  //     If the format is "base16" or "hex", then this uses RFC 4648, section 8.
   315  //     If the format is "array", then the Go slice or array is decoded from a
   316  //     JSON array where each JSON element is recursively decoded for each byte.
   317  //     When decoding into a non-nil []byte, the slice length is reset to zero
   318  //     and the decoded input is appended to it.
   319  //     When decoding into a [N]byte, the input must decode to exactly N bytes,
   320  //     otherwise it fails with a [SemanticError].
   321  //
   322  //   - A Go integer is decoded from a JSON number.
   323  //     It must be decoded from a JSON string containing a JSON number
   324  //     if [StringifyNumbers] is specified or decoding a JSON object name.
   325  //     It fails with a [SemanticError] if the JSON number
   326  //     has a fractional or exponent component.
   327  //     It also fails if it overflows the representation of the Go integer type.
   328  //     It does not support any custom format flags.
   329  //
   330  //   - A Go float is decoded from a JSON number.
   331  //     It must be decoded from a JSON string containing a JSON number
   332  //     if [StringifyNumbers] is specified or decoding a JSON object name.
   333  //     It fails if it overflows the representation of the Go float type.
   334  //     If the format is "nonfinite", then the JSON strings
   335  //     "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf.
   336  //     Otherwise, the presence of such strings results in a [SemanticError].
   337  //
   338  //   - A Go map is decoded from a JSON object,
   339  //     where each JSON object name and value pair is recursively decoded
   340  //     as the Go map key and value. Maps are not cleared.
   341  //     If the Go map is nil, then a new map is allocated to decode into.
   342  //     If the decoded key matches an existing Go map entry, the entry value
   343  //     is reused by decoding the JSON object value into it.
   344  //     The formats "emitnull" and "emitempty" have no effect when decoding.
   345  //
   346  //   - A Go struct is decoded from a JSON object.
   347  //     See the “JSON Representation of Go structs” section
   348  //     in the package-level documentation for more details.
   349  //
   350  //   - A Go slice is decoded from a JSON array, where each JSON element
   351  //     is recursively decoded and appended to the Go slice.
   352  //     Before appending into a Go slice, a new slice is allocated if it is nil,
   353  //     otherwise the slice length is reset to zero.
   354  //     The formats "emitnull" and "emitempty" have no effect when decoding.
   355  //
   356  //   - A Go array is decoded from a JSON array, where each JSON array element
   357  //     is recursively decoded as each corresponding Go array element.
   358  //     Each Go array element is zeroed before decoding into it.
   359  //     It fails with a [SemanticError] if the JSON array does not contain
   360  //     the exact same number of elements as the Go array.
   361  //     It does not support any custom format flags.
   362  //
   363  //   - A Go pointer is decoded based on the JSON kind and underlying Go type.
   364  //     If the input is a JSON null, then this stores a nil pointer.
   365  //     Otherwise, it allocates a new underlying value if the pointer is nil,
   366  //     and recursively JSON decodes into the underlying value.
   367  //     Format flags are forwarded to the decoding of the underlying type.
   368  //
   369  //   - A Go interface is decoded based on the JSON kind and underlying Go type.
   370  //     If the input is a JSON null, then this stores a nil interface value.
   371  //     Otherwise, a nil interface value of an empty interface type is initialized
   372  //     with a zero Go bool, string, float64, map[string]any, or []any if the
   373  //     input is a JSON boolean, string, number, object, or array, respectively.
   374  //     If the interface value is still nil, then this fails with a [SemanticError]
   375  //     since decoding could not determine an appropriate Go type to decode into.
   376  //     For example, unmarshaling into a nil io.Reader fails since
   377  //     there is no concrete type to populate the interface value with.
   378  //     Otherwise an underlying value exists and it recursively decodes
   379  //     the JSON input into it. It does not support any custom format flags.
   380  //
   381  //   - A Go [time.Time] is decoded from a JSON string containing the time
   382  //     formatted in RFC 3339 with nanosecond precision.
   383  //     If the format matches one of the format constants declared in
   384  //     the time package (e.g., RFC1123), then that format is used for parsing.
   385  //     If the format is "unix", "unixmilli", "unixmicro", or "unixnano",
   386  //     then the timestamp is decoded from an optionally fractional JSON number
   387  //     of the number of seconds (or milliseconds, microseconds, or nanoseconds)
   388  //     since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.
   389  //     Otherwise, the format is used as-is with [time.Time.Parse] if non-empty.
   390  //
   391  //   - A Go [time.Duration] currently has no default representation and
   392  //     requires an explicit format to be specified.
   393  //     If the format is "sec", "milli", "micro", or "nano",
   394  //     then the duration is decoded from an optionally fractional JSON number
   395  //     of the number of seconds (or milliseconds, microseconds, or nanoseconds).
   396  //     If the format is "units", it is decoded from a JSON string parsed using
   397  //     [time.ParseDuration] (e.g., "1h30m" for 1 hour 30 minutes).
   398  //     If the format is "iso8601", it is decoded from a JSON string using the
   399  //     ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)
   400  //     accepting only accurate units of hours, minutes, or seconds.
   401  //
   402  //   - All other Go types (e.g., complex numbers, channels, and functions)
   403  //     have no default representation and result in a [SemanticError].
   404  //
   405  // In general, unmarshaling follows merge semantics (similar to RFC 7396)
   406  // where the decoded Go value replaces the destination value
   407  // for any JSON kind other than an object.
   408  // For JSON objects, the input object is merged into the destination value
   409  // where matching object members recursively apply merge semantics.
   410  func Unmarshal(in []byte, out any, opts ...Options) (err error) {
   411  	dec := export.GetBufferedDecoder(in, opts...)
   412  	defer export.PutBufferedDecoder(dec)
   413  	xd := export.Decoder(dec)
   414  	err = unmarshalDecode(dec, out, &xd.Struct, true)
   415  	if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   416  		return internal.TransformUnmarshalError(out, err)
   417  	}
   418  	return err
   419  }
   420  
   421  // UnmarshalRead deserializes a Go value from an [io.Reader] according to the
   422  // provided unmarshal and decode options (while ignoring marshal or encode options).
   423  // The input must be a single JSON value with optional whitespace interspersed.
   424  // It consumes the entirety of [io.Reader] until [io.EOF] is encountered,
   425  // without reporting an error for EOF. The output must be a non-nil pointer.
   426  // See [Unmarshal] for details about the conversion of JSON into a Go value.
   427  func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) {
   428  	dec := export.GetStreamingDecoder(in, opts...)
   429  	defer export.PutStreamingDecoder(dec)
   430  	xd := export.Decoder(dec)
   431  	err = unmarshalDecode(dec, out, &xd.Struct, true)
   432  	if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   433  		return internal.TransformUnmarshalError(out, err)
   434  	}
   435  	return err
   436  }
   437  
   438  // UnmarshalDecode deserializes a Go value from a [jsontext.Decoder] according to
   439  // the provided unmarshal options (while ignoring marshal, encode, or decode options).
   440  // Any unmarshal options already specified on the [jsontext.Decoder]
   441  // take lower precedence than the set of options provided by the caller.
   442  // Unlike [Unmarshal] and [UnmarshalRead], decode options are ignored because
   443  // they must have already been specified on the provided [jsontext.Decoder].
   444  //
   445  // The input may be a stream of zero or more JSON values,
   446  // where this only unmarshals the next JSON value in the stream.
   447  // If there are no more top-level JSON values, it reports [io.EOF].
   448  // The output must be a non-nil pointer.
   449  // See [Unmarshal] for details about the conversion of JSON into a Go value.
   450  func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error) {
   451  	xd := export.Decoder(in)
   452  	if len(opts) > 0 {
   453  		optsOriginal := xd.Struct
   454  		defer func() { xd.Struct = optsOriginal }()
   455  		xd.Struct.JoinWithoutCoderOptions(opts...)
   456  	}
   457  	err = unmarshalDecode(in, out, &xd.Struct, false)
   458  	if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   459  		return internal.TransformUnmarshalError(out, err)
   460  	}
   461  	return err
   462  }
   463  
   464  func unmarshalDecode(in *jsontext.Decoder, out any, uo *jsonopts.Struct, last bool) (err error) {
   465  	v := reflect.ValueOf(out)
   466  	if v.Kind() != reflect.Pointer || v.IsNil() {
   467  		return &SemanticError{action: "unmarshal", GoType: reflect.TypeOf(out), Err: internal.ErrNonNilReference}
   468  	}
   469  	va := addressableValue{v.Elem(), false} // dereferenced pointer is always addressable
   470  	t := va.Type()
   471  
   472  	// In legacy semantics, the entirety of the next JSON value
   473  	// was validated before attempting to unmarshal it.
   474  	if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   475  		if err := export.Decoder(in).CheckNextValue(last); err != nil {
   476  			if err == io.EOF && last {
   477  				offset := in.InputOffset() + int64(len(in.UnreadBuffer()))
   478  				return &jsontext.SyntacticError{ByteOffset: offset, Err: io.ErrUnexpectedEOF}
   479  			}
   480  			return err
   481  		}
   482  	}
   483  
   484  	// Lookup and call the unmarshal function for this type.
   485  	unmarshal := lookupArshaler(t).unmarshal
   486  	if uo.Unmarshalers != nil {
   487  		unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t)
   488  	}
   489  	if err := unmarshal(in, va, uo); err != nil {
   490  		if !uo.Flags.Get(jsonflags.AllowDuplicateNames) {
   491  			export.Decoder(in).Tokens.InvalidateDisabledNamespaces()
   492  		}
   493  		if err == io.EOF && last {
   494  			offset := in.InputOffset() + int64(len(in.UnreadBuffer()))
   495  			return &jsontext.SyntacticError{ByteOffset: offset, Err: io.ErrUnexpectedEOF}
   496  		}
   497  		return err
   498  	}
   499  	if last {
   500  		return export.Decoder(in).CheckEOF()
   501  	}
   502  	return nil
   503  }
   504  
   505  // addressableValue is a reflect.Value that is guaranteed to be addressable
   506  // such that calling the Addr and Set methods do not panic.
   507  //
   508  // There is no compile magic that enforces this property,
   509  // but rather the need to construct this type makes it easier to examine each
   510  // construction site to ensure that this property is upheld.
   511  type addressableValue struct {
   512  	reflect.Value
   513  
   514  	// forcedAddr reports whether this value is addressable
   515  	// only through the use of [newAddressableValue].
   516  	// This is only used for [jsonflags.CallMethodsWithLegacySemantics].
   517  	forcedAddr bool
   518  }
   519  
   520  // newAddressableValue constructs a new addressable value of type t.
   521  func newAddressableValue(t reflect.Type) addressableValue {
   522  	return addressableValue{reflect.New(t).Elem(), true}
   523  }
   524  
   525  // TODO: Remove *jsonopts.Struct argument from [marshaler] and [unmarshaler].
   526  // This can be directly accessed on the encoder or decoder.
   527  
   528  // All marshal and unmarshal behavior is implemented using these signatures.
   529  // The *jsonopts.Struct argument is guaranteed to identical to or at least
   530  // a strict super-set of the options in Encoder.Struct or Decoder.Struct.
   531  // It is identical for Marshal, Unmarshal, MarshalWrite, and UnmarshalRead.
   532  // It is a super-set for MarshalEncode and UnmarshalDecode.
   533  type (
   534  	marshaler   = func(*jsontext.Encoder, addressableValue, *jsonopts.Struct) error
   535  	unmarshaler = func(*jsontext.Decoder, addressableValue, *jsonopts.Struct) error
   536  )
   537  
   538  type arshaler struct {
   539  	marshal    marshaler
   540  	unmarshal  unmarshaler
   541  	nonDefault bool
   542  }
   543  
   544  var lookupArshalerCache sync.Map // map[reflect.Type]*arshaler
   545  
   546  func lookupArshaler(t reflect.Type) *arshaler {
   547  	if v, ok := lookupArshalerCache.Load(t); ok {
   548  		return v.(*arshaler)
   549  	}
   550  
   551  	fncs := makeDefaultArshaler(t)
   552  	fncs = makeMethodArshaler(fncs, t)
   553  	fncs = makeTimeArshaler(fncs, t)
   554  
   555  	// Use the last stored so that duplicate arshalers can be garbage collected.
   556  	v, _ := lookupArshalerCache.LoadOrStore(t, fncs)
   557  	return v.(*arshaler)
   558  }
   559  
   560  var stringsPools = &sync.Pool{New: func() any { return new(stringSlice) }}
   561  
   562  type stringSlice []string
   563  
   564  // getStrings returns a non-nil pointer to a slice with length n.
   565  func getStrings(n int) *stringSlice {
   566  	s := stringsPools.Get().(*stringSlice)
   567  	if cap(*s) < n {
   568  		*s = make([]string, n)
   569  	}
   570  	*s = (*s)[:n]
   571  	return s
   572  }
   573  
   574  func putStrings(s *stringSlice) {
   575  	if cap(*s) > 1<<10 {
   576  		*s = nil // avoid pinning arbitrarily large amounts of memory
   577  	}
   578  	clear(*s) // avoid pinning a reference to each string
   579  	stringsPools.Put(s)
   580  }
   581  

View as plain text