Source file src/encoding/json/jsontext/decode.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build goexperiment.jsonv2
     6  
     7  package jsontext
     8  
     9  import (
    10  	"bytes"
    11  	"errors"
    12  	"io"
    13  
    14  	"encoding/json/internal/jsonflags"
    15  	"encoding/json/internal/jsonopts"
    16  	"encoding/json/internal/jsonwire"
    17  )
    18  
    19  // NOTE: The logic for decoding is complicated by the fact that reading from
    20  // an io.Reader into a temporary buffer means that the buffer may contain a
    21  // truncated portion of some valid input, requiring the need to fetch more data.
    22  //
    23  // This file is structured in the following way:
    24  //
    25  //   - consumeXXX functions parse an exact JSON token from a []byte.
    26  //     If the buffer appears truncated, then it returns io.ErrUnexpectedEOF.
    27  //     The consumeSimpleXXX functions are so named because they only handle
    28  //     a subset of the grammar for the JSON token being parsed.
    29  //     They do not handle the full grammar to keep these functions inlinable.
    30  //
    31  //   - Decoder.consumeXXX methods parse the next JSON token from Decoder.buf,
    32  //     automatically fetching more input if necessary. These methods take
    33  //     a position relative to the start of Decoder.buf as an argument and
    34  //     return the end of the consumed JSON token as a position,
    35  //     also relative to the start of Decoder.buf.
    36  //
    37  //   - In the event of an I/O errors or state machine violations,
    38  //     the implementation avoids mutating the state of Decoder
    39  //     (aside from the book-keeping needed to implement Decoder.fetch).
    40  //     For this reason, only Decoder.ReadToken and Decoder.ReadValue are
    41  //     responsible for updated Decoder.prevStart and Decoder.prevEnd.
    42  //
    43  //   - For performance, much of the implementation uses the pattern of calling
    44  //     the inlinable consumeXXX functions first, and if more work is necessary,
    45  //     then it calls the slower Decoder.consumeXXX methods.
    46  //     TODO: Revisit this pattern if the Go compiler provides finer control
    47  //     over exactly which calls are inlined or not.
    48  
    49  // Decoder is a streaming decoder for raw JSON tokens and values.
    50  // It is used to read a stream of top-level JSON values,
    51  // each separated by optional whitespace characters.
    52  //
    53  // [Decoder.ReadToken] and [Decoder.ReadValue] calls may be interleaved.
    54  // For example, the following JSON value:
    55  //
    56  //	{"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}}
    57  //
    58  // can be parsed with the following calls (ignoring errors for brevity):
    59  //
    60  //	d.ReadToken() // {
    61  //	d.ReadToken() // "name"
    62  //	d.ReadToken() // "value"
    63  //	d.ReadValue() // "array"
    64  //	d.ReadToken() // [
    65  //	d.ReadToken() // null
    66  //	d.ReadToken() // false
    67  //	d.ReadValue() // true
    68  //	d.ReadToken() // 3.14159
    69  //	d.ReadToken() // ]
    70  //	d.ReadValue() // "object"
    71  //	d.ReadValue() // {"k":"v"}
    72  //	d.ReadToken() // }
    73  //
    74  // The above is one of many possible sequence of calls and
    75  // may not represent the most sensible method to call for any given token/value.
    76  // For example, it is probably more common to call [Decoder.ReadToken] to obtain a
    77  // string token for object names.
    78  type Decoder struct {
    79  	s decoderState
    80  }
    81  
    82  // decoderState is the low-level state of Decoder.
    83  // It has exported fields and method for use by the "json" package.
    84  type decoderState struct {
    85  	state
    86  	decodeBuffer
    87  	jsonopts.Struct
    88  
    89  	StringCache *[256]string // only used when unmarshaling; identical to json.stringCache
    90  }
    91  
    92  // decodeBuffer is a buffer split into 4 segments:
    93  //
    94  //   - buf[0:prevEnd]         // already read portion of the buffer
    95  //   - buf[prevStart:prevEnd] // previously read value
    96  //   - buf[prevEnd:len(buf)]  // unread portion of the buffer
    97  //   - buf[len(buf):cap(buf)] // unused portion of the buffer
    98  //
    99  // Invariants:
   100  //
   101  //	0 ≤ prevStart ≤ prevEnd ≤ len(buf) ≤ cap(buf)
   102  type decodeBuffer struct {
   103  	peekPos int   // non-zero if valid offset into buf for start of next token
   104  	peekErr error // implies peekPos is -1
   105  
   106  	buf       []byte // may alias rd if it is a bytes.Buffer
   107  	prevStart int
   108  	prevEnd   int
   109  
   110  	// baseOffset is added to prevStart and prevEnd to obtain
   111  	// the absolute offset relative to the start of io.Reader stream.
   112  	baseOffset int64
   113  
   114  	rd io.Reader
   115  }
   116  
   117  // NewDecoder constructs a new streaming decoder reading from r.
   118  //
   119  // If r is a [bytes.Buffer], then the decoder parses directly from the buffer
   120  // without first copying the contents to an intermediate buffer.
   121  // Additional writes to the buffer must not occur while the decoder is in use.
   122  func NewDecoder(r io.Reader, opts ...Options) *Decoder {
   123  	d := new(Decoder)
   124  	d.Reset(r, opts...)
   125  	return d
   126  }
   127  
   128  // Reset resets a decoder such that it is reading afresh from r and
   129  // configured with the provided options. Reset must not be called on an
   130  // a Decoder passed to the [encoding/json/v2.UnmarshalerFrom.UnmarshalJSONFrom] method
   131  // or the [encoding/json/v2.UnmarshalFromFunc] function.
   132  func (d *Decoder) Reset(r io.Reader, opts ...Options) {
   133  	switch {
   134  	case d == nil:
   135  		panic("jsontext: invalid nil Decoder")
   136  	case r == nil:
   137  		panic("jsontext: invalid nil io.Reader")
   138  	case d.s.Flags.Get(jsonflags.WithinArshalCall):
   139  		panic("jsontext: cannot reset Decoder passed to json.UnmarshalerFrom")
   140  	}
   141  	d.s.reset(nil, r, opts...)
   142  }
   143  
   144  func (d *decoderState) reset(b []byte, r io.Reader, opts ...Options) {
   145  	d.state.reset()
   146  	d.decodeBuffer = decodeBuffer{buf: b, rd: r}
   147  	opts2 := jsonopts.Struct{} // avoid mutating d.Struct in case it is part of opts
   148  	opts2.Join(opts...)
   149  	d.Struct = opts2
   150  }
   151  
   152  // Options returns the options used to construct the encoder and
   153  // may additionally contain semantic options passed to a
   154  // [encoding/json/v2.UnmarshalDecode] call.
   155  //
   156  // If operating within
   157  // a [encoding/json/v2.UnmarshalerFrom.UnmarshalJSONFrom] method call or
   158  // a [encoding/json/v2.UnmarshalFromFunc] function call,
   159  // then the returned options are only valid within the call.
   160  func (d *Decoder) Options() Options {
   161  	return &d.s.Struct
   162  }
   163  
   164  var errBufferWriteAfterNext = errors.New("invalid bytes.Buffer.Write call after calling bytes.Buffer.Next")
   165  
   166  // fetch reads at least 1 byte from the underlying io.Reader.
   167  // It returns io.ErrUnexpectedEOF if zero bytes were read and io.EOF was seen.
   168  func (d *decoderState) fetch() error {
   169  	if d.rd == nil {
   170  		return io.ErrUnexpectedEOF
   171  	}
   172  
   173  	// Inform objectNameStack that we are about to fetch new buffer content.
   174  	d.Names.copyQuotedBuffer(d.buf)
   175  
   176  	// Specialize bytes.Buffer for better performance.
   177  	if bb, ok := d.rd.(*bytes.Buffer); ok {
   178  		switch {
   179  		case bb.Len() == 0:
   180  			return io.ErrUnexpectedEOF
   181  		case len(d.buf) == 0:
   182  			d.buf = bb.Next(bb.Len()) // "read" all data in the buffer
   183  			return nil
   184  		default:
   185  			// This only occurs if a partially filled bytes.Buffer was provided
   186  			// and more data is written to it while Decoder is reading from it.
   187  			// This practice will lead to data corruption since future writes
   188  			// may overwrite the contents of the current buffer.
   189  			//
   190  			// The user is trying to use a bytes.Buffer as a pipe,
   191  			// but a bytes.Buffer is poor implementation of a pipe,
   192  			// the purpose-built io.Pipe should be used instead.
   193  			return &ioError{action: "read", err: errBufferWriteAfterNext}
   194  		}
   195  	}
   196  
   197  	// Allocate initial buffer if empty.
   198  	if cap(d.buf) == 0 {
   199  		d.buf = make([]byte, 0, 64)
   200  	}
   201  
   202  	// Check whether to grow the buffer.
   203  	const maxBufferSize = 4 << 10
   204  	const growthSizeFactor = 2 // higher value is faster
   205  	const growthRateFactor = 2 // higher value is slower
   206  	// By default, grow if below the maximum buffer size.
   207  	grow := cap(d.buf) <= maxBufferSize/growthSizeFactor
   208  	// Growing can be expensive, so only grow
   209  	// if a sufficient number of bytes have been processed.
   210  	grow = grow && int64(cap(d.buf)) < d.previousOffsetEnd()/growthRateFactor
   211  	// If prevStart==0, then fetch was called in order to fetch more data
   212  	// to finish consuming a large JSON value contiguously.
   213  	// Grow if less than 25% of the remaining capacity is available.
   214  	// Note that this may cause the input buffer to exceed maxBufferSize.
   215  	grow = grow || (d.prevStart == 0 && len(d.buf) >= 3*cap(d.buf)/4)
   216  
   217  	if grow {
   218  		// Allocate a new buffer and copy the contents of the old buffer over.
   219  		// TODO: Provide a hard limit on the maximum internal buffer size?
   220  		buf := make([]byte, 0, cap(d.buf)*growthSizeFactor)
   221  		d.buf = append(buf, d.buf[d.prevStart:]...)
   222  	} else {
   223  		// Move unread portion of the data to the front.
   224  		n := copy(d.buf[:cap(d.buf)], d.buf[d.prevStart:])
   225  		d.buf = d.buf[:n]
   226  	}
   227  	d.baseOffset += int64(d.prevStart)
   228  	d.prevEnd -= d.prevStart
   229  	d.prevStart = 0
   230  
   231  	// Read more data into the internal buffer.
   232  	for {
   233  		n, err := d.rd.Read(d.buf[len(d.buf):cap(d.buf)])
   234  		switch {
   235  		case n > 0:
   236  			d.buf = d.buf[:len(d.buf)+n]
   237  			return nil // ignore errors if any bytes are read
   238  		case err == io.EOF:
   239  			return io.ErrUnexpectedEOF
   240  		case err != nil:
   241  			return &ioError{action: "read", err: err}
   242  		default:
   243  			continue // Read returned (0, nil)
   244  		}
   245  	}
   246  }
   247  
   248  const invalidateBufferByte = '#' // invalid starting character for JSON grammar
   249  
   250  // invalidatePreviousRead invalidates buffers returned by Peek and Read calls
   251  // so that the first byte is an invalid character.
   252  // This Hyrum-proofs the API against faulty application code that assumes
   253  // values returned by ReadValue remain valid past subsequent Read calls.
   254  func (d *decodeBuffer) invalidatePreviousRead() {
   255  	// Avoid mutating the buffer if d.rd is nil which implies that d.buf
   256  	// is provided by the user code and may not expect mutations.
   257  	isBytesBuffer := func(r io.Reader) bool {
   258  		_, ok := r.(*bytes.Buffer)
   259  		return ok
   260  	}
   261  	if d.rd != nil && !isBytesBuffer(d.rd) && d.prevStart < d.prevEnd && uint(d.prevStart) < uint(len(d.buf)) {
   262  		d.buf[d.prevStart] = invalidateBufferByte
   263  		d.prevStart = d.prevEnd
   264  	}
   265  }
   266  
   267  // needMore reports whether there are no more unread bytes.
   268  func (d *decodeBuffer) needMore(pos int) bool {
   269  	// NOTE: The arguments and logic are kept simple to keep this inlinable.
   270  	return pos == len(d.buf)
   271  }
   272  
   273  func (d *decodeBuffer) offsetAt(pos int) int64     { return d.baseOffset + int64(pos) }
   274  func (d *decodeBuffer) previousOffsetStart() int64 { return d.baseOffset + int64(d.prevStart) }
   275  func (d *decodeBuffer) previousOffsetEnd() int64   { return d.baseOffset + int64(d.prevEnd) }
   276  func (d *decodeBuffer) previousBuffer() []byte     { return d.buf[d.prevStart:d.prevEnd] }
   277  func (d *decodeBuffer) unreadBuffer() []byte       { return d.buf[d.prevEnd:len(d.buf)] }
   278  
   279  // PreviousTokenOrValue returns the previously read token or value
   280  // unless it has been invalidated by a call to PeekKind.
   281  // If a token is just a delimiter, then this returns a 1-byte buffer.
   282  // This method is used for error reporting at the semantic layer.
   283  func (d *decodeBuffer) PreviousTokenOrValue() []byte {
   284  	b := d.previousBuffer()
   285  	// If peek was called, then the previous token or buffer is invalidated.
   286  	if d.peekPos > 0 || len(b) > 0 && b[0] == invalidateBufferByte {
   287  		return nil
   288  	}
   289  	// ReadToken does not preserve the buffer for null, bools, or delimiters.
   290  	// Manually re-construct that buffer.
   291  	if len(b) == 0 {
   292  		b = d.buf[:d.prevEnd] // entirety of the previous buffer
   293  		for _, tok := range []string{"null", "false", "true", "{", "}", "[", "]"} {
   294  			if len(b) >= len(tok) && string(b[len(b)-len(tok):]) == tok {
   295  				return b[len(b)-len(tok):]
   296  			}
   297  		}
   298  	}
   299  	return b
   300  }
   301  
   302  // PeekKind retrieves the next token kind, but does not advance the read offset.
   303  //
   304  // It returns 0 if an error occurs. Any such error is cached until
   305  // the next read call and it is the caller's responsibility to eventually
   306  // follow up a PeekKind call with a read call.
   307  func (d *Decoder) PeekKind() Kind {
   308  	return d.s.PeekKind()
   309  }
   310  func (d *decoderState) PeekKind() Kind {
   311  	// Check whether we have a cached peek result.
   312  	if d.peekPos > 0 {
   313  		return Kind(d.buf[d.peekPos]).normalize()
   314  	}
   315  
   316  	var err error
   317  	d.invalidatePreviousRead()
   318  	pos := d.prevEnd
   319  
   320  	// Consume leading whitespace.
   321  	pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   322  	if d.needMore(pos) {
   323  		if pos, err = d.consumeWhitespace(pos); err != nil {
   324  			if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 {
   325  				err = io.EOF // EOF possibly if no Tokens present after top-level value
   326  			}
   327  			d.peekPos, d.peekErr = -1, wrapSyntacticError(d, err, pos, 0)
   328  			return invalidKind
   329  		}
   330  	}
   331  
   332  	// Consume colon or comma.
   333  	var delim byte
   334  	if c := d.buf[pos]; c == ':' || c == ',' {
   335  		delim = c
   336  		pos += 1
   337  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   338  		if d.needMore(pos) {
   339  			if pos, err = d.consumeWhitespace(pos); err != nil {
   340  				err = wrapSyntacticError(d, err, pos, 0)
   341  				d.peekPos, d.peekErr = -1, d.checkDelimBeforeIOError(delim, err)
   342  				return invalidKind
   343  			}
   344  		}
   345  	}
   346  	next := Kind(d.buf[pos]).normalize()
   347  	if d.Tokens.needDelim(next) != delim {
   348  		d.peekPos, d.peekErr = -1, d.checkDelim(delim, next)
   349  		return invalidKind
   350  	}
   351  
   352  	// This may set peekPos to zero, which is indistinguishable from
   353  	// the uninitialized state. While a small hit to performance, it is correct
   354  	// since ReadValue and ReadToken will disregard the cached result and
   355  	// recompute the next kind.
   356  	d.peekPos, d.peekErr = pos, nil
   357  	return next
   358  }
   359  
   360  // checkDelimBeforeIOError checks whether the delim is even valid
   361  // before returning an IO error, which occurs after the delim.
   362  func (d *decoderState) checkDelimBeforeIOError(delim byte, err error) error {
   363  	// Since an IO error occurred, we do not know what the next kind is.
   364  	// However, knowing the next kind is necessary to validate
   365  	// whether the current delim is at least potentially valid.
   366  	// Since a JSON string is always valid as the next token,
   367  	// conservatively assume that is the next kind for validation.
   368  	const next = Kind('"')
   369  	if d.Tokens.needDelim(next) != delim {
   370  		err = d.checkDelim(delim, next)
   371  	}
   372  	return err
   373  }
   374  
   375  // CountNextDelimWhitespace counts the number of upcoming bytes of
   376  // delimiter or whitespace characters.
   377  // This method is used for error reporting at the semantic layer.
   378  func (d *decoderState) CountNextDelimWhitespace() int {
   379  	d.PeekKind() // populate unreadBuffer
   380  	return len(d.unreadBuffer()) - len(bytes.TrimLeft(d.unreadBuffer(), ",: \n\r\t"))
   381  }
   382  
   383  // checkDelim checks whether delim is valid for the given next kind.
   384  func (d *decoderState) checkDelim(delim byte, next Kind) error {
   385  	where := "at start of value"
   386  	switch d.Tokens.needDelim(next) {
   387  	case delim:
   388  		return nil
   389  	case ':':
   390  		where = "after object name (expecting ':')"
   391  	case ',':
   392  		if d.Tokens.Last.isObject() {
   393  			where = "after object value (expecting ',' or '}')"
   394  		} else {
   395  			where = "after array element (expecting ',' or ']')"
   396  		}
   397  	}
   398  	pos := d.prevEnd // restore position to right after leading whitespace
   399  	pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   400  	err := jsonwire.NewInvalidCharacterError(d.buf[pos:], where)
   401  	return wrapSyntacticError(d, err, pos, 0)
   402  }
   403  
   404  // SkipValue is semantically equivalent to calling [Decoder.ReadValue] and discarding
   405  // the result except that memory is not wasted trying to hold the entire result.
   406  func (d *Decoder) SkipValue() error {
   407  	return d.s.SkipValue()
   408  }
   409  func (d *decoderState) SkipValue() error {
   410  	switch d.PeekKind() {
   411  	case '{', '[':
   412  		// For JSON objects and arrays, keep skipping all tokens
   413  		// until the depth matches the starting depth.
   414  		depth := d.Tokens.Depth()
   415  		for {
   416  			if _, err := d.ReadToken(); err != nil {
   417  				return err
   418  			}
   419  			if depth >= d.Tokens.Depth() {
   420  				return nil
   421  			}
   422  		}
   423  	default:
   424  		// Trying to skip a value when the next token is a '}' or ']'
   425  		// will result in an error being returned here.
   426  		var flags jsonwire.ValueFlags
   427  		if _, err := d.ReadValue(&flags); err != nil {
   428  			return err
   429  		}
   430  		return nil
   431  	}
   432  }
   433  
   434  // SkipValueRemainder skips the remainder of a value
   435  // after reading a '{' or '[' token.
   436  func (d *decoderState) SkipValueRemainder() error {
   437  	if d.Tokens.Depth()-1 > 0 && d.Tokens.Last.Length() == 0 {
   438  		for n := d.Tokens.Depth(); d.Tokens.Depth() >= n; {
   439  			if _, err := d.ReadToken(); err != nil {
   440  				return err
   441  			}
   442  		}
   443  	}
   444  	return nil
   445  }
   446  
   447  // SkipUntil skips all tokens until the state machine
   448  // is at or past the specified depth and length.
   449  func (d *decoderState) SkipUntil(depth int, length int64) error {
   450  	for d.Tokens.Depth() > depth || (d.Tokens.Depth() == depth && d.Tokens.Last.Length() < length) {
   451  		if _, err := d.ReadToken(); err != nil {
   452  			return err
   453  		}
   454  	}
   455  	return nil
   456  }
   457  
   458  // ReadToken reads the next [Token], advancing the read offset.
   459  // The returned token is only valid until the next Peek, Read, or Skip call.
   460  // It returns [io.EOF] if there are no more tokens.
   461  func (d *Decoder) ReadToken() (Token, error) {
   462  	return d.s.ReadToken()
   463  }
   464  func (d *decoderState) ReadToken() (Token, error) {
   465  	// Determine the next kind.
   466  	var err error
   467  	var next Kind
   468  	pos := d.peekPos
   469  	if pos != 0 {
   470  		// Use cached peek result.
   471  		if d.peekErr != nil {
   472  			err := d.peekErr
   473  			d.peekPos, d.peekErr = 0, nil // possibly a transient I/O error
   474  			return Token{}, err
   475  		}
   476  		next = Kind(d.buf[pos]).normalize()
   477  		d.peekPos = 0 // reset cache
   478  	} else {
   479  		d.invalidatePreviousRead()
   480  		pos = d.prevEnd
   481  
   482  		// Consume leading whitespace.
   483  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   484  		if d.needMore(pos) {
   485  			if pos, err = d.consumeWhitespace(pos); err != nil {
   486  				if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 {
   487  					err = io.EOF // EOF possibly if no Tokens present after top-level value
   488  				}
   489  				return Token{}, wrapSyntacticError(d, err, pos, 0)
   490  			}
   491  		}
   492  
   493  		// Consume colon or comma.
   494  		var delim byte
   495  		if c := d.buf[pos]; c == ':' || c == ',' {
   496  			delim = c
   497  			pos += 1
   498  			pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   499  			if d.needMore(pos) {
   500  				if pos, err = d.consumeWhitespace(pos); err != nil {
   501  					err = wrapSyntacticError(d, err, pos, 0)
   502  					return Token{}, d.checkDelimBeforeIOError(delim, err)
   503  				}
   504  			}
   505  		}
   506  		next = Kind(d.buf[pos]).normalize()
   507  		if d.Tokens.needDelim(next) != delim {
   508  			return Token{}, d.checkDelim(delim, next)
   509  		}
   510  	}
   511  
   512  	// Handle the next token.
   513  	var n int
   514  	switch next {
   515  	case 'n':
   516  		if jsonwire.ConsumeNull(d.buf[pos:]) == 0 {
   517  			pos, err = d.consumeLiteral(pos, "null")
   518  			if err != nil {
   519  				return Token{}, wrapSyntacticError(d, err, pos, +1)
   520  			}
   521  		} else {
   522  			pos += len("null")
   523  		}
   524  		if err = d.Tokens.appendLiteral(); err != nil {
   525  			return Token{}, wrapSyntacticError(d, err, pos-len("null"), +1) // report position at start of literal
   526  		}
   527  		d.prevStart, d.prevEnd = pos, pos
   528  		return Null, nil
   529  
   530  	case 'f':
   531  		if jsonwire.ConsumeFalse(d.buf[pos:]) == 0 {
   532  			pos, err = d.consumeLiteral(pos, "false")
   533  			if err != nil {
   534  				return Token{}, wrapSyntacticError(d, err, pos, +1)
   535  			}
   536  		} else {
   537  			pos += len("false")
   538  		}
   539  		if err = d.Tokens.appendLiteral(); err != nil {
   540  			return Token{}, wrapSyntacticError(d, err, pos-len("false"), +1) // report position at start of literal
   541  		}
   542  		d.prevStart, d.prevEnd = pos, pos
   543  		return False, nil
   544  
   545  	case 't':
   546  		if jsonwire.ConsumeTrue(d.buf[pos:]) == 0 {
   547  			pos, err = d.consumeLiteral(pos, "true")
   548  			if err != nil {
   549  				return Token{}, wrapSyntacticError(d, err, pos, +1)
   550  			}
   551  		} else {
   552  			pos += len("true")
   553  		}
   554  		if err = d.Tokens.appendLiteral(); err != nil {
   555  			return Token{}, wrapSyntacticError(d, err, pos-len("true"), +1) // report position at start of literal
   556  		}
   557  		d.prevStart, d.prevEnd = pos, pos
   558  		return True, nil
   559  
   560  	case '"':
   561  		var flags jsonwire.ValueFlags // TODO: Preserve this in Token?
   562  		if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 {
   563  			oldAbsPos := d.baseOffset + int64(pos)
   564  			pos, err = d.consumeString(&flags, pos)
   565  			newAbsPos := d.baseOffset + int64(pos)
   566  			n = int(newAbsPos - oldAbsPos)
   567  			if err != nil {
   568  				return Token{}, wrapSyntacticError(d, err, pos, +1)
   569  			}
   570  		} else {
   571  			pos += n
   572  		}
   573  		if d.Tokens.Last.NeedObjectName() {
   574  			if !d.Flags.Get(jsonflags.AllowDuplicateNames) {
   575  				if !d.Tokens.Last.isValidNamespace() {
   576  					return Token{}, wrapSyntacticError(d, errInvalidNamespace, pos-n, +1)
   577  				}
   578  				if d.Tokens.Last.isActiveNamespace() && !d.Namespaces.Last().insertQuoted(d.buf[pos-n:pos], flags.IsVerbatim()) {
   579  					err = wrapWithObjectName(ErrDuplicateName, d.buf[pos-n:pos])
   580  					return Token{}, wrapSyntacticError(d, err, pos-n, +1) // report position at start of string
   581  				}
   582  			}
   583  			d.Names.ReplaceLastQuotedOffset(pos - n) // only replace if insertQuoted succeeds
   584  		}
   585  		if err = d.Tokens.appendString(); err != nil {
   586  			return Token{}, wrapSyntacticError(d, err, pos-n, +1) // report position at start of string
   587  		}
   588  		d.prevStart, d.prevEnd = pos-n, pos
   589  		return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil
   590  
   591  	case '0':
   592  		// NOTE: Since JSON numbers are not self-terminating,
   593  		// we need to make sure that the next byte is not part of a number.
   594  		if n = jsonwire.ConsumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) {
   595  			oldAbsPos := d.baseOffset + int64(pos)
   596  			pos, err = d.consumeNumber(pos)
   597  			newAbsPos := d.baseOffset + int64(pos)
   598  			n = int(newAbsPos - oldAbsPos)
   599  			if err != nil {
   600  				return Token{}, wrapSyntacticError(d, err, pos, +1)
   601  			}
   602  		} else {
   603  			pos += n
   604  		}
   605  		if err = d.Tokens.appendNumber(); err != nil {
   606  			return Token{}, wrapSyntacticError(d, err, pos-n, +1) // report position at start of number
   607  		}
   608  		d.prevStart, d.prevEnd = pos-n, pos
   609  		return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil
   610  
   611  	case '{':
   612  		if err = d.Tokens.pushObject(); err != nil {
   613  			return Token{}, wrapSyntacticError(d, err, pos, +1)
   614  		}
   615  		d.Names.push()
   616  		if !d.Flags.Get(jsonflags.AllowDuplicateNames) {
   617  			d.Namespaces.push()
   618  		}
   619  		pos += 1
   620  		d.prevStart, d.prevEnd = pos, pos
   621  		return BeginObject, nil
   622  
   623  	case '}':
   624  		if err = d.Tokens.popObject(); err != nil {
   625  			return Token{}, wrapSyntacticError(d, err, pos, +1)
   626  		}
   627  		d.Names.pop()
   628  		if !d.Flags.Get(jsonflags.AllowDuplicateNames) {
   629  			d.Namespaces.pop()
   630  		}
   631  		pos += 1
   632  		d.prevStart, d.prevEnd = pos, pos
   633  		return EndObject, nil
   634  
   635  	case '[':
   636  		if err = d.Tokens.pushArray(); err != nil {
   637  			return Token{}, wrapSyntacticError(d, err, pos, +1)
   638  		}
   639  		pos += 1
   640  		d.prevStart, d.prevEnd = pos, pos
   641  		return BeginArray, nil
   642  
   643  	case ']':
   644  		if err = d.Tokens.popArray(); err != nil {
   645  			return Token{}, wrapSyntacticError(d, err, pos, +1)
   646  		}
   647  		pos += 1
   648  		d.prevStart, d.prevEnd = pos, pos
   649  		return EndArray, nil
   650  
   651  	default:
   652  		err = jsonwire.NewInvalidCharacterError(d.buf[pos:], "at start of value")
   653  		return Token{}, wrapSyntacticError(d, err, pos, +1)
   654  	}
   655  }
   656  
   657  // ReadValue returns the next raw JSON value, advancing the read offset.
   658  // The value is stripped of any leading or trailing whitespace and
   659  // contains the exact bytes of the input, which may contain invalid UTF-8
   660  // if [AllowInvalidUTF8] is specified.
   661  //
   662  // The returned value is only valid until the next Peek, Read, or Skip call and
   663  // may not be mutated while the Decoder remains in use.
   664  // If the decoder is currently at the end token for an object or array,
   665  // then it reports a [SyntacticError] and the internal state remains unchanged.
   666  // It returns [io.EOF] if there are no more values.
   667  func (d *Decoder) ReadValue() (Value, error) {
   668  	var flags jsonwire.ValueFlags
   669  	return d.s.ReadValue(&flags)
   670  }
   671  func (d *decoderState) ReadValue(flags *jsonwire.ValueFlags) (Value, error) {
   672  	// Determine the next kind.
   673  	var err error
   674  	var next Kind
   675  	pos := d.peekPos
   676  	if pos != 0 {
   677  		// Use cached peek result.
   678  		if d.peekErr != nil {
   679  			err := d.peekErr
   680  			d.peekPos, d.peekErr = 0, nil // possibly a transient I/O error
   681  			return nil, err
   682  		}
   683  		next = Kind(d.buf[pos]).normalize()
   684  		d.peekPos = 0 // reset cache
   685  	} else {
   686  		d.invalidatePreviousRead()
   687  		pos = d.prevEnd
   688  
   689  		// Consume leading whitespace.
   690  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   691  		if d.needMore(pos) {
   692  			if pos, err = d.consumeWhitespace(pos); err != nil {
   693  				if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 {
   694  					err = io.EOF // EOF possibly if no Tokens present after top-level value
   695  				}
   696  				return nil, wrapSyntacticError(d, err, pos, 0)
   697  			}
   698  		}
   699  
   700  		// Consume colon or comma.
   701  		var delim byte
   702  		if c := d.buf[pos]; c == ':' || c == ',' {
   703  			delim = c
   704  			pos += 1
   705  			pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   706  			if d.needMore(pos) {
   707  				if pos, err = d.consumeWhitespace(pos); err != nil {
   708  					err = wrapSyntacticError(d, err, pos, 0)
   709  					return nil, d.checkDelimBeforeIOError(delim, err)
   710  				}
   711  			}
   712  		}
   713  		next = Kind(d.buf[pos]).normalize()
   714  		if d.Tokens.needDelim(next) != delim {
   715  			return nil, d.checkDelim(delim, next)
   716  		}
   717  	}
   718  
   719  	// Handle the next value.
   720  	oldAbsPos := d.baseOffset + int64(pos)
   721  	pos, err = d.consumeValue(flags, pos, d.Tokens.Depth())
   722  	newAbsPos := d.baseOffset + int64(pos)
   723  	n := int(newAbsPos - oldAbsPos)
   724  	if err != nil {
   725  		return nil, wrapSyntacticError(d, err, pos, +1)
   726  	}
   727  	switch next {
   728  	case 'n', 't', 'f':
   729  		err = d.Tokens.appendLiteral()
   730  	case '"':
   731  		if d.Tokens.Last.NeedObjectName() {
   732  			if !d.Flags.Get(jsonflags.AllowDuplicateNames) {
   733  				if !d.Tokens.Last.isValidNamespace() {
   734  					err = errInvalidNamespace
   735  					break
   736  				}
   737  				if d.Tokens.Last.isActiveNamespace() && !d.Namespaces.Last().insertQuoted(d.buf[pos-n:pos], flags.IsVerbatim()) {
   738  					err = wrapWithObjectName(ErrDuplicateName, d.buf[pos-n:pos])
   739  					break
   740  				}
   741  			}
   742  			d.Names.ReplaceLastQuotedOffset(pos - n) // only replace if insertQuoted succeeds
   743  		}
   744  		err = d.Tokens.appendString()
   745  	case '0':
   746  		err = d.Tokens.appendNumber()
   747  	case '{':
   748  		if err = d.Tokens.pushObject(); err != nil {
   749  			break
   750  		}
   751  		if err = d.Tokens.popObject(); err != nil {
   752  			panic("BUG: popObject should never fail immediately after pushObject: " + err.Error())
   753  		}
   754  	case '[':
   755  		if err = d.Tokens.pushArray(); err != nil {
   756  			break
   757  		}
   758  		if err = d.Tokens.popArray(); err != nil {
   759  			panic("BUG: popArray should never fail immediately after pushArray: " + err.Error())
   760  		}
   761  	}
   762  	if err != nil {
   763  		return nil, wrapSyntacticError(d, err, pos-n, +1) // report position at start of value
   764  	}
   765  	d.prevEnd = pos
   766  	d.prevStart = pos - n
   767  	return d.buf[pos-n : pos : pos], nil
   768  }
   769  
   770  // CheckNextValue checks whether the next value is syntactically valid,
   771  // but does not advance the read offset.
   772  func (d *decoderState) CheckNextValue() error {
   773  	d.PeekKind() // populates d.peekPos and d.peekErr
   774  	pos, err := d.peekPos, d.peekErr
   775  	d.peekPos, d.peekErr = 0, nil
   776  	if err != nil {
   777  		return err
   778  	}
   779  
   780  	var flags jsonwire.ValueFlags
   781  	if pos, err := d.consumeValue(&flags, pos, d.Tokens.Depth()); err != nil {
   782  		return wrapSyntacticError(d, err, pos, +1)
   783  	}
   784  	return nil
   785  }
   786  
   787  // CheckEOF verifies that the input has no more data.
   788  func (d *decoderState) CheckEOF() error {
   789  	switch pos, err := d.consumeWhitespace(d.prevEnd); err {
   790  	case nil:
   791  		err := jsonwire.NewInvalidCharacterError(d.buf[pos:], "after top-level value")
   792  		return wrapSyntacticError(d, err, pos, 0)
   793  	case io.ErrUnexpectedEOF:
   794  		return nil
   795  	default:
   796  		return err
   797  	}
   798  }
   799  
   800  // consumeWhitespace consumes all whitespace starting at d.buf[pos:].
   801  // It returns the new position in d.buf immediately after the last whitespace.
   802  // If it returns nil, there is guaranteed to at least be one unread byte.
   803  //
   804  // The following pattern is common in this implementation:
   805  //
   806  //	pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   807  //	if d.needMore(pos) {
   808  //		if pos, err = d.consumeWhitespace(pos); err != nil {
   809  //			return ...
   810  //		}
   811  //	}
   812  //
   813  // It is difficult to simplify this without sacrificing performance since
   814  // consumeWhitespace must be inlined. The body of the if statement is
   815  // executed only in rare situations where we need to fetch more data.
   816  // Since fetching may return an error, we also need to check the error.
   817  func (d *decoderState) consumeWhitespace(pos int) (newPos int, err error) {
   818  	for {
   819  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   820  		if d.needMore(pos) {
   821  			absPos := d.baseOffset + int64(pos)
   822  			err = d.fetch() // will mutate d.buf and invalidate pos
   823  			pos = int(absPos - d.baseOffset)
   824  			if err != nil {
   825  				return pos, err
   826  			}
   827  			continue
   828  		}
   829  		return pos, nil
   830  	}
   831  }
   832  
   833  // consumeValue consumes a single JSON value starting at d.buf[pos:].
   834  // It returns the new position in d.buf immediately after the value.
   835  func (d *decoderState) consumeValue(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) {
   836  	for {
   837  		var n int
   838  		var err error
   839  		switch next := Kind(d.buf[pos]).normalize(); next {
   840  		case 'n':
   841  			if n = jsonwire.ConsumeNull(d.buf[pos:]); n == 0 {
   842  				n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "null")
   843  			}
   844  		case 'f':
   845  			if n = jsonwire.ConsumeFalse(d.buf[pos:]); n == 0 {
   846  				n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "false")
   847  			}
   848  		case 't':
   849  			if n = jsonwire.ConsumeTrue(d.buf[pos:]); n == 0 {
   850  				n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "true")
   851  			}
   852  		case '"':
   853  			if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 {
   854  				return d.consumeString(flags, pos)
   855  			}
   856  		case '0':
   857  			// NOTE: Since JSON numbers are not self-terminating,
   858  			// we need to make sure that the next byte is not part of a number.
   859  			if n = jsonwire.ConsumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) {
   860  				return d.consumeNumber(pos)
   861  			}
   862  		case '{':
   863  			return d.consumeObject(flags, pos, depth)
   864  		case '[':
   865  			return d.consumeArray(flags, pos, depth)
   866  		default:
   867  			if (d.Tokens.Last.isObject() && next == ']') || (d.Tokens.Last.isArray() && next == '}') {
   868  				return pos, errMismatchDelim
   869  			}
   870  			return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "at start of value")
   871  		}
   872  		if err == io.ErrUnexpectedEOF {
   873  			absPos := d.baseOffset + int64(pos)
   874  			err = d.fetch() // will mutate d.buf and invalidate pos
   875  			pos = int(absPos - d.baseOffset)
   876  			if err != nil {
   877  				return pos + n, err
   878  			}
   879  			continue
   880  		}
   881  		return pos + n, err
   882  	}
   883  }
   884  
   885  // consumeLiteral consumes a single JSON literal starting at d.buf[pos:].
   886  // It returns the new position in d.buf immediately after the literal.
   887  func (d *decoderState) consumeLiteral(pos int, lit string) (newPos int, err error) {
   888  	for {
   889  		n, err := jsonwire.ConsumeLiteral(d.buf[pos:], lit)
   890  		if err == io.ErrUnexpectedEOF {
   891  			absPos := d.baseOffset + int64(pos)
   892  			err = d.fetch() // will mutate d.buf and invalidate pos
   893  			pos = int(absPos - d.baseOffset)
   894  			if err != nil {
   895  				return pos + n, err
   896  			}
   897  			continue
   898  		}
   899  		return pos + n, err
   900  	}
   901  }
   902  
   903  // consumeString consumes a single JSON string starting at d.buf[pos:].
   904  // It returns the new position in d.buf immediately after the string.
   905  func (d *decoderState) consumeString(flags *jsonwire.ValueFlags, pos int) (newPos int, err error) {
   906  	var n int
   907  	for {
   908  		n, err = jsonwire.ConsumeStringResumable(flags, d.buf[pos:], n, !d.Flags.Get(jsonflags.AllowInvalidUTF8))
   909  		if err == io.ErrUnexpectedEOF {
   910  			absPos := d.baseOffset + int64(pos)
   911  			err = d.fetch() // will mutate d.buf and invalidate pos
   912  			pos = int(absPos - d.baseOffset)
   913  			if err != nil {
   914  				return pos + n, err
   915  			}
   916  			continue
   917  		}
   918  		return pos + n, err
   919  	}
   920  }
   921  
   922  // consumeNumber consumes a single JSON number starting at d.buf[pos:].
   923  // It returns the new position in d.buf immediately after the number.
   924  func (d *decoderState) consumeNumber(pos int) (newPos int, err error) {
   925  	var n int
   926  	var state jsonwire.ConsumeNumberState
   927  	for {
   928  		n, state, err = jsonwire.ConsumeNumberResumable(d.buf[pos:], n, state)
   929  		// NOTE: Since JSON numbers are not self-terminating,
   930  		// we need to make sure that the next byte is not part of a number.
   931  		if err == io.ErrUnexpectedEOF || d.needMore(pos+n) {
   932  			mayTerminate := err == nil
   933  			absPos := d.baseOffset + int64(pos)
   934  			err = d.fetch() // will mutate d.buf and invalidate pos
   935  			pos = int(absPos - d.baseOffset)
   936  			if err != nil {
   937  				if mayTerminate && err == io.ErrUnexpectedEOF {
   938  					return pos + n, nil
   939  				}
   940  				return pos, err
   941  			}
   942  			continue
   943  		}
   944  		return pos + n, err
   945  	}
   946  }
   947  
   948  // consumeObject consumes a single JSON object starting at d.buf[pos:].
   949  // It returns the new position in d.buf immediately after the object.
   950  func (d *decoderState) consumeObject(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) {
   951  	var n int
   952  	var names *objectNamespace
   953  	if !d.Flags.Get(jsonflags.AllowDuplicateNames) {
   954  		d.Namespaces.push()
   955  		defer d.Namespaces.pop()
   956  		names = d.Namespaces.Last()
   957  	}
   958  
   959  	// Handle before start.
   960  	if uint(pos) >= uint(len(d.buf)) || d.buf[pos] != '{' {
   961  		panic("BUG: consumeObject must be called with a buffer that starts with '{'")
   962  	} else if depth == maxNestingDepth+1 {
   963  		return pos, errMaxDepth
   964  	}
   965  	pos++
   966  
   967  	// Handle after start.
   968  	pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   969  	if d.needMore(pos) {
   970  		if pos, err = d.consumeWhitespace(pos); err != nil {
   971  			return pos, err
   972  		}
   973  	}
   974  	if d.buf[pos] == '}' {
   975  		pos++
   976  		return pos, nil
   977  	}
   978  
   979  	depth++
   980  	for {
   981  		// Handle before name.
   982  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
   983  		if d.needMore(pos) {
   984  			if pos, err = d.consumeWhitespace(pos); err != nil {
   985  				return pos, err
   986  			}
   987  		}
   988  		var flags2 jsonwire.ValueFlags
   989  		if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 {
   990  			oldAbsPos := d.baseOffset + int64(pos)
   991  			pos, err = d.consumeString(&flags2, pos)
   992  			newAbsPos := d.baseOffset + int64(pos)
   993  			n = int(newAbsPos - oldAbsPos)
   994  			flags.Join(flags2)
   995  			if err != nil {
   996  				return pos, err
   997  			}
   998  		} else {
   999  			pos += n
  1000  		}
  1001  		quotedName := d.buf[pos-n : pos]
  1002  		if !d.Flags.Get(jsonflags.AllowDuplicateNames) && !names.insertQuoted(quotedName, flags2.IsVerbatim()) {
  1003  			return pos - n, wrapWithObjectName(ErrDuplicateName, quotedName)
  1004  		}
  1005  
  1006  		// Handle after name.
  1007  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
  1008  		if d.needMore(pos) {
  1009  			if pos, err = d.consumeWhitespace(pos); err != nil {
  1010  				return pos, wrapWithObjectName(err, quotedName)
  1011  			}
  1012  		}
  1013  		if d.buf[pos] != ':' {
  1014  			err := jsonwire.NewInvalidCharacterError(d.buf[pos:], "after object name (expecting ':')")
  1015  			return pos, wrapWithObjectName(err, quotedName)
  1016  		}
  1017  		pos++
  1018  
  1019  		// Handle before value.
  1020  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
  1021  		if d.needMore(pos) {
  1022  			if pos, err = d.consumeWhitespace(pos); err != nil {
  1023  				return pos, wrapWithObjectName(err, quotedName)
  1024  			}
  1025  		}
  1026  		pos, err = d.consumeValue(flags, pos, depth)
  1027  		if err != nil {
  1028  			return pos, wrapWithObjectName(err, quotedName)
  1029  		}
  1030  
  1031  		// Handle after value.
  1032  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
  1033  		if d.needMore(pos) {
  1034  			if pos, err = d.consumeWhitespace(pos); err != nil {
  1035  				return pos, err
  1036  			}
  1037  		}
  1038  		switch d.buf[pos] {
  1039  		case ',':
  1040  			pos++
  1041  			continue
  1042  		case '}':
  1043  			pos++
  1044  			return pos, nil
  1045  		default:
  1046  			return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "after object value (expecting ',' or '}')")
  1047  		}
  1048  	}
  1049  }
  1050  
  1051  // consumeArray consumes a single JSON array starting at d.buf[pos:].
  1052  // It returns the new position in d.buf immediately after the array.
  1053  func (d *decoderState) consumeArray(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) {
  1054  	// Handle before start.
  1055  	if uint(pos) >= uint(len(d.buf)) || d.buf[pos] != '[' {
  1056  		panic("BUG: consumeArray must be called with a buffer that starts with '['")
  1057  	} else if depth == maxNestingDepth+1 {
  1058  		return pos, errMaxDepth
  1059  	}
  1060  	pos++
  1061  
  1062  	// Handle after start.
  1063  	pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
  1064  	if d.needMore(pos) {
  1065  		if pos, err = d.consumeWhitespace(pos); err != nil {
  1066  			return pos, err
  1067  		}
  1068  	}
  1069  	if d.buf[pos] == ']' {
  1070  		pos++
  1071  		return pos, nil
  1072  	}
  1073  
  1074  	var idx int64
  1075  	depth++
  1076  	for {
  1077  		// Handle before value.
  1078  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
  1079  		if d.needMore(pos) {
  1080  			if pos, err = d.consumeWhitespace(pos); err != nil {
  1081  				return pos, err
  1082  			}
  1083  		}
  1084  		pos, err = d.consumeValue(flags, pos, depth)
  1085  		if err != nil {
  1086  			return pos, wrapWithArrayIndex(err, idx)
  1087  		}
  1088  
  1089  		// Handle after value.
  1090  		pos += jsonwire.ConsumeWhitespace(d.buf[pos:])
  1091  		if d.needMore(pos) {
  1092  			if pos, err = d.consumeWhitespace(pos); err != nil {
  1093  				return pos, err
  1094  			}
  1095  		}
  1096  		switch d.buf[pos] {
  1097  		case ',':
  1098  			pos++
  1099  			idx++
  1100  			continue
  1101  		case ']':
  1102  			pos++
  1103  			return pos, nil
  1104  		default:
  1105  			return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "after array element (expecting ',' or ']')")
  1106  		}
  1107  	}
  1108  }
  1109  
  1110  // InputOffset returns the current input byte offset. It gives the location
  1111  // of the next byte immediately after the most recently returned token or value.
  1112  // The number of bytes actually read from the underlying [io.Reader] may be more
  1113  // than this offset due to internal buffering effects.
  1114  func (d *Decoder) InputOffset() int64 {
  1115  	return d.s.previousOffsetEnd()
  1116  }
  1117  
  1118  // UnreadBuffer returns the data remaining in the unread buffer,
  1119  // which may contain zero or more bytes.
  1120  // The returned buffer must not be mutated while Decoder continues to be used.
  1121  // The buffer contents are valid until the next Peek, Read, or Skip call.
  1122  func (d *Decoder) UnreadBuffer() []byte {
  1123  	return d.s.unreadBuffer()
  1124  }
  1125  
  1126  // StackDepth returns the depth of the state machine for read JSON data.
  1127  // Each level on the stack represents a nested JSON object or array.
  1128  // It is incremented whenever an [BeginObject] or [BeginArray] token is encountered
  1129  // and decremented whenever an [EndObject] or [EndArray] token is encountered.
  1130  // The depth is zero-indexed, where zero represents the top-level JSON value.
  1131  func (d *Decoder) StackDepth() int {
  1132  	// NOTE: Keep in sync with Encoder.StackDepth.
  1133  	return d.s.Tokens.Depth() - 1
  1134  }
  1135  
  1136  // StackIndex returns information about the specified stack level.
  1137  // It must be a number between 0 and [Decoder.StackDepth], inclusive.
  1138  // For each level, it reports the kind:
  1139  //
  1140  //   - 0 for a level of zero,
  1141  //   - '{' for a level representing a JSON object, and
  1142  //   - '[' for a level representing a JSON array.
  1143  //
  1144  // It also reports the length of that JSON object or array.
  1145  // Each name and value in a JSON object is counted separately,
  1146  // so the effective number of members would be half the length.
  1147  // A complete JSON object must have an even length.
  1148  func (d *Decoder) StackIndex(i int) (Kind, int64) {
  1149  	// NOTE: Keep in sync with Encoder.StackIndex.
  1150  	switch s := d.s.Tokens.index(i); {
  1151  	case i > 0 && s.isObject():
  1152  		return '{', s.Length()
  1153  	case i > 0 && s.isArray():
  1154  		return '[', s.Length()
  1155  	default:
  1156  		return 0, s.Length()
  1157  	}
  1158  }
  1159  
  1160  // StackPointer returns a JSON Pointer (RFC 6901) to the most recently read value.
  1161  func (d *Decoder) StackPointer() Pointer {
  1162  	return Pointer(d.s.AppendStackPointer(nil, -1))
  1163  }
  1164  
  1165  func (d *decoderState) AppendStackPointer(b []byte, where int) []byte {
  1166  	d.Names.copyQuotedBuffer(d.buf)
  1167  	return d.state.appendStackPointer(b, where)
  1168  }
  1169  

View as plain text