package json
import (
)
const optimizeCommon = true
var (
anyType = reflect.TypeFor[any]()
boolType = reflect.TypeFor[bool]()
stringType = reflect.TypeFor[string]()
float64Type = reflect.TypeFor[float64]()
mapStringAnyType = reflect.TypeFor[map[string]any]()
sliceAnyType = reflect.TypeFor[[]any]()
bytesType = reflect.TypeFor[[]byte]()
emptyStructType = reflect.TypeFor[struct{}]()
)
const startDetectingCyclesAfter = 1000
type seenPointers = map[any]struct{}
type typedPointer struct {
typ reflect.Type
ptr any
len int
}
func ( *seenPointers, reflect.Value) error {
:= typedPointer{.Type(), .UnsafePointer(), sliceLen()}
if , := (*)[]; {
return internal.ErrCycle
}
if * == nil {
* = make(seenPointers)
}
(*)[] = struct{}{}
return nil
}
func ( *seenPointers, reflect.Value) {
:= typedPointer{.Type(), .UnsafePointer(), sliceLen()}
delete(*, )
}
func ( reflect.Value) int {
if .Kind() == reflect.Slice {
return .Len()
}
return 0
}
func [ ~[]byte | ~string]( ) int64 {
return int64(len())
}
func ( reflect.Type) *arshaler {
switch .Kind() {
case reflect.Bool:
return makeBoolArshaler()
case reflect.String:
return makeStringArshaler()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return makeIntArshaler()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return makeUintArshaler()
case reflect.Float32, reflect.Float64:
return makeFloatArshaler()
case reflect.Map:
return makeMapArshaler()
case reflect.Struct:
return makeStructArshaler()
case reflect.Slice:
:= makeSliceArshaler()
if .Elem().Kind() == reflect.Uint8 {
return makeBytesArshaler(, )
}
return
case reflect.Array:
:= makeArrayArshaler()
if .Elem().Kind() == reflect.Uint8 {
return makeBytesArshaler(, )
}
return
case reflect.Pointer:
return makePointerArshaler()
case reflect.Interface:
return makeInterfaceArshaler()
default:
return makeInvalidArshaler()
}
}
func ( reflect.Type) *arshaler {
var arshaler
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
var bool
if .Flags.Has(jsonflags.TagFlags) {
= .Flags.Get(jsonflags.StringTag) && .Flags.Get(jsonflags.StringifyWithLegacySemantics)
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && ! && !.Tokens.Last.NeedObjectName() {
.Buf = strconv.AppendBool(.Tokens.MayAppendDelim(.Buf, 't'), .Bool())
.Tokens.Last.Increment()
if .NeedFlush() {
return .Flush()
}
return nil
}
if {
if .Bool() {
return .WriteToken(jsontext.String("true"))
} else {
return .WriteToken(jsontext.String("false"))
}
}
return .WriteToken(jsontext.Bool(.Bool()))
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
var bool
if .Flags.Has(jsonflags.TagFlags) {
= .Flags.Get(jsonflags.StringTag) && .Flags.Get(jsonflags.StringifyWithLegacySemantics)
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
, := .ReadToken()
if != nil {
return
}
:= .Kind()
switch {
case 'n':
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetBool(false)
}
return nil
case 't', 'f':
if ! {
.SetBool(.Bool())
return nil
}
case '"':
if {
switch .String() {
case "true":
.SetBool(true)
case "false":
.SetBool(false)
default:
if .Flags.Get(jsonflags.StringifyWithLegacySemantics) && .String() == "null" {
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetBool(false)
}
return nil
}
return newUnmarshalErrorAfterWithValue(, , strconv.ErrSyntax)
}
return nil
}
}
return newUnmarshalErrorAfterWithSkipping(, , nil)
}
return &
}
func ( reflect.Type) *arshaler {
var arshaler
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
var bool
if .Flags.Has(jsonflags.TagFlags) {
= .Flags.Get(jsonflags.StringTag) && .Flags.Get(jsonflags.StringifyWithLegacySemantics)
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
:= .String()
if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && ! && !.Tokens.Last.NeedObjectName() {
:= .Buf
= .Tokens.MayAppendDelim(, '"')
, := jsonwire.AppendQuote(, []byte(), &.Flags)
if == nil {
.Buf =
.Tokens.Last.Increment()
if .NeedFlush() {
return .Flush()
}
return nil
}
}
if {
, := jsonwire.AppendQuote(nil, []byte(), &.Flags)
if != nil {
return newMarshalErrorBefore(, , &jsontext.SyntacticError{Err: })
}
, := jsontext.AppendQuote(nil, )
if != nil {
panic("BUG: second AppendQuote should never fail: " + .Error())
}
return .WriteValue()
}
return .WriteToken(jsontext.String())
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
:= export.Decoder()
var bool
if .Flags.Has(jsonflags.TagFlags) {
= .Flags.Get(jsonflags.StringTag) && .Flags.Get(jsonflags.StringifyWithLegacySemantics)
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
var jsonwire.ValueFlags
, := .ReadValue(&)
if != nil {
return
}
:= .Kind()
switch {
case 'n':
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetString("")
}
return nil
case '"':
= jsonwire.UnquoteMayCopy(, .IsVerbatim())
if {
if string() == "null" {
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetString("")
}
return nil
}
, = jsontext.AppendUnquote(nil, )
if != nil {
return newUnmarshalErrorAfter(, , )
}
}
if .StringCache == nil {
.StringCache = new(stringCache)
}
:= makeString(.StringCache, )
.SetString()
return nil
}
return newUnmarshalErrorAfter(, , nil)
}
return &
}
var (
appendEncodeBase16 = hex.AppendEncode
appendEncodeBase32 = base32.StdEncoding.AppendEncode
appendEncodeBase32Hex = base32.HexEncoding.AppendEncode
appendEncodeBase64 = base64.StdEncoding.AppendEncode
appendEncodeBase64URL = base64.URLEncoding.AppendEncode
encodedLenBase16 = hex.EncodedLen
encodedLenBase32 = base32.StdEncoding.EncodedLen
encodedLenBase32Hex = base32.HexEncoding.EncodedLen
encodedLenBase64 = base64.StdEncoding.EncodedLen
encodedLenBase64URL = base64.URLEncoding.EncodedLen
appendDecodeBase16 = hex.AppendDecode
appendDecodeBase32 = base32.StdEncoding.AppendDecode
appendDecodeBase32Hex = base32.HexEncoding.AppendDecode
appendDecodeBase64 = base64.StdEncoding.AppendDecode
appendDecodeBase64URL = base64.URLEncoding.AppendDecode
)
func ( reflect.Type, *arshaler) *arshaler {
:= .marshal
:= .Elem().PkgPath() != ""
:= implementsAny(.Elem(), allMarshalerTypes...)
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
if !.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && {
return (, , )
}
:= export.Encoder()
:= appendEncodeBase64
if .Flags.Has(jsonflags.TagFlags | jsonflags.FormatByteArrayAsArray | jsonflags.FormatBytesWithLegacySemantics | jsonflags.FormatNilSliceAsNull) {
switch {
case .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics):
return newMarshalErrorBefore(, , errInvalidStringTag)
case .Flags.Has(jsonflags.FormatTag):
switch .Format {
case "base64":
= appendEncodeBase64
case "base64url":
= appendEncodeBase64URL
case "base32":
= appendEncodeBase32
case "base32hex":
= appendEncodeBase32Hex
case "base16", "hex":
= appendEncodeBase16
case "array":
.Flags.Clear(jsonflags.FormatTag)
return (, , )
default:
return newInvalidFormatError(, )
}
case .Flags.Get(jsonflags.FormatByteArrayAsArray) && .Kind() == reflect.Array:
return (, , )
case .Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && :
return (, , )
}
if .Flags.Get(jsonflags.FormatNilSliceAsNull) && .Kind() == reflect.Slice && .IsNil() {
return .WriteToken(jsontext.Null)
}
}
return .AppendRaw('"', true, func( []byte) ([]byte, error) {
return (, .Bytes()), nil
})
}
:= .unmarshal
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
if !.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && {
return (, , )
}
:= export.Decoder()
, := appendDecodeBase64, encodedLenBase64
if .Flags.Has(jsonflags.TagFlags | jsonflags.FormatByteArrayAsArray | jsonflags.FormatBytesWithLegacySemantics) {
switch {
case .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics):
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
case .Flags.Has(jsonflags.FormatTag):
switch .Format {
case "base64":
, = appendDecodeBase64, encodedLenBase64
case "base64url":
, = appendDecodeBase64URL, encodedLenBase64URL
case "base32":
, = appendDecodeBase32, encodedLenBase32
case "base32hex":
, = appendDecodeBase32Hex, encodedLenBase32Hex
case "base16", "hex":
, = appendDecodeBase16, encodedLenBase16
case "array":
.Flags.Clear(jsonflags.FormatTag)
return (, , )
default:
return newInvalidFormatError(, )
}
case .Flags.Get(jsonflags.FormatByteArrayAsArray) && .Kind() == reflect.Array:
return (, , )
case .Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && .PeekKind() == '[':
return (, , )
}
}
var jsonwire.ValueFlags
, := .ReadValue(&)
if != nil {
return
}
:= .Kind()
switch {
case 'n':
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) || .Kind() != reflect.Array {
.SetZero()
}
return nil
case '"':
= jsonwire.UnquoteMayCopy(, .IsVerbatim())
, := (.Bytes()[:0], )
if != nil {
return newUnmarshalErrorAfter(, , )
}
if len() != (len()) && !.Flags.Get(jsonflags.ParseBytesWithLooseRFC4648) {
:= bytes.IndexAny(, "\r\n")
:= fmt.Errorf("illegal character %s at offset %d", jsonwire.QuoteRune([:]), )
return newUnmarshalErrorAfter(, , )
}
if .Kind() == reflect.Array {
:= .Bytes()
clear([copy(, ):])
if len() != len() && !.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) {
:= fmt.Errorf("decoded length of %d mismatches array length of %d", len(), len())
return newUnmarshalErrorAfter(, , )
}
} else {
if == nil {
= []byte{}
}
.SetBytes()
}
return nil
}
return newUnmarshalErrorAfter(, , nil)
}
return
}
func ( reflect.Type) *arshaler {
var arshaler
:= .Bits()
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
:= .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && ! {
.Buf = strconv.AppendInt(.Tokens.MayAppendDelim(.Buf, '0'), .Int(), 10)
.Tokens.Last.Increment()
if .NeedFlush() {
return .Flush()
}
return nil
}
:= stringOrNumberKind()
return .AppendRaw(, true, func( []byte) ([]byte, error) {
return strconv.AppendInt(, .Int(), 10), nil
})
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
:= export.Decoder()
:= .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
var jsonwire.ValueFlags
, := .ReadValue(&)
if != nil {
return
}
:= .Kind()
switch {
case 'n':
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetInt(0)
}
return nil
case '"':
if ! {
break
}
= jsonwire.UnquoteMayCopy(, .IsVerbatim())
if .Flags.Get(jsonflags.StringifyWithLegacySemantics) {
, := strconv.ParseInt(string(), 10, )
if != nil {
if string() == "null" {
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetInt(0)
}
return nil
}
return newUnmarshalErrorAfterWithValue(, , errors.Unwrap())
}
.SetInt()
return nil
}
fallthrough
case '0':
if && == '0' {
break
}
var int
:= len() > 0 && [0] == '-'
if {
= 1
}
, := jsonwire.ParseUint([:])
:= uint64(1) << ( - 1)
:= ( && > ) || (! && > -1)
if ! {
if != math.MaxUint64 {
return newUnmarshalErrorAfterWithValue(, , strconv.ErrSyntax)
}
= true
}
if {
return newUnmarshalErrorAfterWithValue(, , strconv.ErrRange)
}
if {
.SetInt(int64(-))
} else {
.SetInt(int64(+))
}
return nil
}
return newUnmarshalErrorAfter(, , nil)
}
return &
}
func ( reflect.Type) *arshaler {
var arshaler
:= .Bits()
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
:= .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && ! {
.Buf = strconv.AppendUint(.Tokens.MayAppendDelim(.Buf, '0'), .Uint(), 10)
.Tokens.Last.Increment()
if .NeedFlush() {
return .Flush()
}
return nil
}
:= stringOrNumberKind()
return .AppendRaw(, true, func( []byte) ([]byte, error) {
return strconv.AppendUint(, .Uint(), 10), nil
})
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
:= export.Decoder()
:= .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
var jsonwire.ValueFlags
, := .ReadValue(&)
if != nil {
return
}
:= .Kind()
switch {
case 'n':
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetUint(0)
}
return nil
case '"':
if ! {
break
}
= jsonwire.UnquoteMayCopy(, .IsVerbatim())
if .Flags.Get(jsonflags.StringifyWithLegacySemantics) {
, := strconv.ParseUint(string(), 10, )
if != nil {
if string() == "null" {
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetUint(0)
}
return nil
}
return newUnmarshalErrorAfterWithValue(, , errors.Unwrap())
}
.SetUint()
return nil
}
fallthrough
case '0':
if && == '0' {
break
}
, := jsonwire.ParseUint()
:= uint64(1) <<
:= > -1
if ! {
if != math.MaxUint64 {
return newUnmarshalErrorAfterWithValue(, , strconv.ErrSyntax)
}
= true
}
if {
return newUnmarshalErrorAfterWithValue(, , strconv.ErrRange)
}
.SetUint()
return nil
}
return newUnmarshalErrorAfter(, , nil)
}
return &
}
func ( reflect.Type) *arshaler {
var arshaler
:= .Bits()
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
:= .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
var bool
if .Flags.Has(jsonflags.FormatTag) {
if .Format == "nonfinite" {
= true
} else {
return newInvalidFormatError(, )
}
}
:= .Float()
if math.IsNaN() || math.IsInf(, 0) {
if ! {
:= fmt.Errorf("unsupported value: %v", )
if .Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
= &internal.ValueError{Val: .Interface(), Err: }
}
return newMarshalErrorBefore(, , )
}
return .WriteToken(jsontext.Float())
}
if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && ! {
.Buf = jsonwire.AppendFloat(.Tokens.MayAppendDelim(.Buf, '0'), , )
.Tokens.Last.Increment()
if .NeedFlush() {
return .Flush()
}
return nil
}
:= stringOrNumberKind()
return .AppendRaw(, true, func( []byte) ([]byte, error) {
return jsonwire.AppendFloat(, .Float(), ), nil
})
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
:= export.Decoder()
:= .Tokens.Last.NeedObjectName() || .Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
var bool
if .Flags.Has(jsonflags.FormatTag) {
if .Format == "nonfinite" {
= true
} else {
return newInvalidFormatError(, )
}
}
var jsonwire.ValueFlags
, := .ReadValue(&)
if != nil {
return
}
:= .Kind()
switch {
case 'n':
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetFloat(0)
}
return nil
case '"':
= jsonwire.UnquoteMayCopy(, .IsVerbatim())
if {
switch string() {
case "NaN":
.SetFloat(math.NaN())
return nil
case "Infinity":
.SetFloat(math.Inf(+1))
return nil
case "-Infinity":
.SetFloat(math.Inf(-1))
return nil
}
}
if ! {
break
}
if .Flags.Get(jsonflags.StringifyWithLegacySemantics) {
, := strconv.ParseFloat(string(), )
if != nil {
if string() == "null" {
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetFloat(0)
}
return nil
}
return newUnmarshalErrorAfterWithValue(, , errors.Unwrap())
}
.SetFloat()
return nil
}
if , := jsonwire.ConsumeNumber(); != len() || != nil {
return newUnmarshalErrorAfterWithValue(, , strconv.ErrSyntax)
}
fallthrough
case '0':
if && == '0' {
break
}
, := strconv.ParseFloat(string(), )
if != nil {
return newUnmarshalErrorAfterWithValue(, , errors.Unwrap())
}
.SetFloat()
return nil
}
return newUnmarshalErrorAfter(, , nil)
}
return &
}
func ( reflect.Type) *arshaler {
var arshaler
var (
sync.Once
*arshaler
*arshaler
)
:= func() {
= lookupArshaler(.Key())
= lookupArshaler(.Elem())
}
:= .Key().Kind() == reflect.Pointer &&
implementsAny(.Key(), textMarshalerType, textAppenderType)
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
if .Tokens.Depth() > startDetectingCyclesAfter {
if := visitPointer(&.SeenPointers, .Value); != nil {
return newMarshalErrorBefore(, , )
}
defer leavePointer(&.SeenPointers, .Value)
}
:= .Flags.Get(jsonflags.FormatNilMapAsNull)
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
switch .Format {
case "emitnull":
= true
case "emitempty":
= false
default:
return newInvalidFormatError(, )
}
}
}
:= .Len()
if == 0 {
if && .IsNil() {
return .WriteToken(jsontext.Null)
}
if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && !.Tokens.Last.NeedObjectName() {
.Buf = append(.Tokens.MayAppendDelim(.Buf, '{'), "{}"...)
.Tokens.Last.Increment()
if .NeedFlush() {
return .Flush()
}
return nil
}
}
.Do()
if := .WriteToken(jsontext.BeginObject); != nil {
return
}
if > 0 {
:= .nonDefault
:= .marshal
:= .marshal
if .Marshalers != nil {
var bool
, = .Marshalers.(*Marshalers).lookup(, .Key())
, _ = .Marshalers.(*Marshalers).lookup(, .Elem())
= ||
}
:= newAddressableValue(.Key())
:= newAddressableValue(.Elem())
if ! && mapKeyWithUniqueRepresentation(.Kind(), .Flags.Get(jsonflags.AllowInvalidUTF8)) {
.Tokens.Last.DisableNamespace()
}
switch {
case !.Flags.Get(jsonflags.Deterministic) || <= 1:
for := .Value.MapRange(); .Next(); {
.SetIterKey()
:= (, , )
if != nil {
if .Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&
errors.Is(, jsontext.ErrNonStringName) && && .IsNil() {
= .WriteToken(jsontext.String(""))
}
if != nil {
if , := .(*jsontext.SyntacticError); && .Err == jsontext.ErrNonStringName {
= newMarshalErrorBefore(, .Type(), )
}
return
}
}
.SetIterValue()
if := (, , ); != nil {
return
}
}
case ! && .Key().Kind() == reflect.String:
:= getStrings()
for , := 0, .Value.MapRange(); < && .Next(); ++ {
.SetIterKey()
(*)[] = .String()
}
slices.Sort(*)
for , := range * {
if := .WriteToken(jsontext.String()); != nil {
return
}
.SetString()
.Set(.MapIndex(.Value))
if := (, , ); != nil {
return
}
}
putStrings()
default:
type struct {
string
addressableValue
addressableValue
}
:= make([], )
:= reflect.MakeSlice(reflect.SliceOf(.Key()), , )
:= reflect.MakeSlice(reflect.SliceOf(.Elem()), , )
for , := 0, .Value.MapRange(); < && .Next(); ++ {
:= addressableValue{.Index(), true}
.SetIterKey()
:= addressableValue{.Index(), true}
.SetIterValue()
:= (, , )
if != nil {
if .Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&
errors.Is(, jsontext.ErrNonStringName) && && .IsNil() {
= .WriteToken(jsontext.String(""))
}
if != nil {
if , := .(*jsontext.SyntacticError); && .Err == jsontext.ErrNonStringName {
= newMarshalErrorBefore(, .Type(), )
}
return
}
}
:= .UnwriteOnlyObjectMemberName()
[] = {, , }
}
slices.SortFunc(, func(, ) int {
return strings.Compare(., .)
})
for , := range {
if := .WriteToken(jsontext.String(.)); != nil {
return
}
if := (, ., ); != nil {
return
}
}
}
}
if := .WriteToken(jsontext.EndObject); != nil {
return
}
return nil
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
:= export.Decoder()
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
switch .Format {
case "emitnull", "emitempty":
default:
return newInvalidFormatError(, )
}
}
}
, := .ReadToken()
if != nil {
return
}
:= .Kind()
switch {
case 'n':
.SetZero()
return nil
case '{':
.Do()
if .IsNil() {
.Set(reflect.MakeMap())
}
:= .nonDefault
:= .unmarshal
:= .unmarshal
if .Unmarshalers != nil {
var bool
, = .Unmarshalers.(*Unmarshalers).lookup(, .Key())
, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Elem())
= ||
}
:= newAddressableValue(.Key())
:= newAddressableValue(.Elem())
if ! && mapKeyWithUniqueRepresentation(.Kind(), .Flags.Get(jsonflags.AllowInvalidUTF8)) {
.Tokens.Last.DisableNamespace()
}
var reflect.Value
if !.Flags.Get(jsonflags.AllowDuplicateNames) && .Len() > 0 {
= reflect.MakeMap(reflect.MapOf(.Type(), emptyStructType))
}
var error
for .PeekKind() != '}' {
.SetZero()
:= (, , )
if != nil {
if isFatalError(, .Flags) {
return
}
if := .SkipValue(); != nil {
return
}
= cmp.Or(, )
continue
}
if .Kind() == reflect.Interface && !.IsNil() && !.Elem().Type().Comparable() {
:= newUnmarshalErrorAfter(, , fmt.Errorf("invalid incomparable key type %v", .Elem().Type()))
if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return
}
if := .SkipValue(); != nil {
return
}
= cmp.Or(, )
continue
}
if := .MapIndex(.Value); .IsValid() {
if !.Flags.Get(jsonflags.AllowDuplicateNames) && (!.IsValid() || .MapIndex(.Value).IsValid()) {
:= .PreviousTokenOrValue()
return newDuplicateNameError(.StackPointer(), nil, .InputOffset()-len64())
}
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.Set()
} else {
.SetZero()
}
} else {
.SetZero()
}
= (, , )
.SetMapIndex(.Value, .Value)
if .IsValid() {
.SetMapIndex(.Value, reflect.Zero(emptyStructType))
}
if != nil {
if isFatalError(, .Flags) {
return
}
= cmp.Or(, )
}
}
if , := .ReadToken(); != nil {
return
}
return
}
return newUnmarshalErrorAfterWithSkipping(, , nil)
}
return &
}
func ( reflect.Kind, bool) bool {
switch {
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return true
case reflect.String:
return !
default:
return false
}
}
var errNilField = errors.New("cannot set embedded pointer to unexported struct type")
var errInvalidStringTag = errors.New("invalid use of `string` tag option")
func ( reflect.Type) *arshaler {
var arshaler
var (
sync.Once
structFields
*SemanticError
)
:= func() {
, = makeStructFields()
}
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
.Do()
if != nil && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, .GoType, .Err)
} else if .errUnsupportedFormat != nil && !.Flags.Get(jsonflags.FormatTagSupported) {
return newMarshalErrorBefore(, .errUnsupportedFormat.GoType, .errUnsupportedFormat.Err)
}
if := .WriteToken(jsontext.BeginObject); != nil {
return
}
var uintSet
:= -1
.Tokens.Last.DisableNamespace()
for := range .flattened {
:= &.flattened[]
:= addressableValue{.Field(.index0), .forcedAddr}
if len(.index) > 0 {
= .fieldByIndex(.index, false)
if !.IsValid() {
continue
}
}
if (.omitzero || .Flags.Get(jsonflags.OmitZeroStructFields)) &&
((.isZero == nil && .IsZero()) || (.isZero != nil && .isZero())) {
continue
}
if .omitempty && .Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) && isLegacyEmpty() {
continue
}
:= .fncs.marshal
:= .fncs.nonDefault
if .Marshalers != nil {
var bool
, = .Marshalers.(*Marshalers).lookup(, .typ)
= ||
}
if .omitempty && !.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) &&
! && .isEmpty != nil && .isEmpty() {
continue
}
if optimizeCommon {
:= .Buf
if .Tokens.Last.Length() > 0 {
= append(, ',')
if .Flags.Get(jsonflags.SpaceAfterComma) {
= append(, ' ')
}
}
if .Flags.Get(jsonflags.Multiline) {
= .AppendIndent(, .Tokens.NeedIndent('"'))
}
:= len()
if !.nameNeedEscape {
= append(, .quotedName...)
} else {
, _ = jsonwire.AppendQuote(, []byte(.name), &.Flags)
}
.Buf =
.Names.ReplaceLastQuotedOffset()
.Tokens.Last.Increment()
} else {
if := .WriteToken(jsontext.String(.name)); != nil {
return
}
}
:= .Flags
if .string {
.Flags.Set(jsonflags.StringTag | 1)
}
if .format != "" {
.Flags.Set(jsonflags.FormatTag | 1)
.Format = .format
}
:= (, , )
.Flags =
.Format = ""
if != nil {
return
}
if .omitempty && !.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) {
var *string
if >= 0 {
= &.flattened[].name
}
if .UnwriteEmptyObjectMember() {
continue
}
}
if !.Flags.Get(jsonflags.AllowDuplicateNames) && .embeddedFallback != nil {
.insert(uint(.id))
}
= .id
}
if .embeddedFallback != nil {
var func([]byte) bool
if !.Flags.Get(jsonflags.AllowDuplicateNames) {
= func( []byte) bool {
if := .lookupByFoldedName(); len() > 0 {
if := .byActualName[string()]; != nil {
return .insert(uint(.id))
}
for , := range {
if .matchFoldedName(, &.Flags) {
return .insert(uint(.id))
}
}
}
return .Namespaces.Last().InsertUnquoted()
}
}
if := marshalEmbeddedFallbackAll(, , , .embeddedFallback, ); != nil {
return
}
}
if := .WriteToken(jsontext.EndObject); != nil {
return
}
return nil
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
:= export.Decoder()
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
, := .ReadToken()
if != nil {
return
}
:= .Kind()
switch {
case 'n':
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetZero()
}
return nil
case '{':
.Do()
if != nil && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorAfter(, .GoType, .Err)
} else if .errUnsupportedFormat != nil && !.Flags.Get(jsonflags.FormatTagSupported) {
return newUnmarshalErrorAfter(, .errUnsupportedFormat.GoType, .errUnsupportedFormat.Err)
}
var uintSet
.Tokens.Last.DisableNamespace()
var error
for .PeekKind() != '}' {
var jsonwire.ValueFlags
, := .ReadValue(&)
if != nil {
return
}
:= jsonwire.UnquoteMayCopy(, .IsVerbatim())
:= .byActualName[string()]
if == nil {
var int
for , := range .lookupByFoldedName() {
if .matchFoldedName(, &.Flags) {
if == nil {
=
}
++
}
}
if > 1 && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorAfter(, , errAmbiguousName)
}
if == nil {
if .Flags.Get(jsonflags.RejectUnknownMembers) && .embeddedFallback == nil {
:= newUnmarshalErrorAfter(, , ErrUnknownName)
if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return
}
= cmp.Or(, )
}
if !.Flags.Get(jsonflags.AllowDuplicateNames) && !.Namespaces.Last().InsertUnquoted() {
return newDuplicateNameError(.StackPointer(), nil, .InputOffset()-len64())
}
if .embeddedFallback == nil {
if := .SkipValue(); != nil {
return
}
} else {
if := unmarshalEmbeddedFallbackNext(, , , .embeddedFallback, , ); != nil {
if isFatalError(, .Flags) {
return
}
= cmp.Or(, )
}
}
continue
}
}
if !.Flags.Get(jsonflags.AllowDuplicateNames) && !.insert(uint(.id)) {
return newDuplicateNameError(.StackPointer(), nil, .InputOffset()-len64())
}
:= .fncs.unmarshal
if .Unmarshalers != nil {
, _ = .Unmarshalers.(*Unmarshalers).lookup(, .typ)
}
:= .Flags
if .string {
.Flags.Set(jsonflags.StringTag | 1)
}
if .format != "" {
.Flags.Set(jsonflags.FormatTag | 1)
.Format = .format
}
:= addressableValue{.Field(.index0), .forcedAddr}
if len(.index) > 0 {
= .fieldByIndex(.index, true)
if !.IsValid() {
:= newUnmarshalErrorBefore(, , errNilField)
if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return
}
= cmp.Or(, )
= func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
return .SkipValue()
}
}
}
= (, , )
.Flags =
.Format = ""
if != nil {
if isFatalError(, .Flags) {
return
}
= cmp.Or(, )
}
}
if , := .ReadToken(); != nil {
return
}
return
}
return newUnmarshalErrorAfterWithSkipping(, , nil)
}
return &
}
func ( addressableValue) ( []int, bool) addressableValue {
for , := range {
= .indirect()
if !.IsValid() {
return
}
= addressableValue{.Field(), .forcedAddr}
}
return
}
func ( addressableValue) ( bool) addressableValue {
if .Kind() == reflect.Pointer {
if .IsNil() {
if ! || !.CanSet() {
return addressableValue{}
}
.Set(reflect.New(.Type().Elem()))
}
= addressableValue{.Elem(), false}
}
return
}
func ( addressableValue) bool {
switch .Kind() {
case reflect.Bool:
return .Bool() == false
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return .Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return .Uint() == 0
case reflect.Float32, reflect.Float64:
return .Float() == 0
case reflect.String, reflect.Map, reflect.Slice, reflect.Array:
return .Len() == 0
case reflect.Pointer, reflect.Interface:
return .IsNil()
}
return false
}
func ( reflect.Type) *arshaler {
var arshaler
var (
sync.Once
*arshaler
)
:= func() {
= lookupArshaler(.Elem())
}
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
if .Tokens.Depth() > startDetectingCyclesAfter {
if := visitPointer(&.SeenPointers, .Value); != nil {
return newMarshalErrorBefore(, , )
}
defer leavePointer(&.SeenPointers, .Value)
}
:= .Flags.Get(jsonflags.FormatNilSliceAsNull)
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
switch .Format {
case "emitnull":
= true
case "emitempty":
= false
default:
return newInvalidFormatError(, )
}
}
}
:= .Len()
if == 0 {
if && .IsNil() {
return .WriteToken(jsontext.Null)
}
if optimizeCommon && !.Flags.Get(jsonflags.AnyWhitespace) && !.Tokens.Last.NeedObjectName() {
.Buf = append(.Tokens.MayAppendDelim(.Buf, '['), "[]"...)
.Tokens.Last.Increment()
if .NeedFlush() {
return .Flush()
}
return nil
}
}
.Do()
if := .WriteToken(jsontext.BeginArray); != nil {
return
}
:= .marshal
if .Marshalers != nil {
, _ = .Marshalers.(*Marshalers).lookup(, .Elem())
}
for := range {
:= addressableValue{.Index(), false}
if := (, , ); != nil {
return
}
}
if := .WriteToken(jsontext.EndArray); != nil {
return
}
return nil
}
:= reflect.MakeSlice(, 0, 0)
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
switch .Format {
case "emitnull", "emitempty":
default:
return newInvalidFormatError(, )
}
}
}
, := .ReadToken()
if != nil {
return
}
:= .Kind()
switch {
case 'n':
.SetZero()
return nil
case '[':
.Do()
:= .unmarshal
if .Unmarshalers != nil {
, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Elem())
}
:= true
:= .Cap()
if > 0 {
.SetLen()
}
var int
var error
for .PeekKind() != ']' {
if == {
.Value.Grow(1)
= .Cap()
.SetLen()
= false
}
:= addressableValue{.Index(), false}
++
if && !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetZero()
}
if := (, , ); != nil {
if isFatalError(, .Flags) {
.SetLen()
return
}
= cmp.Or(, )
}
}
if == 0 {
.Set()
} else {
.SetLen()
}
if , := .ReadToken(); != nil {
return
}
return
}
return newUnmarshalErrorAfterWithSkipping(, , nil)
}
return &
}
var errArrayUnderflow = errors.New("too few array elements")
var errArrayOverflow = errors.New("too many array elements")
func ( reflect.Type) *arshaler {
var arshaler
var (
sync.Once
*arshaler
)
:= func() {
= lookupArshaler(.Elem())
}
:= .Len()
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
.Do()
if := .WriteToken(jsontext.BeginArray); != nil {
return
}
:= .marshal
if .Marshalers != nil {
, _ = .Marshalers.(*Marshalers).lookup(, .Elem())
}
for := range {
:= addressableValue{.Index(), .forcedAddr}
if := (, , ); != nil {
return
}
}
if := .WriteToken(jsontext.EndArray); != nil {
return
}
return nil
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) && !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
, := .ReadToken()
if != nil {
return
}
:= .Kind()
switch {
case 'n':
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetZero()
}
return nil
case '[':
.Do()
:= .unmarshal
if .Unmarshalers != nil {
, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Elem())
}
var int
var error
for .PeekKind() != ']' {
if >= {
if := .SkipValue(); != nil {
return
}
= errArrayOverflow
continue
}
:= addressableValue{.Index(), .forcedAddr}
if !.Flags.Get(jsonflags.MergeWithLegacySemantics) {
.SetZero()
}
if := (, , ); != nil {
if isFatalError(, .Flags) {
return
}
= cmp.Or(, )
}
++
}
for ; < ; ++ {
.Index().SetZero()
= errArrayUnderflow
}
if , := .ReadToken(); != nil {
return
}
if != nil && !.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) {
return newUnmarshalErrorAfter(, , )
}
return
}
return newUnmarshalErrorAfterWithSkipping(, , nil)
}
return &
}
func ( reflect.Type) *arshaler {
var arshaler
var (
sync.Once
*arshaler
)
:= func() {
= lookupArshaler(.Elem())
}
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
:= export.Encoder()
if .Tokens.Depth() > startDetectingCyclesAfter {
if := visitPointer(&.SeenPointers, .Value); != nil {
return newMarshalErrorBefore(, , )
}
defer leavePointer(&.SeenPointers, .Value)
}
if .Flags.Get(jsonflags.StringTag) && .Flags.Get(jsonflags.StringifyWithLegacySemantics) && .Elem().Kind() == reflect.Pointer {
if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, , errInvalidStringTag)
}
.Flags.Clear(jsonflags.StringTag)
}
if .IsNil() {
return .WriteToken(jsontext.Null)
}
.Do()
:= .marshal
if .Marshalers != nil {
, _ = .Marshalers.(*Marshalers).lookup(, .Elem())
}
:= addressableValue{.Elem(), false}
return (, , )
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
if .PeekKind() == 'n' {
if , := .ReadToken(); != nil {
return
}
.SetZero()
return nil
}
if .Flags.Get(jsonflags.StringTag) && .Flags.Get(jsonflags.StringifyWithLegacySemantics) && .Elem().Kind() == reflect.Pointer {
if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
}
.Flags.Clear(jsonflags.StringTag)
}
.Do()
:= .unmarshal
if .Unmarshalers != nil {
, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Elem())
}
if .IsNil() {
.Set(reflect.New(.Elem()))
}
:= addressableValue{.Elem(), false}
if := (, , ); != nil {
return
}
if .Flags.Get(jsonflags.StringTag) && .Flags.Get(jsonflags.StringifyWithLegacySemantics) {
if string(export.Decoder().PreviousTokenOrValue()) == `"null"` {
.SetZero()
}
}
return nil
}
return &
}
func ( reflect.Type) *arshaler {
var arshaler
var reflect.Type
for , := range allMarshalerTypes {
if .Implements() {
=
break
}
}
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) {
if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newMarshalErrorBefore(, , errInvalidStringTag)
}
if .Flags.Get(jsonflags.StringifyWithLegacySemantics) {
.Flags.Clear(jsonflags.StringTag)
}
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
if .IsNil() {
return .WriteToken(jsontext.Null)
} else if .Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && != nil {
if .Elem().Kind() == reflect.Pointer && .Elem().IsNil() {
:= newAddressableValue()
switch {
case jsonMarshalerToType:
.Set(reflect.ValueOf(struct{ MarshalerTo }{.Elem().Interface().(MarshalerTo)}))
case jsonMarshalerType:
.Set(reflect.ValueOf(struct{ Marshaler }{.Elem().Interface().(Marshaler)}))
case textAppenderType:
.Set(reflect.ValueOf(struct{ encoding.TextAppender }{.Elem().Interface().(encoding.TextAppender)}))
case textMarshalerType:
.Set(reflect.ValueOf(struct{ encoding.TextMarshaler }{.Elem().Interface().(encoding.TextMarshaler)}))
}
=
}
}
:= newAddressableValue(.Elem().Type())
.Set(.Elem())
:= lookupArshaler(.Type()).marshal
if .Marshalers != nil {
, _ = .Marshalers.(*Marshalers).lookup(, .Type())
}
if optimizeCommon &&
== anyType && !.Flags.Get(jsonflags.StringifyNumbers|jsonflags.TagFlags) &&
(.Marshalers == nil || !.Marshalers.(*Marshalers).fromAny) {
return marshalValueAny(, .Elem().Interface(), )
}
return (, , )
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
if .Flags.Has(jsonflags.TagFlags) {
if .Flags.Get(jsonflags.StringTag) {
if !.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
return newUnmarshalErrorBeforeWithSkipping(, , errInvalidStringTag)
}
if .Flags.Get(jsonflags.StringifyWithLegacySemantics) {
.Flags.Clear(jsonflags.StringTag)
}
}
if .Flags.Has(jsonflags.FormatTag) {
return newInvalidFormatError(, )
}
}
if .Flags.Get(jsonflags.MergeWithLegacySemantics) && !.IsNil() {
:= .Elem()
if .Kind() == reflect.Pointer && !.IsNil() {
if .PeekKind() == 'n' && .Elem().Kind() == reflect.Pointer {
if , := .ReadToken(); != nil {
return
}
.Elem().Elem().SetZero()
return nil
}
} else {
.SetZero()
}
}
if .PeekKind() == 'n' {
if , := .ReadToken(); != nil {
return
}
.SetZero()
return nil
}
var addressableValue
if .IsNil() {
if optimizeCommon &&
== anyType && !.Flags.Get(jsonflags.AllowDuplicateNames|jsonflags.FormatTag) &&
(.Unmarshalers == nil || !.Unmarshalers.(*Unmarshalers).fromAny) {
, := unmarshalValueAny(, )
if != nil {
.Set(reflect.ValueOf())
}
return
}
:= .PeekKind()
if !isAnyType() {
return newUnmarshalErrorBeforeWithSkipping(, , internal.ErrNilInterface)
}
switch {
case 'f', 't':
= newAddressableValue(boolType)
case '"':
= newAddressableValue(stringType)
case '0':
if .Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) {
= addressableValue{reflect.ValueOf(internal.NewRawNumber()).Elem(), true}
} else {
= newAddressableValue(float64Type)
}
case '{':
= newAddressableValue(mapStringAnyType)
case '[':
= newAddressableValue(sliceAnyType)
default:
, := .ReadValue()
return
}
} else {
= newAddressableValue(.Elem().Type())
.Set(.Elem())
}
:= lookupArshaler(.Type()).unmarshal
if .Unmarshalers != nil {
, _ = .Unmarshalers.(*Unmarshalers).lookup(, .Type())
}
:= (, , )
.Set(.Value)
return
}
return &
}
func ( reflect.Type) bool {
return == anyType || anyType.Implements()
}
func ( reflect.Type) *arshaler {
var arshaler
.marshal = func( *jsontext.Encoder, addressableValue, *jsonopts.Struct) error {
return newMarshalErrorBefore(, , nil)
}
.unmarshal = func( *jsontext.Decoder, addressableValue, *jsonopts.Struct) error {
if .Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
switch , := .ReadValue(); {
case != nil:
return
case .Kind() == 'n':
return nil
default:
return newUnmarshalErrorAfter(, , nil)
}
}
return newUnmarshalErrorBefore(, , nil)
}
return &
}
func ( bool) jsontext.Kind {
if {
return '"'
} else {
return '0'
}
}
type uintSet64 uint64
func ( uintSet64) ( uint) bool { return &(1<<) > 0 }
func ( *uintSet64) ( uint) { * |= 1 << }
type uintSet struct {
lo uintSet64
hi []uintSet64
}
func ( *uintSet) ( uint) bool {
if < 64 {
return .lo.has()
} else {
-= 64
, := int(/64), %64
return < len(.hi) && .hi[].has()
}
}
func ( *uintSet) ( uint) bool {
if < 64 {
:= .lo.has()
.lo.set()
return !
} else {
-= 64
, := int(/64), %64
if >= len(.hi) {
.hi = append(.hi, make([]uintSet64, +1-len(.hi))...)
.hi = .hi[:cap(.hi)]
}
:= .hi[].has()
.hi[].set()
return !
}
}