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.
Decoder is a token-based JSON decoder.
lastCall is last method called, either readCall or peekCall. Initial value is readCall.
lastToken contains the last read token.
lastErr contains the last read 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.
orig is used in reporting line and column.
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.
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 &