package decoder

import (
	
	
	
	
	

	
	
)

type interfaceDecoder struct {
	typ           *runtime.Type
	structName    string
	fieldName     string
	sliceDecoder  *sliceDecoder
	mapDecoder    *mapDecoder
	floatDecoder  *floatDecoder
	numberDecoder *numberDecoder
	stringDecoder *stringDecoder
}

func newEmptyInterfaceDecoder(,  string) *interfaceDecoder {
	 := &interfaceDecoder{
		typ:        emptyInterfaceType,
		structName: ,
		fieldName:  ,
		floatDecoder: newFloatDecoder(, , func( unsafe.Pointer,  float64) {
			*(*interface{})() = 
		}),
		numberDecoder: newNumberDecoder(, , func( unsafe.Pointer,  json.Number) {
			*(*interface{})() = 
		}),
		stringDecoder: newStringDecoder(, ),
	}
	.sliceDecoder = newSliceDecoder(
		,
		emptyInterfaceType,
		emptyInterfaceType.Size(),
		, ,
	)
	.mapDecoder = newMapDecoder(
		interfaceMapType,
		stringType,
		.stringDecoder,
		interfaceMapType.Elem(),
		,
		,
		,
	)
	return 
}

func newInterfaceDecoder( *runtime.Type, ,  string) *interfaceDecoder {
	 := newEmptyInterfaceDecoder(, )
	 := newStringDecoder(, )
	return &interfaceDecoder{
		typ:        ,
		structName: ,
		fieldName:  ,
		sliceDecoder: newSliceDecoder(
			,
			emptyInterfaceType,
			emptyInterfaceType.Size(),
			, ,
		),
		mapDecoder: newMapDecoder(
			interfaceMapType,
			stringType,
			,
			interfaceMapType.Elem(),
			,
			,
			,
		),
		floatDecoder: newFloatDecoder(, , func( unsafe.Pointer,  float64) {
			*(*interface{})() = 
		}),
		numberDecoder: newNumberDecoder(, , func( unsafe.Pointer,  json.Number) {
			*(*interface{})() = 
		}),
		stringDecoder: ,
	}
}

func ( *interfaceDecoder) ( *Stream) Decoder {
	if .UseNumber {
		return .numberDecoder
	}
	return .floatDecoder
}

var (
	emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem())
	EmptyInterfaceType = emptyInterfaceType
	interfaceMapType   = runtime.Type2RType(
		reflect.TypeOf((*map[string]interface{})(nil)).Elem(),
	)
	stringType = runtime.Type2RType(
		reflect.TypeOf(""),
	)
)

func decodeStreamUnmarshaler( *Stream,  int64,  json.Unmarshaler) error {
	 := .cursor
	if  := .skipValue();  != nil {
		return 
	}
	 := .buf[:.cursor]
	 := make([]byte, len())
	copy(, )

	if  := .UnmarshalJSON();  != nil {
		return 
	}
	return nil
}

func decodeStreamUnmarshalerContext( *Stream,  int64,  unmarshalerContext) error {
	 := .cursor
	if  := .skipValue();  != nil {
		return 
	}
	 := .buf[:.cursor]
	 := make([]byte, len())
	copy(, )

	if  := .UnmarshalJSON(.Option.Context, );  != nil {
		return 
	}
	return nil
}

func decodeUnmarshaler( []byte, ,  int64,  json.Unmarshaler) (int64, error) {
	 = skipWhiteSpace(, )
	 := 
	,  := skipValue(, , )
	if  != nil {
		return 0, 
	}
	 := [:]
	 := make([]byte, len())
	copy(, )

	if  := .UnmarshalJSON();  != nil {
		return 0, 
	}
	return , nil
}

func decodeUnmarshalerContext( *RuntimeContext,  []byte, ,  int64,  unmarshalerContext) (int64, error) {
	 = skipWhiteSpace(, )
	 := 
	,  := skipValue(, , )
	if  != nil {
		return 0, 
	}
	 := [:]
	 := make([]byte, len())
	copy(, )

	if  := .UnmarshalJSON(.Option.Context, );  != nil {
		return 0, 
	}
	return , nil
}

func decodeStreamTextUnmarshaler( *Stream,  int64,  encoding.TextUnmarshaler,  unsafe.Pointer) error {
	 := .cursor
	if  := .skipValue();  != nil {
		return 
	}
	 := .buf[:.cursor]
	if bytes.Equal(, nullbytes) {
		*(*unsafe.Pointer)() = nil
		return nil
	}

	 := make([]byte, len())
	copy(, )

	if  := .UnmarshalText();  != nil {
		return 
	}
	return nil
}

