#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#endregion

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;

namespace Google.Protobuf
{
    /// <summary>
    /// Simple but strict JSON tokenizer, rigidly following RFC 7159.
    /// </summary>
    /// <remarks>
    /// <para>
    /// This tokenizer is stateful, and only returns "useful" tokens - names, values etc.
    /// It does not create tokens for the separator between names and values, or for the comma
    /// between values. It validates the token stream as it goes - so callers can assume that the
    /// tokens it produces are appropriate. For example, it would never produce "start object, end array."
    /// </para>
    /// <para>Implementation details: the base class handles single token push-back and </para>
    /// <para>Not thread-safe.</para>
    /// </remarks>
    internal abstract class JsonTokenizer
    {
        private JsonToken bufferedToken;

        /// <summary>
        ///  Creates a tokenizer that reads from the given text reader.
        /// </summary>
        internal static JsonTokenizer FromTextReader(TextReader reader)
        {
            return new JsonTextTokenizer(reader);
        }

        /// <summary>
        /// Creates a tokenizer that first replays the given list of tokens, then continues reading
        /// from another tokenizer. Note that if the returned tokenizer is "pushed back", that does not push back
        /// on the continuation tokenizer, or vice versa. Care should be taken when using this method - it was
        /// created for the sake of Any parsing.
        /// </summary>
        internal static JsonTokenizer FromReplayedTokens(IList<JsonToken> tokens, JsonTokenizer continuation)
        {
            return new JsonReplayTokenizer(tokens, continuation);
        }

        /// <summary>
        /// The depth of recursion within JsonParser. This is not directly computable within the tokenizer itself,
        /// as arrays contribute to the recursion depth for ListValue parsing, but not for "normal" message types.
        /// This is maintained (and checked) by <see cref="JsonParser.Merge(IMessage, JsonTokenizer)"/>.
        /// </summary>
        internal int RecursionDepth { get; set; }

        /// <summary>
        /// Returns the depth of the stack, purely in objects (not collections).
        /// Informally, this is the number of remaining unclosed '{' characters we have.
        /// </summary>
        internal int ObjectDepth { get; private set; }

        // TODO: Why do we allow a different token to be pushed back? It might be better to always remember the previous
        // token returned, and allow a parameterless Rewind() method (which could only be called once, just like the current PushBack).
        internal void PushBack(JsonToken token)
        {
            if (bufferedToken != null)
            {
                throw new InvalidOperationException("Can't push back twice");
            }
            bufferedToken = token;
            if (token.Type == JsonToken.TokenType.StartObject)
            {
                ObjectDepth--;
            }
            else if (token.Type == JsonToken.TokenType.EndObject)
            {
                ObjectDepth++;
            }
        }

        /// <summary>
        /// Returns the next JSON token in the stream. An EndDocument token is returned to indicate the end of the stream,
        /// after which point <c>Next()</c> should not be called again.
        /// </summary>
        /// <remarks>This implementation provides single-token buffering, and calls <see cref="NextImpl"/> if there is no buffered token.</remarks>
        /// <returns>The next token in the stream. This is never null.</returns>
        /// <exception cref="InvalidOperationException">This method is called after an EndDocument token has been returned</exception>
        /// <exception cref="InvalidJsonException">The input text does not comply with RFC 7159</exception>
        internal JsonToken Next()
        {
            JsonToken tokenToReturn;
            if (bufferedToken != null)
            {
                tokenToReturn = bufferedToken;
                bufferedToken = null;
            }
            else
            {
                tokenToReturn = NextImpl();
            }
            if (tokenToReturn.Type == JsonToken.TokenType.StartObject)
            {
                ObjectDepth++;
            }
            else if (tokenToReturn.Type == JsonToken.TokenType.EndObject)
            {
                ObjectDepth--;
            }
            return tokenToReturn;
        }

        /// <summary>
        /// Returns the next JSON token in the stream, when requested by the base class. (The <see cref="Next"/> method delegates
        /// to this if it doesn't have a buffered token.)
        /// </summary>
        /// <exception cref="InvalidOperationException">This method is called after an EndDocument token has been returned</exception>
        /// <exception cref="InvalidJsonException">The input text does not comply with RFC 7159</exception>
        protected abstract JsonToken NextImpl();

