package jsoniter

import (
	
	
	
)

// ValueType the type for JSON element
type ValueType int

const (
	// InvalidValue invalid JSON element
	InvalidValue ValueType = iota
	// StringValue JSON element "string"
	StringValue
	// NumberValue JSON element 100 or 0.10
	NumberValue
	// NilValue JSON element null
	NilValue
	// BoolValue JSON element true or false
	BoolValue
	// ArrayValue JSON element []
	ArrayValue
	// ObjectValue JSON element {}
	ObjectValue
)

var hexDigits []byte
var valueTypes []ValueType

func init() {
	hexDigits = make([]byte, 256)
	for  := 0;  < len(hexDigits); ++ {
		hexDigits[] = 255
	}
	for  := '0';  <= '9'; ++ {
		hexDigits[] = byte( - '0')
	}
	for  := 'a';  <= 'f'; ++ {
		hexDigits[] = byte(( - 'a') + 10)
	}
	for  := 'A';  <= 'F'; ++ {
		hexDigits[] = byte(( - 'A') + 10)
	}
	valueTypes = make([]ValueType, 256)
	for  := 0;  < len(valueTypes); ++ {
		valueTypes[] = InvalidValue
	}
	valueTypes['"'] = StringValue
	valueTypes['-'] = NumberValue
	valueTypes['0'] = NumberValue
	valueTypes['1'] = NumberValue
	valueTypes['2'] = NumberValue
	valueTypes['3'] = NumberValue
	valueTypes['4'] = NumberValue
	valueTypes['5'] = NumberValue
	valueTypes['6'] = NumberValue
	valueTypes['7'] = NumberValue
	valueTypes['8'] = NumberValue
	valueTypes['9'] = NumberValue
	valueTypes['t'] = BoolValue
	valueTypes['f'] = BoolValue
	valueTypes['n'] = NilValue
	valueTypes['['] = ArrayValue
	valueTypes['{'] = ObjectValue
}

// Iterator is a io.Reader like object, with JSON specific read functions.
// Error is not returned as return value, but stored as Error member on this iterator instance.
type Iterator struct {
	cfg              *frozenConfig
	reader           io.Reader
	buf              []byte
	head             int
	tail             int
	depth            int
	captureStartedAt int
	captured         []byte
	Error            error
	Attachment       interface{} // open for customized decoder
}

// NewIterator creates an empty Iterator instance
func ( API) *Iterator {
	return &Iterator{
		cfg:    .(*frozenConfig),
		reader: nil,
		buf:    nil,
		head:   0,
		tail:   0,
		depth:  0,
	}
}

// Parse creates an Iterator instance from io.Reader
func ( API,  io.Reader,  int) *Iterator {
	return &Iterator{
		cfg:    .(*frozenConfig),
		reader: ,
		buf:    make([]byte, ),
		head:   0,
		tail:   0,
		depth:  0,
	}
}

// ParseBytes creates an Iterator instance from byte array
func ( API,  []byte) *Iterator {
	return &Iterator{
		cfg:    .(*frozenConfig),
		reader: nil,
		buf:    ,
		head:   0,
		tail:   len(),
		depth:  0,
	}
}

// ParseString creates an Iterator instance from string
func ( API,  string) *Iterator {
	return ParseBytes(, []byte())
}

// Pool returns a pool can provide more iterator with same configuration
func ( *Iterator) () IteratorPool {
	return .cfg
}

// Reset reuse iterator instance by specifying another reader
func ( *Iterator) ( io.Reader) *Iterator {
	.reader = 
	.head = 0
	.tail = 0
	.depth = 0
	return 
}

// ResetBytes reuse iterator instance by specifying another byte array as input
func ( *Iterator) ( []byte) *Iterator {
	.reader = nil
	.buf = 
	.head = 0
	.tail = len()
	.depth = 0
	return 
}

// WhatIsNext gets ValueType of relatively next json element
func ( *Iterator) () ValueType {
	 := valueTypes[.nextToken()]
	.unreadByte()
	return 
}

