// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package json

import (
	
	
	
	
	

	
)

// call specifies which Decoder method was invoked.
type call uint8

const (
	readCall call = iota
	peekCall
)

const unexpectedFmt = "unexpected token %s"

// ErrUnexpectedEOF means that EOF was encountered in the middle of the input.
var ErrUnexpectedEOF = errors.New("%v", io.ErrUnexpectedEOF)

// Decoder is a token-based JSON decoder.
type Decoder struct {
	// lastCall is last method called, either readCall or peekCall.
	// Initial value is readCall.
	lastCall call

	// lastToken contains the last read token.
	lastToken Token

	// lastErr contains the last read error.
	lastErr error

	// openStack is a stack containing ObjectOpen and ArrayOpen values. The
	// top of stack represents the object or the array the current value is
	// directly located in.
	openStack []Kind

	// orig is used in reporting line and column.
	orig []byte
	// in contains the unconsumed input.
	in []byte
}

// NewDecoder returns a Decoder to read the given []byte.
func ( []byte) *Decoder {
	return &Decoder{orig: , in: }
}

// Peek looks ahead and returns the next token kind without advancing a read.
func ( *Decoder) () (Token, error) {
	defer func() { .lastCall = peekCall }()
	if .lastCall == readCall {
		.lastToken, .lastErr = .Read()
	}
	return .lastToken, .lastErr
}

// Read returns the next JSON token.
// It will return an error if there is no valid token.
func ( *Decoder) () (Token, error) {
	const  = Null | Bool | Number | String

	defer func() { .lastCall = readCall }()
	if .lastCall == peekCall {
		return .lastToken, .lastErr
	}

	,  := .parseNext()
	if  != nil {
		return Token{}, 
	}

	switch .kind {
	case EOF:
		if len(.openStack) != 0 ||
			.lastToken.kind&|ObjectClose|ArrayClose == 0 {
			return Token{}, ErrUnexpectedEOF
		}

	case Null:
		if !.isValueNext() {
			return Token{}, .newSyntaxError(.pos, unexpectedFmt, .RawString())
		}

	case Bool, Number:
		if !.isValueNext() {
			return Token{}, .newSyntaxError(.pos, unexpectedFmt, .RawString())
		}

	case String:
		if .isValueNext() {
			break
		}
		// This string token should only be for a field name.
		if .lastToken.kind&(ObjectOpen|comma) == 0 {
			return Token{}, .newSyntaxError(.pos, unexpectedFmt, .RawString())
		}
		if len(.in) == 0 {
			return Token{}, ErrUnexpectedEOF
		}
		if  := .in[0];  != ':' {
			return Token{}, .newSyntaxError(.currPos(), `unexpected character %s, missing ":" after field name`, string())
		}
		.kind = Name
		.consume(1)

	case ObjectOpen, ArrayOpen:
		if !.isValueNext() {
			return Token{}, .newSyntaxError(.pos, unexpectedFmt, .RawString())
		}
		.openStack = append(.openStack, .kind)

	case ObjectClose:
		if len(.openStack) == 0 ||
			.lastToken.kind == comma ||
			.openStack[len(.openStack)-1] != ObjectOpen {
			return Token{}, .newSyntaxError(.pos, unexpectedFmt, .RawString())
		}
		.openStack = .openStack[:len(.openStack)-1]

	case ArrayClose:
		if len(.openStack) == 0 ||
			.lastToken.kind == comma ||
			.openStack[len(.openStack)-1] != ArrayOpen {
			return Token{}, .newSyntaxError(.pos, unexpectedFmt, .RawString())
		}
		.openStack = .openStack[:len(.openStack)-1]

	case comma:
		if len(.openStack) == 0 ||
			.lastToken.kind&(|ObjectClose|ArrayClose) == 0 {
			return Token{}, .newSyntaxError(.pos, unexpectedFmt, .RawString())
		}
	}

	// Update d.lastToken only after validating token to be in the right sequence.
	.lastToken = 

	if .lastToken.kind == comma {
		return .()
	}
	return , nil
}

// Any sequence that looks like a non-delimiter (for error reporting).
var errRegexp = regexp.MustCompile(`^([-+._a-zA-Z0-9]{1,32}|.)`)

