package jsoniter

import (
	
	
	
	
	
	
	
)

// Any generic object representation.
// The lazy json implementation holds []byte and parse lazily.
type Any interface {
	LastError() error
	ValueType() ValueType
	MustBeValid() Any
	ToBool() bool
	ToInt() int
	ToInt32() int32
	ToInt64() int64
	ToUint() uint
	ToUint32() uint32
	ToUint64() uint64
	ToFloat32() float32
	ToFloat64() float64
	ToString() string
	ToVal(val interface{})
	Get(path ...interface{}) Any
	Size() int
	Keys() []string
	GetInterface() interface{}
	WriteTo(stream *Stream)
}

type baseAny struct{}

func ( *baseAny) ( ...interface{}) Any {
	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", )}
}

func ( *baseAny) () int {
	return 0
}

func ( *baseAny) () []string {
	return []string{}
}

func ( *baseAny) ( interface{}) {
	panic("not implemented")
}

// WrapInt32 turn int32 into Any interface
func ( int32) Any {
	return &int32Any{baseAny{}, }
}

// WrapInt64 turn int64 into Any interface
func ( int64) Any {
	return &int64Any{baseAny{}, }
}

// WrapUint32 turn uint32 into Any interface
func ( uint32) Any {
	return &uint32Any{baseAny{}, }
}

// WrapUint64 turn uint64 into Any interface
func ( uint64) Any {
	return &uint64Any{baseAny{}, }
}

// WrapFloat64 turn float64 into Any interface
func ( float64) Any {
	return &floatAny{baseAny{}, }
}

// WrapString turn string into Any interface
func ( string) Any {
	return &stringAny{baseAny{}, }
}

// Wrap turn a go object into Any interface
func ( interface{}) Any {
	if  == nil {
		return &nilAny{}
	}
	,  := .(Any)
	if  {
		return 
	}
	 := reflect2.TypeOf()
	switch .Kind() {
	case reflect.Slice:
		return wrapArray()
	case reflect.Struct:
		return wrapStruct()
	case reflect.Map:
		return wrapMap()
	case reflect.String:
		return WrapString(.(string))
	case reflect.Int:
		if strconv.IntSize == 32 {
			return WrapInt32(int32(.(int)))
		}
		return WrapInt64(int64(.(int)))
	case reflect.Int8:
		return WrapInt32(int32(.(int8)))
	case reflect.Int16:
		return WrapInt32(int32(.(int16)))
	case reflect.Int32:
		return WrapInt32(.(int32))
	case reflect.Int64:
		return WrapInt64(.(int64))
	case reflect.Uint:
		if strconv.IntSize == 32 {
			return WrapUint32(uint32(.(uint)))
		}
		return WrapUint64(uint64(.(uint)))
	case reflect.Uintptr:
		if ptrSize == 32 {
			return WrapUint32(uint32(.(uintptr)))
		}
		return WrapUint64(uint64(.(uintptr)))
	case reflect.Uint8:
		return WrapUint32(uint32(.(uint8)))
	case reflect.Uint16:
		return WrapUint32(uint32(.(uint16)))
	case reflect.Uint32:
		return WrapUint32(uint32(.(uint32)))
	case reflect.Uint64:
		return WrapUint64(.(uint64))
	case reflect.Float32:
		return WrapFloat64(float64(.(float32)))
	case reflect.Float64:
		return WrapFloat64(.(float64))
	case reflect.Bool:
		if .(bool) == true {
			return &trueAny{}
		}
		return &falseAny{}
	}
	return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", )}
}

// ReadAny read next JSON element as an Any object. It is a better json.RawMessage.
func ( *Iterator) () Any {
	return .readAny()
}