        /// <summary>
        /// Skips the value we're about to read. This must only be called immediately after reading a property name.
        /// If the value is an object or an array, the complete object/array is skipped.
        /// </summary>
        internal void SkipValue()
        {
            // We'll assume that Next() makes sure that the end objects and end arrays are all valid.
            // All we care about is the total nesting depth we need to close.
            int depth = 0;

            // do/while rather than while loop so that we read at least one token.
            do
            {
                var token = Next();
                switch (token.Type)
                {
                    case JsonToken.TokenType.EndArray:
                    case JsonToken.TokenType.EndObject:
                        depth--;
                        break;
                    case JsonToken.TokenType.StartArray:
                    case JsonToken.TokenType.StartObject:
                        depth++;
                        break;
                }
            } while (depth != 0);
        }

        /// <summary>
        /// Tokenizer which first exhausts a list of tokens, then consults another tokenizer.
        /// </summary>
        private class JsonReplayTokenizer : JsonTokenizer
        {
            private readonly IList<JsonToken> tokens;
            private readonly JsonTokenizer nextTokenizer;
            private int nextTokenIndex;

            internal JsonReplayTokenizer(IList<JsonToken> tokens, JsonTokenizer nextTokenizer)
            {
                this.tokens = tokens;
                this.nextTokenizer = nextTokenizer;
                // Inherit recursion depth from the parent tokenizer so that the
                // JsonParser.RecursionLimit check applies across replayed Any
                // bodies. Without this, deeply-nested google.protobuf.Any
                // payloads can bypass the limit and cause a StackOverflowException.
                this.RecursionDepth = nextTokenizer.RecursionDepth;
            }

            protected override JsonToken NextImpl()
            {
                if (nextTokenIndex >= tokens.Count)
                {
                    return nextTokenizer.Next();
                }
                return tokens[nextTokenIndex++];
            }
        }

        /// <summary>
        /// Tokenizer which does all the *real* work of parsing JSON.
        /// </summary>
        private sealed class JsonTextTokenizer : JsonTokenizer
        {
            // The set of states in which a value is valid next token.
            private static readonly State ValueStates = State.ArrayStart | State.ArrayAfterComma | State.ObjectAfterColon | State.StartOfDocument;

            private readonly Stack<ContainerType> containerStack = new Stack<ContainerType>();
            private readonly PushBackReader reader;
            private State state;

            internal JsonTextTokenizer(TextReader reader)
            {
                this.reader = new PushBackReader(reader);
                state = State.StartOfDocument;
                containerStack.Push(ContainerType.Document);
            }

            /// <remarks>
            /// This method essentially just loops through characters skipping whitespace, validating and
            /// changing state (e.g. from ObjectBeforeColon to ObjectAfterColon)
            /// until it reaches something which will be a genuine token (e.g. a start object, or a value) at which point
            /// it returns the token. Although the method is large, it would be relatively hard to break down further... most
            /// of it is the large switch statement, which sometimes returns and sometimes doesn't.
            /// </remarks>
            protected override JsonToken NextImpl()
            {
                if (state == State.ReaderExhausted)
                {
                    throw new InvalidOperationException("Next() called after end of document");
                }
                while (true)
                {
                    var next = reader.Read();
                    switch (next)
                    {
                        case -1:
                            ValidateState(State.ExpectedEndOfDocument, "Unexpected end of document in state: ");
                            state = State.ReaderExhausted;
                            return JsonToken.EndDocument;

                        // Skip whitespace between tokens
                        case ' ':
                        case '\t':
                        case '\r':
                        case '\n':
                            break;
                        case ':':
                            ValidateState(State.ObjectBeforeColon, "Invalid state to read a colon: ");
                            state = State.ObjectAfterColon;
                            break;
                        case ',':
                            ValidateState(State.ObjectAfterProperty | State.ArrayAfterValue, "Invalid state to read a comma: ");
                            state = state == State.ObjectAfterProperty ? State.ObjectAfterComma : State.ArrayAfterComma;
                            break;
                        case '"':
                            string stringValue = ReadString();
                            if ((state & (State.ObjectStart | State.ObjectAfterComma)) != 0)
                            {
                                state = State.ObjectBeforeColon;
                                return JsonToken.Name(stringValue);
                            }
                            else
                            {
                                ValidateAndModifyStateForValue("Invalid state to read a double quote: ");
                                return JsonToken.Value(stringValue);
                            }
                        case '{':
                            ValidateState(ValueStates, "Invalid state to read an open brace: ");
                            state = State.ObjectStart;
                            containerStack.Push(ContainerType.Object);
                            return JsonToken.StartObject;
                        case '}':
                            ValidateState(State.ObjectAfterProperty | State.ObjectStart, "Invalid state to read a close brace: ");
                            PopContainer();
                            return JsonToken.EndObject;
                        case '[':
                            ValidateState(ValueStates, "Invalid state to read an open square bracket: ");
                            state = State.ArrayStart;
                            containerStack.Push(ContainerType.Array);
                            return JsonToken.StartArray;
                        case ']':
                            ValidateState(State.ArrayAfterValue | State.ArrayStart, "Invalid state to read a close square bracket: ");
                            PopContainer();
                            return JsonToken.EndArray;
                        case 'n': // Start of null
                            ConsumeLiteral("null");
                            ValidateAndModifyStateForValue("Invalid state to read a null literal: ");
                            return JsonToken.Null;
                        case 't': // Start of true
                            ConsumeLiteral("true");
                            ValidateAndModifyStateForValue("Invalid state to read a true literal: ");
                            return JsonToken.True;
                        case 'f': // Start of false
                            ConsumeLiteral("false");
                            ValidateAndModifyStateForValue("Invalid state to read a false literal: ");
                            return JsonToken.False;
                        case '-': // Start of a number
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':
                            double number = ReadNumber((char) next);
                            ValidateAndModifyStateForValue("Invalid state to read a number token: ");
                            return JsonToken.Value(number);
                        default:
                            throw new InvalidJsonException($"Invalid first character of token: {(char) next}");
                    }
                }
            }