func decodeTextUnmarshaler( []byte, ,  int64,  encoding.TextUnmarshaler,  unsafe.Pointer) (int64, error) {
	 = skipWhiteSpace(, )
	 := 
	,  := skipValue(, , )
	if  != nil {
		return 0, 
	}
	 := [:]
	if bytes.Equal(, nullbytes) {
		*(*unsafe.Pointer)() = nil
		return , nil
	}
	if ,  := unquoteBytes();  {
		 = 
	}
	if  := .UnmarshalText();  != nil {
		return 0, 
	}
	return , nil
}

func ( *interfaceDecoder) ( *Stream,  int64,  unsafe.Pointer) error {
	 := .skipWhiteSpace()
	for {
		switch  {
		case '{':
			var  map[string]interface{}
			 := unsafe.Pointer(&)
			if  := .mapDecoder.DecodeStream(, , );  != nil {
				return 
			}
			*(*interface{})() = 
			return nil
		case '[':
			var  []interface{}
			 := unsafe.Pointer(&)
			if  := .sliceDecoder.DecodeStream(, , );  != nil {
				return 
			}
			*(*interface{})() = 
			return nil
		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			return .numDecoder().DecodeStream(, , )
		case '"':
			.cursor++
			 := .cursor
			for {
				switch .char() {
				case '\\':
					if ,  := decodeEscapeString(, nil);  != nil {
						return 
					}
				case '"':
					 := .buf[:.cursor]
					.cursor++
					*(*interface{})() = string()
					return nil
				case nul:
					if .read() {
						continue
					}
					return errors.ErrUnexpectedEndOfJSON("string", .totalOffset())
				}
				.cursor++
			}
		case 't':
			if  := trueBytes();  != nil {
				return 
			}
			**(**interface{})(unsafe.Pointer(&)) = true
			return nil
		case 'f':
			if  := falseBytes();  != nil {
				return 
			}
			**(**interface{})(unsafe.Pointer(&)) = false
			return nil
		case 'n':
			if  := nullBytes();  != nil {
				return 
			}
			*(*interface{})() = nil
			return nil
		case nul:
			if .read() {
				 = .char()
				continue
			}
		}
		break
	}
	return errors.ErrInvalidBeginningOfValue(, .totalOffset())
}

type emptyInterface struct {
	typ *runtime.Type
	ptr unsafe.Pointer
}

func ( *interfaceDecoder) ( *Stream,  int64,  unsafe.Pointer) error {
	 := *(*interface{})(unsafe.Pointer(&emptyInterface{
		typ: .typ,
		ptr: ,
	}))
	 := reflect.ValueOf()
	if .NumMethod() > 0 && .CanInterface() {
		if ,  := .Interface().(unmarshalerContext);  {
			return decodeStreamUnmarshalerContext(, , )
		}
		if ,  := .Interface().(json.Unmarshaler);  {
			return decodeStreamUnmarshaler(, , )
		}
		if ,  := .Interface().(encoding.TextUnmarshaler);  {
			return decodeStreamTextUnmarshaler(, , , )
		}
		if .skipWhiteSpace() == 'n' {
			if  := nullBytes();  != nil {
				return 
			}
			*(*interface{})() = nil
			return nil
		}
		return .errUnmarshalType(.Type(), .totalOffset())
	}
	 := .Interface()
	 := (*emptyInterface)(unsafe.Pointer(&))
	 := .typ
	if .ptr == nil || .typ ==  ||  == nil {
		// concrete type is empty interface
		return .decodeStreamEmptyInterface(, , )
	}
	if .Kind() == reflect.Ptr && .Elem() == .typ || .Kind() != reflect.Ptr {
		return .decodeStreamEmptyInterface(, , )
	}
	if .skipWhiteSpace() == 'n' {
		if  := nullBytes();  != nil {
			return 
		}
		*(*interface{})() = nil
		return nil
	}
	,  := CompileToGetDecoder()
	if  != nil {
		return 
	}
	return .DecodeStream(, , .ptr)
}

func ( *interfaceDecoder) ( reflect.Type,  int64) *errors.UnmarshalTypeError {
	return &errors.UnmarshalTypeError{
		Value:  .String(),
		Type:   ,
		Offset: ,
		Struct: .structName,
		Field:  .fieldName,
	}
}