func ( *Iterator) () Any {
	 := .nextToken()
	switch  {
	case '"':
		.unreadByte()
		return &stringAny{baseAny{}, .ReadString()}
	case 'n':
		.skipThreeBytes('u', 'l', 'l') // null
		return &nilAny{}
	case 't':
		.skipThreeBytes('r', 'u', 'e') // true
		return &trueAny{}
	case 'f':
		.skipFourBytes('a', 'l', 's', 'e') // false
		return &falseAny{}
	case '{':
		return .readObjectAny()
	case '[':
		return .readArrayAny()
	case '-':
		return .readNumberAny(false)
	case 0:
		return &invalidAny{baseAny{}, errors.New("input is empty")}
	default:
		return .readNumberAny(true)
	}
}

func ( *Iterator) ( bool) Any {
	.startCapture(.head - 1)
	.skipNumber()
	 := .stopCapture()
	return &numberLazyAny{baseAny{}, .cfg, , nil}
}

func ( *Iterator) () Any {
	.startCapture(.head - 1)
	.skipObject()
	 := .stopCapture()
	return &objectLazyAny{baseAny{}, .cfg, , nil}
}

func ( *Iterator) () Any {
	.startCapture(.head - 1)
	.skipArray()
	 := .stopCapture()
	return &arrayLazyAny{baseAny{}, .cfg, , nil}
}

func locateObjectField( *Iterator,  string) []byte {
	var  []byte
	.ReadObjectCB(func( *Iterator,  string) bool {
		if  ==  {
			 = .SkipAndReturnBytes()
			return false
		}
		.Skip()
		return true
	})
	return 
}

func locateArrayElement( *Iterator,  int) []byte {
	var  []byte
	 := 0
	.ReadArrayCB(func( *Iterator) bool {
		if  ==  {
			 = .SkipAndReturnBytes()
			return false
		}
		.Skip()
		++
		return true
	})
	return 
}

func locatePath( *Iterator,  []interface{}) Any {
	for ,  := range  {
		switch pathKey := .(type) {
		case string:
			 := locateObjectField(, )
			if  == nil {
				return newInvalidAny([:])
			}
			.ResetBytes()
		case int:
			 := locateArrayElement(, )
			if  == nil {
				return newInvalidAny([:])
			}
			.ResetBytes()
		case int32:
			if '*' ==  {
				return .readAny().Get([:]...)
			}
			return newInvalidAny([:])
		default:
			return newInvalidAny([:])
		}
	}
	if .Error != nil && .Error != io.EOF {
		return &invalidAny{baseAny{}, .Error}
	}
	return .readAny()
}

var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem()

func createDecoderOfAny( *ctx,  reflect2.Type) ValDecoder {
	if  == anyType {
		return &directAnyCodec{}
	}
	if .Implements(anyType) {
		return &anyCodec{
			valType: ,
		}
	}
	return nil
}

func createEncoderOfAny( *ctx,  reflect2.Type) ValEncoder {
	if  == anyType {
		return &directAnyCodec{}
	}
	if .Implements(anyType) {
		return &anyCodec{
			valType: ,
		}
	}
	return nil
}

type anyCodec struct {
	valType reflect2.Type
}

func ( *anyCodec) ( unsafe.Pointer,  *Iterator) {
	panic("not implemented")
}

func ( *anyCodec) ( unsafe.Pointer,  *Stream) {
	 := .valType.UnsafeIndirect()
	 := .(Any)
	.WriteTo()
}

func ( *anyCodec) ( unsafe.Pointer) bool {
	 := .valType.UnsafeIndirect()
	 := .(Any)
	return .Size() == 0
}

type directAnyCodec struct {
}

func ( *directAnyCodec) ( unsafe.Pointer,  *Iterator) {
	*(*Any)() = .readAny()
}

func ( *directAnyCodec) ( unsafe.Pointer,  *Stream) {
	 := *(*Any)()
	if  == nil {
		.WriteNil()
		return
	}
	.WriteTo()
}

func ( *directAnyCodec) ( unsafe.Pointer) bool {
	 := *(*Any)()
	return .Size() == 0
}