            private void ValidateState(State validStates, string errorPrefix)
            {
                if ((validStates & state) == 0)
                {
                    throw reader.CreateException(errorPrefix + state);
                }
            }

            /// <summary>
            /// Reads a string token. It is assumed that the opening " has already been read.
            /// </summary>
            private string ReadString()
            {
                //builder will not be released in case of an exception, but this is not a problem and we will create new on next Acquire
                var builder = StringBuilderCache.Acquire();
                bool haveHighSurrogate = false;
                while (true)
                {
                    char c = reader.ReadOrFail("Unexpected end of text while reading string");
                    if (c < ' ')
                    {
                        throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in string literal: U+{0:x4}", (int) c));
                    }
                    if (c == '"')
                    {
                        if (haveHighSurrogate)
                        {
                            throw reader.CreateException("Invalid use of surrogate pair code units");
                        }
                        return StringBuilderCache.GetStringAndRelease(builder);
                    }
                    if (c == '\\')
                    {
                        c = ReadEscapedCharacter();
                    }
                    // TODO: Consider only allowing surrogate pairs that are either both escaped,
                    // or both not escaped. It would be a very odd text stream that contained a "lone" high surrogate
                    // followed by an escaped low surrogate or vice versa... and that couldn't even be represented in UTF-8.
                    if (haveHighSurrogate != char.IsLowSurrogate(c))
                    {
                        throw reader.CreateException("Invalid use of surrogate pair code units");
                    }
                    haveHighSurrogate = char.IsHighSurrogate(c);
                    builder.Append(c);
                }
            }