func ( *Iterator) () bool {
	for  := .head;  < .tail; ++ {
		 := .buf[]
		switch  {
		case ' ', '\n', '\t', '\r':
			continue
		}
		.head = 
		return false
	}
	return true
}

func ( *Iterator) () bool {
	 := .nextToken()
	if  == ',' {
		return false
	}
	if  == '}' {
		return true
	}
	.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{}))
	return true
}

func ( *Iterator) () byte {
	// a variation of skip whitespaces, returning the next non-whitespace token
	for {
		for  := .head;  < .tail; ++ {
			 := .buf[]
			switch  {
			case ' ', '\n', '\t', '\r':
				continue
			}
			.head =  + 1
			return 
		}
		if !.loadMore() {
			return 0
		}
	}
}

// ReportError record a error in iterator instance with current position.
func ( *Iterator) ( string,  string) {
	if .Error != nil {
		if .Error != io.EOF {
			return
		}
	}
	 := .head - 10
	if  < 0 {
		 = 0
	}
	 := .head + 10
	if  > .tail {
		 = .tail
	}
	 := string(.buf[:])
	 := .head - 50
	if  < 0 {
		 = 0
	}
	 := .head + 50
	if  > .tail {
		 = .tail
	}
	 := string(.buf[:])
	.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
		, , .head-, , )
}

// CurrentBuffer gets current buffer as string for debugging purpose
func ( *Iterator) () string {
	 := .head - 10
	if  < 0 {
		 = 0
	}
	return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", .head,
		string(.buf[:.head]), string(.buf[0:.tail]))
}

func ( *Iterator) () ( byte) {
	if .head == .tail {
		if .loadMore() {
			 = .buf[.head]
			.head++
			return 
		}
		return 0
	}
	 = .buf[.head]
	.head++
	return 
}

func ( *Iterator) () bool {
	if .reader == nil {
		if .Error == nil {
			.head = .tail
			.Error = io.EOF
		}
		return false
	}
	if .captured != nil {
		.captured = append(.captured,
			.buf[.captureStartedAt:.tail]...)
		.captureStartedAt = 0
	}
	for {
		,  := .reader.Read(.buf)
		if  == 0 {
			if  != nil {
				if .Error == nil {
					.Error = 
				}
				return false
			}
		} else {
			.head = 0
			.tail = 
			return true
		}
	}
}

func ( *Iterator) () {
	if .Error != nil {
		return
	}
	.head--
	return
}

// Read read the next JSON element as generic interface{}.
func ( *Iterator) () interface{} {
	 := .WhatIsNext()
	switch  {
	case StringValue:
		return .ReadString()
	case NumberValue:
		if .cfg.configBeforeFrozen.UseNumber {
			return json.Number(.readNumberAsString())
		}
		return .ReadFloat64()
	case NilValue:
		.skipFourBytes('n', 'u', 'l', 'l')
		return nil
	case BoolValue:
		return .ReadBool()
	case ArrayValue:
		 := []interface{}{}
		.ReadArrayCB(func( *Iterator) bool {
			var  interface{}
			.ReadVal(&)
			 = append(, )
			return true
		})
		return 
	case ObjectValue:
		 := map[string]interface{}{}
		.ReadMapCB(func( *Iterator,  string) bool {
			var  interface{}
			.ReadVal(&)
			[] = 
			return true
		})
		return 
	default:
		.ReportError("Read", fmt.Sprintf("unexpected value type: %v", ))
		return nil
	}
}

// limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9
const maxDepth = 10000

func ( *Iterator) () ( bool) {
	.depth++
	if .depth <= maxDepth {
		return true
	}
	.ReportError("incrementDepth", "exceeded max depth")
	return false
}

func ( *Iterator) () ( bool) {
	.depth--
	if .depth >= 0 {
		return true
	}
	.ReportError("decrementDepth", "unexpected negative nesting")
	return false
}