func ( *interfaceDecoder) ( *RuntimeContext, ,  int64,  unsafe.Pointer) (int64, error) {
	 := .Buf
	 := *(*interface{})(unsafe.Pointer(&emptyInterface{
		typ: .typ,
		ptr: ,
	}))
	 := reflect.ValueOf()
	if .NumMethod() > 0 && .CanInterface() {
		if ,  := .Interface().(unmarshalerContext);  {
			return decodeUnmarshalerContext(, , , , )
		}
		if ,  := .Interface().(json.Unmarshaler);  {
			return decodeUnmarshaler(, , , )
		}
		if ,  := .Interface().(encoding.TextUnmarshaler);  {
			return decodeTextUnmarshaler(, , , , )
		}
		 = skipWhiteSpace(, )
		if [] == 'n' {
			if  := validateNull(, );  != nil {
				return 0, 
			}
			 += 4
			**(**interface{})(unsafe.Pointer(&)) = nil
			return , nil
		}
		return 0, .errUnmarshalType(.Type(), )
	}

	 := .Interface()
	 := (*emptyInterface)(unsafe.Pointer(&))
	 := .typ
	if .ptr == nil || .typ ==  ||  == nil {
		// concrete type is empty interface
		return .decodeEmptyInterface(, , , )
	}
	if .Kind() == reflect.Ptr && .Elem() == .typ || .Kind() != reflect.Ptr {
		return .decodeEmptyInterface(, , , )
	}
	 = skipWhiteSpace(, )
	if [] == 'n' {
		if  := validateNull(, );  != nil {
			return 0, 
		}
		 += 4
		**(**interface{})(unsafe.Pointer(&)) = nil
		return , nil
	}
	,  := CompileToGetDecoder()
	if  != nil {
		return 0, 
	}
	return .Decode(, , , .ptr)
}

func ( *interfaceDecoder) ( *RuntimeContext, ,  int64,  unsafe.Pointer) (int64, error) {
	 := .Buf
	 = skipWhiteSpace(, )
	switch [] {
	case '{':
		var  map[string]interface{}
		 := unsafe.Pointer(&)
		,  := .mapDecoder.Decode(, , , )
		if  != nil {
			return 0, 
		}
		**(**interface{})(unsafe.Pointer(&)) = 
		return , nil
	case '[':
		var  []interface{}
		 := unsafe.Pointer(&)
		,  := .sliceDecoder.Decode(, , , )
		if  != nil {
			return 0, 
		}
		**(**interface{})(unsafe.Pointer(&)) = 
		return , nil
	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		return .floatDecoder.Decode(, , , )
	case '"':
		var  string
		 := unsafe.Pointer(&)
		,  := .stringDecoder.Decode(, , , )
		if  != nil {
			return 0, 
		}
		**(**interface{})(unsafe.Pointer(&)) = 
		return , nil
	case 't':
		if  := validateTrue(, );  != nil {
			return 0, 
		}
		 += 4
		**(**interface{})(unsafe.Pointer(&)) = true
		return , nil
	case 'f':
		if  := validateFalse(, );  != nil {
			return 0, 
		}
		 += 5
		**(**interface{})(unsafe.Pointer(&)) = false
		return , nil
	case 'n':
		if  := validateNull(, );  != nil {
			return 0, 
		}
		 += 4
		**(**interface{})(unsafe.Pointer(&)) = nil
		return , nil
	}
	return , errors.ErrInvalidBeginningOfValue([], )
}

func () Decoder {
	 := &interfaceDecoder{
		typ:        emptyInterfaceType,
		structName: "",
		fieldName:  "",
		floatDecoder: newFloatDecoder("", "", func( unsafe.Pointer,  float64) {
			*(*interface{})() = 
		}),
		numberDecoder: newNumberDecoder("", "", func( unsafe.Pointer,  json.Number) {
			*(*interface{})() = 
		}),
		stringDecoder: newStringDecoder("", ""),
	}
	.sliceDecoder = newSliceDecoder(
		,
		emptyInterfaceType,
		emptyInterfaceType.Size(),
		"", "",
	)
	.mapDecoder = newMapDecoder(
		interfaceMapType,
		stringType,
		.stringDecoder,
		interfaceMapType.Elem(),
		,
		"", "",
	)
	return 
}

var (
	truebytes  = []byte("true")
	falsebytes = []byte("false")
)

func ( *interfaceDecoder) ( *RuntimeContext, ,  int64) ([][]byte, int64, error) {
	 := .Buf
	 = skipWhiteSpace(, )
	switch [] {
	case '{':
		return .mapDecoder.DecodePath(, , )
	case '[':
		return .sliceDecoder.DecodePath(, , )
	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		return .floatDecoder.DecodePath(, , )
	case '"':
		return .stringDecoder.DecodePath(, , )
	case 't':
		if  := validateTrue(, );  != nil {
			return nil, 0, 
		}
		 += 4
		return [][]byte{truebytes}, , nil
	case 'f':
		if  := validateFalse(, );  != nil {
			return nil, 0, 
		}
		 += 5
		return [][]byte{falsebytes}, , nil
	case 'n':
		if  := validateNull(, );  != nil {
			return nil, 0, 
		}
		 += 4
		return [][]byte{nullbytes}, , nil
	}
	return nil, , errors.ErrInvalidBeginningOfValue([], )
}