            /// <summary>
            /// Reads an escaped character. It is assumed that the leading backslash has already been read.
            /// </summary>
            private char ReadEscapedCharacter()
            {
                char c = reader.ReadOrFail("Unexpected end of text while reading character escape sequence");
                return c switch
                {
                    'n' => '\n',
                    '\\' => '\\',
                    'b' => '\b',
                    'f' => '\f',
                    'r' => '\r',
                    't' => '\t',
                    '"' => '"',
                    '/' => '/',
                    'u' => ReadUnicodeEscape(),
                    _ => throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int)c)),
                };
            }

            /// <summary>
            /// Reads an escaped Unicode 4-nybble hex sequence. It is assumed that the leading \u has already been read.
            /// </summary>
            private char ReadUnicodeEscape()
            {
                int result = 0;
                for (int i = 0; i < 4; i++)
                {
                    char c = reader.ReadOrFail("Unexpected end of text while reading Unicode escape sequence");
                    int nybble;
                    if (c >= '0' && c <= '9')
                    {
                        nybble = c - '0';
                    }
                    else if (c >= 'a' && c <= 'f')
                    {
                        nybble = c - 'a' + 10;
                    }
                    else if (c >= 'A' && c <= 'F')
                    {
                        nybble = c - 'A' + 10;
                    }
                    else
                    {
                        throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int) c));
                    }
                    result = (result << 4) + nybble;
                }
                return (char) result;
            }

            /// <summary>
            /// Consumes a text-only literal, throwing an exception if the read text doesn't match it.
            /// It is assumed that the first letter of the literal has already been read.
            /// </summary>
            private void ConsumeLiteral(string text)
            {
                for (int i = 1; i < text.Length; i++)
                {
                    int next = reader.Read();
                    if (next != text[i])
                    {
                        // Only check for "end of text" when we've detected that the character differs from the
                        // expected one.
                        var message = next == -1
                            ? $"Unexpected end of text while reading literal token {text}"
                            : $"Unexpected character while reading literal token {text}";
                        throw reader.CreateException(message);
                    }
                }
            }

            private double ReadNumber(char initialCharacter)
            {
                //builder will not be released in case of an exception, but this is not a problem and we will create new on next Acquire
                var builder = StringBuilderCache.Acquire();
                if (initialCharacter == '-')
                {
                    builder.Append('-');
                }
                else
                {
                    reader.PushBack(initialCharacter);
                }
                // Each method returns the character it read that doesn't belong in that part,
                // so we know what to do next, including pushing the character back at the end.
                // null is returned for "end of text".
                int next = ReadInt(builder);
                if (next == '.')
                {
                    next = ReadFrac(builder);
                }
                if (next == 'e' || next == 'E')
                {
                    next = ReadExp(builder);
                }
                // If we read a character which wasn't part of the number, push it back so we can read it again
                // to parse the next token.
                if (next != -1)
                {
                    reader.PushBack((char) next);
                }

                // TODO: What exception should we throw if the value can't be represented as a double?
                var builderValue = StringBuilderCache.GetStringAndRelease(builder);
                try
                {
                    double result = double.Parse(builderValue,
                        NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent,
                        CultureInfo.InvariantCulture);

                    // .NET Core 3.0 and later returns infinity if the number is too large or small to be represented.
                    // For compatibility with other Protobuf implementations the tokenizer should still throw.
                    if (double.IsInfinity(result))
                    {
                        throw reader.CreateException("Numeric value out of range: " + builderValue);
                    }

                    return result;
                }
                catch (OverflowException)
                {
                    throw reader.CreateException("Numeric value out of range: " + builderValue);
                }
            }

            /// <summary>
            /// Copies an integer into a StringBuilder.
            /// </summary>
            /// <param name="builder">The builder to read the number into</param>
            /// <returns>The character following the integer, or -1 for end-of-text.</returns>
            private int ReadInt(StringBuilder builder)
            {
                char first = reader.ReadOrFail("Invalid numeric literal");
                if (first < '0' || first > '9')
                {
                    throw reader.CreateException("Invalid numeric literal");
                }
                builder.Append(first);
                int next = ConsumeDigits(builder, out int digitCount);
                if (first == '0' && digitCount != 0)
                {
                    throw reader.CreateException("Invalid numeric literal: leading 0 for non-zero value.");
                }
                return next;
            }

            /// <summary>
            /// Copies the fractional part of an integer into a StringBuilder, assuming reader is positioned after a period.
            /// </summary>
            /// <param name="builder">The builder to read the number into</param>
            /// <returns>The character following the fractional part, or -1 for end-of-text.</returns>
            private int ReadFrac(StringBuilder builder)
            {
                builder.Append('.'); // Already consumed this
                int next = ConsumeDigits(builder, out int digitCount);
                if (digitCount == 0)
                {
                    throw reader.CreateException("Invalid numeric literal: fraction with no trailing digits");
                }
                return next;
            }

            /// <summary>
            /// Copies the exponent part of a number into a StringBuilder, with an assumption that the reader is already positioned after the "e".
            /// </summary>
            /// <param name="builder">The builder to read the number into</param>
            /// <returns>The character following the exponent, or -1 for end-of-text.</returns>
            private int ReadExp(StringBuilder builder)
            {
                builder.Append('E'); // Already consumed this (or 'e')
                int next = reader.Read();
                if (next == -1)
                {
                    throw reader.CreateException("Invalid numeric literal: exponent with no trailing digits");
                }
                if (next == '-' || next == '+')
                {
                    builder.Append((char) next);
                }
                else
                {
                    reader.PushBack((char) next);
                }
                next = ConsumeDigits(builder, out int digitCount);
                if (digitCount == 0)
                {
                    throw reader.CreateException("Invalid numeric literal: exponent without value");
                }
                return next;
            }

            /// <summary>
            /// Copies a sequence of digits into a StringBuilder.
            /// </summary>
            /// <param name="builder">The builder to read the number into</param>
            /// <param name="count">The number of digits appended to the builder</param>
            /// <returns>The character following the digits, or -1 for end-of-text.</returns>
            private int ConsumeDigits(StringBuilder builder, out int count)
            {
                count = 0;
                while (true)
                {
                    int next = reader.Read();
                    if (next == -1 || next < '0' || next > '9')
                    {
                        return next;
                    }
                    count++;
                    builder.Append((char) next);
                }
            }

            /// <summary>
            /// Validates that we're in a valid state to read a value (using the given error prefix if necessary)
            /// and changes the state to the appropriate one, e.g. ObjectAfterColon to ObjectAfterProperty.
            /// </summary>
            private void ValidateAndModifyStateForValue(string errorPrefix)
            {
                ValidateState(ValueStates, errorPrefix);
                switch (state)
                {
                    case State.StartOfDocument:
                        state = State.ExpectedEndOfDocument;
                        return;
                    case State.ObjectAfterColon:
                        state = State.ObjectAfterProperty;
                        return;
                    case State.ArrayStart:
                    case State.ArrayAfterComma:
                        state = State.ArrayAfterValue;
                        return;
                    default:
                        throw new InvalidOperationException("ValidateAndModifyStateForValue does not handle all value states (and should)");
                }
            }

            /// <summary>
            /// Pops the top-most container, and sets the state to the appropriate one for the end of a value
            /// in the parent container.
            /// </summary>
            private void PopContainer()
            {
                containerStack.Pop();
                var parent = containerStack.Peek();
                state = parent switch
                {
                    ContainerType.Object => State.ObjectAfterProperty,
                    ContainerType.Array => State.ArrayAfterValue,
                    ContainerType.Document => State.ExpectedEndOfDocument,
                    _ => throw new InvalidOperationException("Unexpected container type: " + parent),
                };
            }

            private enum ContainerType
            {
                Document, Object, Array
            }

            /// <summary>
            /// Possible states of the tokenizer.
            /// </summary>
            /// <remarks>
            /// <para>This is a flags enum purely so we can simply and efficiently represent a set of valid states
            /// for checking.</para>
            /// <para>
            /// Each is documented with an example,
            /// where ^ represents the current position within the text stream. The examples all use string values,
            /// but could be any value, including nested objects/arrays.
            /// The complete state of the tokenizer also includes a stack to indicate the contexts (arrays/objects).
            /// Any additional notional state of "AfterValue" indicates that a value has been completed, at which
            /// point there's an immediate transition to ExpectedEndOfDocument,  ObjectAfterProperty or ArrayAfterValue.
            /// </para>
            /// <para>
            /// These states were derived manually by reading RFC 7159 carefully.
            /// </para>
            /// </remarks>
            [Flags]
            private enum State
            {
                /// <summary>
                /// ^ { "foo": "bar" }
                /// Before the value in a document. Next states: ObjectStart, ArrayStart, "AfterValue"
                /// </summary>
                StartOfDocument = 1 << 0,
                /// <summary>
                /// { "foo": "bar" } ^
                /// After the value in a document. Next states: ReaderExhausted
                /// </summary>
                ExpectedEndOfDocument = 1 << 1,
                /// <summary>
                /// { "foo": "bar" } ^ (and already read to the end of the reader)
                /// Terminal state.
                /// </summary>
                ReaderExhausted = 1 << 2,
                /// <summary>
                /// { ^ "foo": "bar" }
                /// Before the *first* property in an object.
                /// Next states:
                /// "AfterValue" (empty object)
                /// ObjectBeforeColon (read a name)
                /// </summary>
                ObjectStart = 1 << 3,
                /// <summary>
                /// { "foo" ^ : "bar", "x": "y" }
                /// Next state: ObjectAfterColon
                /// </summary>
                ObjectBeforeColon = 1 << 4,
                /// <summary>
                /// { "foo" : ^ "bar", "x": "y" }
                /// Before any property other than the first in an object.
                /// (Equivalently: after any property in an object)
                /// Next states:
                /// "AfterValue" (value is simple)
                /// ObjectStart (value is object)
                /// ArrayStart (value is array)
                /// </summary>
                ObjectAfterColon = 1 << 5,
                /// <summary>
                /// { "foo" : "bar" ^ , "x" : "y" }
                /// At the end of a property, so expecting either a comma or end-of-object
                /// Next states: ObjectAfterComma or "AfterValue"
                /// </summary>
                ObjectAfterProperty = 1 << 6,
                /// <summary>
                /// { "foo":"bar", ^ "x":"y" }
                /// Read the comma after the previous property, so expecting another property.
                /// This is like ObjectStart, but closing brace isn't valid here
                /// Next state: ObjectBeforeColon.
                /// </summary>
                ObjectAfterComma = 1 << 7,
                /// <summary>
                /// [ ^ "foo", "bar" ]
                /// Before the *first* value in an array.
                /// Next states:
                /// "AfterValue" (read a value)
                /// "AfterValue" (end of array; will pop stack)
                /// </summary>
                ArrayStart = 1 << 8,
                /// <summary>
                /// [ "foo" ^ , "bar" ]
                /// After any value in an array, so expecting either a comma or end-of-array
                /// Next states: ArrayAfterComma or "AfterValue"
                /// </summary>
                ArrayAfterValue = 1 << 9,
                /// <summary>
                /// [ "foo", ^ "bar" ]
                /// After a comma in an array, so there *must* be another value (simple or complex).
                /// Next states: "AfterValue" (simple value), StartObject, StartArray
                /// </summary>
                ArrayAfterComma = 1 << 10
            }

            /// <summary>
            /// Wrapper around a text reader allowing small amounts of buffering and location handling.
            /// </summary>
            private class PushBackReader
            {
                // TODO: Add locations for errors etc.

                private readonly TextReader reader;

                internal PushBackReader(TextReader reader)
                {
                    // TODO: Wrap the reader in a BufferedReader?
                    this.reader = reader;
                }

                /// <summary>
                /// The buffered next character, if we have one, or -1 if there is no buffered character.
                /// </summary>
                private int nextChar = -1;

                /// <summary>
                /// Returns the next character in the stream, or -1 if we have reached the end of the stream.
                /// </summary>
                internal int Read()
                {
                    if (nextChar != -1)
                    {
                        int tmp = nextChar;
                        nextChar = -1;
                        return tmp;
                    }
                    return reader.Read();
                }

                /// <summary>
                /// Reads the next character from the underlying reader, throwing an <see cref="InvalidJsonException" />
                /// with the specified message if there are no more characters available.
                /// </summary>
                internal char ReadOrFail(string messageOnFailure)
                {
                    int next = Read();
                    if (next == -1)
                    {
                        throw CreateException(messageOnFailure);
                    }
                    return (char) next;
                }

                internal void PushBack(char c)
                {
                    if (nextChar != -1)
                    {
                        throw new InvalidOperationException("Cannot push back when already buffering a character");
                    }
                    nextChar = c;
                }

                /// <summary>
                /// Creates a new exception appropriate for the current state of the reader.
                /// </summary>
                internal InvalidJsonException CreateException(string message)
                {
                    // TODO: Keep track of and use the location.
                    return new InvalidJsonException(message);
                }
            }

            /// <summary>
            /// Provide a cached reusable instance of stringbuilder per thread.
            /// Copied from https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/System/Text/StringBuilderCache.cs
            /// </summary>
            private static class StringBuilderCache
            {
                private const int MaxCachedStringBuilderSize = 360;
                private const int DefaultStringBuilderCapacity = 16; // == StringBuilder.DefaultCapacity

                [ThreadStatic]
                private static StringBuilder cachedInstance;

                /// <summary>Get a StringBuilder for the specified capacity.</summary>
                /// <remarks>If a StringBuilder of an appropriate size is cached, it will be returned and the cache emptied.</remarks>
                public static StringBuilder Acquire(int capacity = DefaultStringBuilderCapacity)
                {
                    if (capacity <= MaxCachedStringBuilderSize)
                    {
                        StringBuilder sb = cachedInstance;
                        if (sb != null)
                        {
                            // Avoid stringbuilder block fragmentation by getting a new StringBuilder
                            // when the requested size is larger than the current capacity
                            if (capacity <= sb.Capacity)
                            {
                                cachedInstance = null;
                                sb.Clear();
                                return sb;
                            }
                        }
                    }

                    return new StringBuilder(capacity);
                }

                /// <summary>Place the specified builder in the cache if it is not too big.</summary>
                private static void Release(StringBuilder sb)
                {
                    if (sb.Capacity <= MaxCachedStringBuilderSize)
                    {
                        cachedInstance = cachedInstance?.Capacity >= sb.Capacity ? cachedInstance : sb;
                    }
                }

                /// <summary>ToString() the stringbuilder, Release it to the cache, and return the resulting string.</summary>
                public static string GetStringAndRelease(StringBuilder sb)
                {
                    string result = sb.ToString();
                    Release(sb);
                    return result;
                }
            }
        }
    }
}