// parseNext parses for the next JSON token. It returns a Token object for
// different types, except for Name. It does not handle whether the next token
// is in a valid sequence or not.
func ( *Decoder) () (Token, error) {
	// Trim leading spaces.
	.consume(0)

	 := .in
	if len() == 0 {
		return .consumeToken(EOF, 0), nil
	}

	switch [0] {
	case 'n':
		if  := matchWithDelim("null", );  != 0 {
			return .consumeToken(Null, ), nil
		}

	case 't':
		if  := matchWithDelim("true", );  != 0 {
			return .consumeBoolToken(true, ), nil
		}

	case 'f':
		if  := matchWithDelim("false", );  != 0 {
			return .consumeBoolToken(false, ), nil
		}

	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		if ,  := parseNumber();  {
			return .consumeToken(Number, ), nil
		}

	case '"':
		, ,  := .parseString()
		if  != nil {
			return Token{}, 
		}
		return .consumeStringToken(, ), nil

	case '{':
		return .consumeToken(ObjectOpen, 1), nil

	case '}':
		return .consumeToken(ObjectClose, 1), nil

	case '[':
		return .consumeToken(ArrayOpen, 1), nil

	case ']':
		return .consumeToken(ArrayClose, 1), nil

	case ',':
		return .consumeToken(comma, 1), nil
	}
	return Token{}, .newSyntaxError(.currPos(), "invalid value %s", errRegexp.Find())
}

// newSyntaxError returns an error with line and column information useful for
// syntax errors.
func ( *Decoder) ( int,  string,  ...interface{}) error {
	 := errors.New(, ...)
	,  := .Position()
	return errors.New("syntax error (line %d:%d): %v", , , )
}

// Position returns line and column number of given index of the original input.
// It will panic if index is out of range.
func ( *Decoder) ( int) ( int,  int) {
	 := .orig[:]
	 = bytes.Count(, []byte("\n")) + 1
	if  := bytes.LastIndexByte(, '\n');  >= 0 {
		 = [+1:]
	}
	 = utf8.RuneCount() + 1 // ignore multi-rune characters
	return , 
}

// currPos returns the current index position of d.in from d.orig.
func ( *Decoder) () int {
	return len(.orig) - len(.in)
}

// matchWithDelim matches s with the input b and verifies that the match
// terminates with a delimiter of some form (e.g., r"[^-+_.a-zA-Z0-9]").
// As a special case, EOF is considered a delimiter. It returns the length of s
// if there is a match, else 0.
func ( string,  []byte) int {
	if !bytes.HasPrefix(, []byte()) {
		return 0
	}

	 := len()
	if  < len() && isNotDelim([]) {
		return 0
	}
	return 
}

// isNotDelim returns true if given byte is a not delimiter character.
func ( byte) bool {
	return ( == '-' ||  == '+' ||  == '.' ||  == '_' ||
		('a' <=  &&  <= 'z') ||
		('A' <=  &&  <= 'Z') ||
		('0' <=  &&  <= '9'))
}

// consume consumes n bytes of input and any subsequent whitespace.
func ( *Decoder) ( int) {
	.in = .in[:]
	for len(.in) > 0 {
		switch .in[0] {
		case ' ', '\n', '\r', '\t':
			.in = .in[1:]
		default:
			return
		}
	}
}

// isValueNext returns true if next type should be a JSON value: Null,
// Number, String or Bool.
func ( *Decoder) () bool {
	if len(.openStack) == 0 {
		return .lastToken.kind == 0
	}

	 := .openStack[len(.openStack)-1]
	switch  {
	case ObjectOpen:
		return .lastToken.kind&Name != 0
	case ArrayOpen:
		return .lastToken.kind&(ArrayOpen|comma) != 0
	}
	panic(fmt.Sprintf(
		"unreachable logic in Decoder.isValueNext, lastToken.kind: %v, openStack: %v",
		.lastToken.kind, ))
}

// consumeToken constructs a Token for given Kind with raw value derived from
// current d.in and given size, and consumes the given size-lenght of it.
func ( *Decoder) ( Kind,  int) Token {
	 := Token{
		kind: ,
		raw:  .in[:],
		pos:  len(.orig) - len(.in),
	}
	.consume()
	return 
}

// consumeBoolToken constructs a Token for a Bool kind with raw value derived from
// current d.in and given size.
func ( *Decoder) ( bool,  int) Token {
	 := Token{
		kind: Bool,
		raw:  .in[:],
		pos:  len(.orig) - len(.in),
		boo:  ,
	}
	.consume()
	return 
}

// consumeStringToken constructs a Token for a String kind with raw value derived
// from current d.in and given size.
func ( *Decoder) ( string,  int) Token {
	 := Token{
		kind: String,
		raw:  .in[:],
		pos:  len(.orig) - len(.in),
		str:  ,
	}
	.consume()
	return 
}

// Clone returns a copy of the Decoder for use in reading ahead the next JSON
// object, array or other values without affecting current Decoder.
func ( *Decoder) () *Decoder {
	 := *
	.openStack = append([]Kind(nil), .openStack...)
	return &
}