/*
 * Copyright 2018 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "modules/jsonreader/SkJSONReader.h"

#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/private/SkDebug.h"
#include "include/private/SkMalloc.h"
#include "include/private/SkTo.h"
#include "include/utils/SkParse.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkAutoLocaleSetter.h"
#include "src/core/SkUTF.h"

#include <array>
#include <charconv>
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <limits>
#include <new>
#include <tuple>
#include <vector>

namespace skjson {

// #define SK_JSON_REPORT_ERRORS

static_assert( sizeof(Value) == 8, "");
static_assert(alignof(Value) == 8, "");

static constexpr size_t kRecAlign = alignof(Value);

void Value::init_tagged(Tag t) {
    memset(fData8, 0, sizeof(fData8));
    fData8[0] = SkTo<uint8_t>(t);
    SkASSERT(this->getTag() == t);
}

// Pointer values store a type (in the lower kTagBits bits) and a pointer.
void Value::init_tagged_pointer(Tag t, void* p) {
    if (sizeof(Value) == sizeof(uintptr_t)) {
        *this->cast<uintptr_t>() = reinterpret_cast<uintptr_t>(p);
        // For 64-bit, we rely on the pointer lower bits being zero.
        SkASSERT(!(fData8[0] & kTagMask));
        fData8[0] |= SkTo<uint8_t>(t);
    } else {
        // For 32-bit, we store the pointer in the upper word
        SkASSERT(sizeof(Value) == sizeof(uintptr_t) * 2);
        this->init_tagged(t);
        *this->cast<uintptr_t>() = reinterpret_cast<uintptr_t>(p);
    }

    SkASSERT(this->getTag()    == t);
    SkASSERT(this->ptr<void>() == p);
}

NullValue::NullValue() {
    this->init_tagged(Tag::kNull);
    SkASSERT(this->getTag() == Tag::kNull);
}

BoolValue::BoolValue(bool b) {
    this->init_tagged(Tag::kBool);
    *this->cast<bool>() = b;
    SkASSERT(this->getTag() == Tag::kBool);
}

NumberValue::NumberValue(int32_t i) {
    this->init_tagged(Tag::kInt);
    *this->cast<int32_t>() = i;
    SkASSERT(this->getTag() == Tag::kInt);
}

NumberValue::NumberValue(float f) {
    this->init_tagged(Tag::kFloat);
    *this->cast<float>() = f;
    SkASSERT(this->getTag() == Tag::kFloat);
}

// Vector recs point to externally allocated slabs with the following layout:
//
//   [size_t n] [REC_0] ... [REC_n-1] [optional extra trailing storage]
//
// Long strings use extra_alloc_size == 1 to store the \0 terminator.
//
template <typename T, size_t extra_alloc_size = 0>
static void* MakeVector(size_t vec_size, const void* src, size_t src_size, SkArenaAlloc& alloc) {
    // The Ts are already in memory, so their size should be safe.
    const auto total_size = sizeof(size_t) + vec_size * sizeof(T) + extra_alloc_size;
    auto* size_ptr = reinterpret_cast<size_t*>(alloc.makeBytesAlignedTo(total_size, kRecAlign));

    *size_ptr = vec_size;
    sk_careful_memcpy(size_ptr + 1, src, src_size * sizeof(T));

    return size_ptr;
}

template <typename T, size_t extra_alloc_size = 0>
static void* MakeVector(size_t vec_size, const void* src, SkArenaAlloc& alloc) {
    return MakeVector<T, extra_alloc_size>(vec_size, src, vec_size, alloc);
}

ArrayValue::ArrayValue(const Value* src, size_t size, SkArenaAlloc& alloc) {
    this->init_tagged_pointer(Tag::kArray, MakeVector<Value>(size, src, alloc));
    SkASSERT(this->getTag() == Tag::kArray);
}

// Strings have two flavors:
//
// -- short strings (len <= 7) -> these are stored inline, in the record
//    (one byte reserved for null terminator/type):
//
//        [str] [\0]|[max_len - actual_len]
//
//    Storing [max_len - actual_len] allows the 'len' field to double-up as a
//    null terminator when size == max_len (this works 'cause kShortString == 0).
//
// -- long strings (len > 7) -> these are externally allocated vectors (VectorRec<char>).
//
// The string data plus a null-char terminator are copied over.
//
namespace {

// An internal string builder with a fast 8 byte short string load path
// (for the common case where the string is not at the end of the stream).
class FastString final : public Value {
public:
    FastString(const char* src, size_t size, const char* eos, SkArenaAlloc& alloc) {
        SkASSERT(src <= eos);

        if (size > kMaxInlineStringSize) {
            this->initLongString(src, size, alloc);
            SkASSERT(this->getTag() == Tag::kString);
            return;
        }

        // initFastShortString is faster (doh), but requires access to 6 chars past src.
        if (src && src + 6 <= eos) {
            this->initFastShortString(src, size);
        } else {
            this->initShortString(src, size);
        }

        SkASSERT(this->getTag() == Tag::kShortString);
    }

private:
    // first byte reserved for tagging, \0 terminator => 6 usable chars
    inline static constexpr size_t kMaxInlineStringSize = sizeof(Value) - 2;

    void initLongString(const char* src, size_t size, SkArenaAlloc& alloc) {
        SkASSERT(size > kMaxInlineStringSize);

        this->init_tagged_pointer(Tag::kString, MakeVector<char, 1>(size, src, alloc));

        auto* data = this->cast<VectorValue<char, Value::Type::kString>>()->begin();
        const_cast<char*>(data)[size] = '\0';
    }

    void initShortString(const char* src, size_t size) {
        SkASSERT(size <= kMaxInlineStringSize);

        this->init_tagged(Tag::kShortString);
        sk_careful_memcpy(this->cast<char>(), src, size);
        // Null terminator provided by init_tagged() above (fData8 is zero-initialized).
    }

    void initFastShortString(const char* src, size_t size) {
        SkASSERT(size <= kMaxInlineStringSize);

        uint64_t* s64 = this->cast<uint64_t>();

        // Load 8 chars and mask out the tag and \0 terminator.
        // Note: we picked kShortString == 0 to avoid setting explicitly below.
        static_assert(SkToU8(Tag::kShortString) == 0, "please don't break this");

        // Since the first byte is occupied by the tag, we want the string chars [0..5] to land
        // on bytes [1..6] => the fastest way is to read8 @(src - 1) (always safe, because the
        // string requires a " prefix at the very least).
        memcpy(s64, src - 1, 8);

#if defined(SK_CPU_LENDIAN)
        // The mask for a max-length string (6), with a leading tag and trailing \0 is
        // 0x00ffffffffffff00.  Accounting for the final left-shift, this becomes
        // 0x0000ffffffffffff.
        *s64 &= (0x0000ffffffffffffULL >> ((kMaxInlineStringSize - size) * 8)) // trailing \0s
                    << 8;                                                      // tag byte
#else
        static_assert(false, "Big-endian builds are not supported at this time.");
#endif
    }
};

}  // namespace

StringValue::StringValue(const char* src, SkArenaAlloc& alloc)
        : StringValue(src, strlen(src), alloc) {}

StringValue::StringValue(const char* src, size_t size, SkArenaAlloc& alloc) {
    new (this) FastString(src, size, src, alloc);
}

ObjectValue::ObjectValue(const Member* src, size_t size, SkArenaAlloc& alloc) {
    this->init_tagged_pointer(Tag::kObject, MakeVector<Member>(size, src, alloc));
    SkASSERT(this->getTag() == Tag::kObject);
}

// Boring public Value glue.

static int inline_strcmp(const char a[], const char b[]) {
    for (;;) {
        char c = *a++;
        if (c == 0) {
            break;
        }
        if (c != *b++) {
            return 1;
        }
    }
    return *b != 0;
}

const Member* ObjectValue::find(const char* key) const {
    // Reverse search for duplicates resolution (policy: return last).
    const auto* begin  = this->begin();
    const auto* member = this->end();

    while (member > begin) {
        --member;
        if (0 == inline_strcmp(key, member->fKey.as<StringValue>().begin())) {
            return member;
        }
    }

    return nullptr;
}

Value& ObjectValue::writable(const char* key, SkArenaAlloc& alloc) const {
    Member* writable_member = const_cast<Member*>(this->find(key));

    if (!writable_member) {
        ObjectValue* writable_obj = const_cast<ObjectValue*>(this);
        writable_obj->init_tagged_pointer(Tag::kObject, MakeVector<Member>(this->size() + 1,
                                                                           this->begin(),
                                                                           this->size(),
                                                                           alloc));
        writable_member         = const_cast<Member*>(writable_obj->end() - 1);
        writable_member->fKey   = StringValue(key, strlen(key), alloc);
        writable_member->fValue = NullValue();
    }

    return writable_member->fValue;
}

namespace {

// Lexer/parser inspired by rapidjson [1], sajson [2] and pjson [3].
//
// [1] https://github.com/Tencent/rapidjson/
// [2] https://github.com/chadaustin/sajson
// [3] https://pastebin.com/hnhSTL3h

// bit 0 (0x01) - plain ASCII string character
// bit 1 (0x02) - whitespace
// bit 2 (0x04) - string terminator (" \\ \0 [control chars] **AND } ]** <- see matchString notes)
// bit 3 (0x08) - 0-9
// bit 4 (0x10) - 0-9 e E .
// bit 5 (0x20) - scope terminator (} ])
static constexpr std::array<uint8_t, 256> g_token_flags = {
 // 0    1    2    3    4    5    6    7      8    9    A    B    C    D    E    F
    4,   4,   4,   4,   4,   4,   4,   4,     4,   6,   6,   4,   4,   6,   4,   4, // 0
    4,   4,   4,   4,   4,   4,   4,   4,     4,   4,   4,   4,   4,   4,   4,   4, // 1
    3,   1,   4,   1,   1,   1,   1,   1,     1,   1,   1,   1,   1,   1,   0x11,1, // 2
 0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,  0x19,0x19,   1,   1,   1,   1,   1,   1, // 3
    1,   1,   1,   1,   1,   0x11,1,   1,     1,   1,   1,   1,   1,   1,   1,   1, // 4
    1,   1,   1,   1,   1,   1,   1,   1,     1,   1,   1,   1,   4,0x25,   1,   1, // 5
    1,   1,   1,   1,   1,   0x11,1,   1,     1,   1,   1,   1,   1,   1,   1,   1, // 6
    1,   1,   1,   1,   1,   1,   1,   1,     1,   1,   1,   1,   1,0x25,   1,   1, // 7

 // 128-255
    0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0
};

static inline bool is_ws(char c)       { return g_token_flags[static_cast<uint8_t>(c)] & 0x02; }
static inline bool is_eostring(char c) { return g_token_flags[static_cast<uint8_t>(c)] & 0x04; }
static inline bool is_digit(char c)    { return g_token_flags[static_cast<uint8_t>(c)] & 0x08; }
static inline bool is_numeric(char c)  { return g_token_flags[static_cast<uint8_t>(c)] & 0x10; }
static inline bool is_eoscope(char c)  { return g_token_flags[static_cast<uint8_t>(c)] & 0x20; }

static inline const char* skip_ws(const char* p) {
    while (is_ws(*p)) ++p;
    return p;
}

static inline float pow10(int32_t exp) {
    static constexpr std::array<float, 63> g_pow10_table = {
       1.e-031f, 1.e-030f, 1.e-029f, 1.e-028f, 1.e-027f, 1.e-026f, 1.e-025f, 1.e-024f,
       1.e-023f, 1.e-022f, 1.e-021f, 1.e-020f, 1.e-019f, 1.e-018f, 1.e-017f, 1.e-016f,
       1.e-015f, 1.e-014f, 1.e-013f, 1.e-012f, 1.e-011f, 1.e-010f, 1.e-009f, 1.e-008f,
       1.e-007f, 1.e-006f, 1.e-005f, 1.e-004f, 1.e-003f, 1.e-002f, 1.e-001f, 1.e+000f,
       1.e+001f, 1.e+002f, 1.e+003f, 1.e+004f, 1.e+005f, 1.e+006f, 1.e+007f, 1.e+008f,
       1.e+009f, 1.e+010f, 1.e+011f, 1.e+012f, 1.e+013f, 1.e+014f, 1.e+015f, 1.e+016f,
       1.e+017f, 1.e+018f, 1.e+019f, 1.e+020f, 1.e+021f, 1.e+022f, 1.e+023f, 1.e+024f,
       1.e+025f, 1.e+026f, 1.e+027f, 1.e+028f, 1.e+029f, 1.e+030f, 1.e+031f
    };

    static constexpr int32_t k_exp_offset = std::size(g_pow10_table) / 2;

    // We only support negative exponents for now.
    SkASSERT(exp <= 0);

    return (exp >= -k_exp_offset) ? g_pow10_table[exp + k_exp_offset]
                                  : std::pow(10.0f, static_cast<float>(exp));
}

class DOMParser {
public:
    explicit DOMParser(SkArenaAlloc& alloc) : fAlloc(alloc) {
        fValueStack.reserve(kValueStackReserve);
        fUnescapeBuffer.reserve(kUnescapeBufferReserve);
    }

    Value parse(const char* p, size_t size) {
        if (!size) {
            return this->error(NullValue(), p, "invalid empty input");
        }

        #if !defined(__cpp_lib_to_chars)
        // Setting locale with dot decimal separator
        SkAutoLocaleSetter locale("C");
        #endif // !defined(__cpp_lib_to_chars)

        const char* p_stop = p + size - 1;

        // We're only checking for end-of-stream on object/array close('}',']'),
        // so we must trim any whitespace from the buffer tail.
        while (p_stop > p && is_ws(*p_stop)) --p_stop;

        SkASSERT(p_stop >= p && p_stop < p + size);
        if (!is_eoscope(*p_stop)) {
            return this->error(NullValue(), p_stop, "invalid top-level value");
        }

        p = skip_ws(p);

        switch (*p) {
            case '{':
                goto match_object;
            case '[':
                goto match_array;
            default:
                return this->error(NullValue(), p, "invalid top-level value");
        }

    match_object:
        SkASSERT(*p == '{');
        p = skip_ws(p + 1);

        this->pushObjectScope();

        if (*p == '}') goto pop_object;

        // goto match_object_key;
    match_object_key:
        p = skip_ws(p);
        if (*p != '"') return this->error(NullValue(), p, "expected object key");

        p = this->matchString(p, p_stop, [this](const char* key, size_t size, const char* eos) {
            this->pushObjectKey(key, size, eos);
        });
        if (!p) return NullValue();

        p = skip_ws(p);
        if (*p != ':') return this->error(NullValue(), p, "expected ':' separator");

        ++p;

        // goto match_value;
    match_value:
        p = skip_ws(p);

        switch (*p) {
            case '\0':
                return this->error(NullValue(), p, "unexpected input end");
            case '"':
                p = this->matchString(
                        p, p_stop, [this](const char* str, size_t size, const char* eos) {
                            this->pushString(str, size, eos);
                        });
                break;
            case '[':
                goto match_array;
            case 'f':
                p = this->matchFalse(p);
                break;
            case 'n':
                p = this->matchNull(p);
                break;
            case 't':
                p = this->matchTrue(p);
                break;
            case '{':
                goto match_object;
            default:
                p = this->matchNumber(p, p_stop);
                break;
        }

        if (!p) return NullValue();

        // goto match_post_value;
    match_post_value:
        SkASSERT(!this->inTopLevelScope());

        p = skip_ws(p);
        switch (*p) {
            case ',':
                ++p;
                if (this->inObjectScope()) {
                    goto match_object_key;
                } else {
                    SkASSERT(this->inArrayScope());
                    goto match_value;
                }
            case ']':
                goto pop_array;
            case '}':
                goto pop_object;
            default:
                return this->error(NullValue(), p - 1, "unexpected value-trailing token");
        }

        // unreachable
        SkASSERT(false);

    pop_object:
        SkASSERT(*p == '}');

        if (this->inArrayScope()) {
            return this->error(NullValue(), p, "unexpected object terminator");
        }

        this->popObjectScope();

        // goto pop_common
    pop_common:
        SkASSERT(is_eoscope(*p));

        if (this->inTopLevelScope()) {
            SkASSERT(fValueStack.size() == 1);

            // Success condition: parsed the top level element and reached the stop token.
            return p == p_stop ? fValueStack.front()
                               : this->error(NullValue(), p + 1, "trailing root garbage");
        }

        if (p == p_stop) {
            return this->error(NullValue(), p, "unexpected end-of-input");
        }

        ++p;

        goto match_post_value;

    match_array:
        SkASSERT(*p == '[');
        p = skip_ws(p + 1);

        this->pushArrayScope();

        if (*p != ']') goto match_value;

        // goto pop_array;
    pop_array:
        SkASSERT(*p == ']');

        if (this->inObjectScope()) {
            return this->error(NullValue(), p, "unexpected array terminator");
        }

        this->popArrayScope();

        goto pop_common;

        SkASSERT(false);
        return NullValue();
    }

    std::tuple<const char*, const SkString> getError() const {
        return std::make_tuple(fErrorToken, fErrorMessage);
    }

private:
    SkArenaAlloc&         fAlloc;

    // Pending values stack.
    inline static constexpr size_t kValueStackReserve = 256;
    std::vector<Value>    fValueStack;

    // String unescape buffer.
    inline static constexpr size_t kUnescapeBufferReserve = 512;
    std::vector<char>     fUnescapeBuffer;

    // Tracks the current object/array scope, as an index into fStack:
    //
    //   - for objects: fScopeIndex =  (index of first value in scope)
    //   - for arrays : fScopeIndex = -(index of first value in scope)
    //
    // fScopeIndex == 0 IFF we are at the top level (no current/active scope).
    intptr_t              fScopeIndex = 0;

    // Error reporting.
    const char*           fErrorToken = nullptr;
    SkString              fErrorMessage;

    bool inTopLevelScope() const { return fScopeIndex == 0; }
    bool inObjectScope()   const { return fScopeIndex >  0; }
    bool inArrayScope()    const { return fScopeIndex <  0; }

    // Helper for masquerading raw primitive types as Values (bypassing tagging, etc).
    template <typename T>
    class RawValue final : public Value {
    public:
        explicit RawValue(T v) {
            static_assert(sizeof(T) <= sizeof(Value), "");
            *this->cast<T>() = v;
        }

        T operator*() const { return *this->cast<T>(); }
    };

    template <typename VectorT>
    void popScopeAsVec(size_t scope_start) {
        SkASSERT(scope_start > 0);
        SkASSERT(scope_start <= fValueStack.size());

        using T = typename VectorT::ValueT;
        static_assert( sizeof(T) >=  sizeof(Value), "");
        static_assert( sizeof(T)  %  sizeof(Value) == 0, "");
        static_assert(alignof(T) == alignof(Value), "");

        const auto scope_count = fValueStack.size() - scope_start,
                   count = scope_count / (sizeof(T) / sizeof(Value));
        SkASSERT(scope_count % (sizeof(T) / sizeof(Value)) == 0);

        const auto* begin = reinterpret_cast<const T*>(fValueStack.data() + scope_start);

        // Restore the previous scope index from saved placeholder value,
        // and instantiate as a vector of values in scope.
        auto& placeholder = fValueStack[scope_start - 1];
        fScopeIndex = *static_cast<RawValue<intptr_t>&>(placeholder);
        placeholder = VectorT(begin, count, fAlloc);

        // Drop the (consumed) values in scope.
        fValueStack.resize(scope_start);
    }

    void pushObjectScope() {
        // Save a scope index now, and then later we'll overwrite this value as the Object itself.
        fValueStack.push_back(RawValue<intptr_t>(fScopeIndex));

        // New object scope.
        fScopeIndex = SkTo<intptr_t>(fValueStack.size());
    }

    void popObjectScope() {
        SkASSERT(this->inObjectScope());
        this->popScopeAsVec<ObjectValue>(SkTo<size_t>(fScopeIndex));

        SkDEBUGCODE(
            const auto& obj = fValueStack.back().as<ObjectValue>();
            SkASSERT(obj.is<ObjectValue>());
            for (const auto& member : obj) {
                SkASSERT(member.fKey.is<StringValue>());
            }
        )
    }

    void pushArrayScope() {
        // Save a scope index now, and then later we'll overwrite this value as the Array itself.
        fValueStack.push_back(RawValue<intptr_t>(fScopeIndex));

        // New array scope.
        fScopeIndex = -SkTo<intptr_t>(fValueStack.size());
    }

    void popArrayScope() {
        SkASSERT(this->inArrayScope());
        this->popScopeAsVec<ArrayValue>(SkTo<size_t>(-fScopeIndex));

        SkDEBUGCODE(
            const auto& arr = fValueStack.back().as<ArrayValue>();
            SkASSERT(arr.is<ArrayValue>());
        )
    }

    void pushObjectKey(const char* key, size_t size, const char* eos) {
        SkASSERT(this->inObjectScope());
        SkASSERT(fValueStack.size() >= SkTo<size_t>(fScopeIndex));
        SkASSERT(!((fValueStack.size() - SkTo<size_t>(fScopeIndex)) & 1));
        this->pushString(key, size, eos);
    }

    void pushTrue() { fValueStack.push_back(BoolValue(true)); }

    void pushFalse() { fValueStack.push_back(BoolValue(false)); }

    void pushNull() { fValueStack.push_back(NullValue()); }

    void pushString(const char* s, size_t size, const char* eos) {
        fValueStack.push_back(FastString(s, size, eos, fAlloc));
    }

    void pushInt32(int32_t i) { fValueStack.push_back(NumberValue(i)); }

    void pushFloat(float f) { fValueStack.push_back(NumberValue(f)); }

    template <typename T>
    T error(T&& ret_val, const char* p, const char* msg) {
#if defined(SK_JSON_REPORT_ERRORS)
        fErrorToken = p;
        fErrorMessage.set(msg);
#endif
        return ret_val;
    }

    const char* matchTrue(const char* p) {
        SkASSERT(p[0] == 't');

        if (p[1] == 'r' && p[2] == 'u' && p[3] == 'e') {
            this->pushTrue();
            return p + 4;
        }

        return this->error(nullptr, p, "invalid token");
    }

    const char* matchFalse(const char* p) {
        SkASSERT(p[0] == 'f');

        if (p[1] == 'a' && p[2] == 'l' && p[3] == 's' && p[4] == 'e') {
            this->pushFalse();
            return p + 5;
        }

        return this->error(nullptr, p, "invalid token");
    }

    const char* matchNull(const char* p) {
        SkASSERT(p[0] == 'n');

        if (p[1] == 'u' && p[2] == 'l' && p[3] == 'l') {
            this->pushNull();
            return p + 4;
        }

        return this->error(nullptr, p, "invalid token");
    }

    const std::vector<char>* unescapeString(const char* begin, const char* end) {
        fUnescapeBuffer.clear();

        for (const auto* p = begin; p != end; ++p) {
            if (*p != '\\') {
                fUnescapeBuffer.push_back(*p);
                continue;
            }

            if (++p == end) {
                return nullptr;
            }

            switch (*p) {
            case  '"': fUnescapeBuffer.push_back( '"'); break;
            case '\\': fUnescapeBuffer.push_back('\\'); break;
            case  '/': fUnescapeBuffer.push_back( '/'); break;
            case  'b': fUnescapeBuffer.push_back('\b'); break;
            case  'f': fUnescapeBuffer.push_back('\f'); break;
            case  'n': fUnescapeBuffer.push_back('\n'); break;
            case  'r': fUnescapeBuffer.push_back('\r'); break;
            case  't': fUnescapeBuffer.push_back('\t'); break;
            case  'u': {
                if (p + 4 >= end) {
                    return nullptr;
                }

                    uint32_t hexed;
                    const char hex_str[] = {p[1], p[2], p[3], p[4], '\0'};
                    const auto* eos = SkParse::FindHex(hex_str, &hexed);
                    if (!eos || *eos) {
                        return nullptr;
                    }

                    char utf8[SkUTF::kMaxBytesInUTF8Sequence];
                    const auto utf8_len = SkUTF::ToUTF8(SkTo<SkUnichar>(hexed), utf8);
                    fUnescapeBuffer.insert(fUnescapeBuffer.end(), utf8, utf8 + utf8_len);
                    p += 4;
                } break;
                default:
                    return nullptr;
            }
        }

        return &fUnescapeBuffer;
    }

    template <typename MatchFunc>
    const char* matchString(const char* p, const char* p_stop, MatchFunc&& func) {
        SkASSERT(*p == '"');
        const auto* s_begin = p + 1;
        bool requires_unescape = false;

        do {
            // Consume string chars.
            // This is the fast path, and hopefully we only hit it once then quick-exit below.
            for (p = p + 1; !is_eostring(*p); ++p);

            if (*p == '"') {
                // Valid string found.
                if (!requires_unescape) {
                    func(s_begin, p - s_begin, p_stop);
                } else {
                    // Slow unescape.  We could avoid this extra copy with some effort,
                    // but in practice escaped strings should be rare.
                    const auto* buf = this->unescapeString(s_begin, p);
                    if (!buf) {
                        break;
                    }

                    SkASSERT(!buf->empty());
                    func(buf->data(), buf->size(), buf->data() + buf->size() - 1);
                }
                return p + 1;
            }

            if (*p == '\\') {
                requires_unescape = true;
                ++p;
                continue;
            }

            // End-of-scope chars are special: we use them to tag the end of the input.
            // Thus they cannot be consumed indiscriminately -- we need to check if we hit the
            // end of the input.  To that effect, we treat them as string terminators above,
            // then we catch them here.
            if (is_eoscope(*p)) {
                continue;
            }

            // Invalid/unexpected char.
            break;
        } while (p != p_stop);

        // Premature end-of-input, or illegal string char.
        return this->error(nullptr, s_begin - 1, "invalid string");
    }

    const char* matchFastFloatDecimalPart(const char* p, int sign, float f, int exp) {
        SkASSERT(exp <= 0);

        for (;;) {
            if (!is_digit(*p)) break;
            f = f * 10.f + (*p++ - '0'); --exp;
            if (!is_digit(*p)) break;
            f = f * 10.f + (*p++ - '0'); --exp;
        }

        const auto decimal_scale = pow10(exp);
        if (is_numeric(*p) || !decimal_scale) {
            SkASSERT((*p == '.' || *p == 'e' || *p == 'E') || !decimal_scale);
            // Malformed input, or an (unsupported) exponent, or a collapsed decimal factor.
            return nullptr;
        }

        this->pushFloat(sign * f * decimal_scale);

        return p;
    }

    const char* matchFastFloatPart(const char* p, int sign, float f) {
        for (;;) {
            if (!is_digit(*p)) break;
            f = f * 10.f + (*p++ - '0');
            if (!is_digit(*p)) break;
            f = f * 10.f + (*p++ - '0');
        }

        if (!is_numeric(*p)) {
            // Matched (integral) float.
            this->pushFloat(sign * f);
            return p;
        }

        return (*p == '.') ? this->matchFastFloatDecimalPart(p + 1, sign, f, 0)
                           : nullptr;
    }

    const char* matchFast32OrFloat(const char* p) {
        int sign = 1;
        if (*p == '-') {
            sign = -1;
            ++p;
        }

        const auto* digits_start = p;

        int32_t n32 = 0;

        // This is the largest absolute int32 value we can handle before
        // risking overflow *on the next digit* (214748363).
        static constexpr int32_t kMaxInt32 = (std::numeric_limits<int32_t>::max() - 9) / 10;

        if (is_digit(*p)) {
            n32 = (*p++ - '0');
            for (;;) {
                if (!is_digit(*p) || n32 > kMaxInt32) break;
                n32 = n32 * 10 + (*p++ - '0');
            }
        }

        if (!is_numeric(*p)) {
            // Did we actually match any digits?
            if (p > digits_start) {
                this->pushInt32(sign * n32);
                return p;
            }
            return nullptr;
        }

        if (*p == '.') {
            const auto* decimals_start = ++p;

            int exp = 0;

            for (;;) {
                if (!is_digit(*p) || n32 > kMaxInt32) break;
                n32 = n32 * 10 + (*p++ - '0'); --exp;
                if (!is_digit(*p) || n32 > kMaxInt32) break;
                n32 = n32 * 10 + (*p++ - '0'); --exp;
            }

            if (!is_numeric(*p)) {
                // Did we actually match any digits?
                if (p > decimals_start) {
                    this->pushFloat(sign * n32 * pow10(exp));
                    return p;
                }
                return nullptr;
            }

            if (n32 > kMaxInt32) {
                // we ran out on n32 bits
                return this->matchFastFloatDecimalPart(p, sign, n32, exp);
            }
        }

        return this->matchFastFloatPart(p, sign, n32);
    }

    const char* matchNumber(const char* p, const char* p_stop) {
        if (const auto* fast = this->matchFast32OrFloat(p)) return fast;

        // slow fallback
        float f;
#if defined(__cpp_lib_to_chars)
        auto result = std::from_chars(p, p_stop + 1, f);
        if (result.ec == std::errc{}) {
            this->pushFloat(f);
            return result.ptr;
        }
#else
        char* matched;
        f = strtof(p, &matched);
        if (matched > p) {
            this->pushFloat(f);
            return matched;
        }
#endif // defined(__cpp_lib_to_chars)
        return this->error(nullptr, p, "invalid numeric token");
    }
};

void Write(const Value& v, SkWStream* stream) {
    // We use the address of these as special tags in the pending list.
    static const NullValue kArrayCloseTag,    // ]
                           kObjectCloseTag,   // }
                           kListSeparatorTag, // ,
                           kKeySeparatorTag;  // :

    std::vector<const Value*> pending{&v};

    do {
        const Value* val = pending.back();
        pending.pop_back();

        if (val == &kArrayCloseTag) {
            stream->writeText("]");
            continue;
        }

        if (val == &kObjectCloseTag) {
            stream->writeText("}");
            continue;
        }

        if (val == &kListSeparatorTag) {
            stream->writeText(",");
            continue;
        }

        if (val == &kKeySeparatorTag) {
            stream->writeText(":");
            continue;
        }

        switch (val->getType()) {
            case Value::Type::kNull:
                stream->writeText("null");
                break;
            case Value::Type::kBool:
                stream->writeText(*val->as<BoolValue>() ? "true" : "false");
                break;
            case Value::Type::kNumber:
                stream->writeScalarAsText(*val->as<NumberValue>());
                break;
            case Value::Type::kString:
                stream->writeText("\"");
                stream->writeText(val->as<StringValue>().begin());
                stream->writeText("\"");
                break;
            case Value::Type::kArray: {
                const auto& array = val->as<ArrayValue>();
                stream->writeText("[");
                // "val, val, .. ]" in reverse order
                pending.push_back(&kArrayCloseTag);
                if (array.size() > 0) {
                    bool last_value = true;
                    for (const Value* it = array.end() - 1; it >= array.begin(); --it) {
                        if (!last_value) pending.push_back(&kListSeparatorTag);
                        pending.push_back(it);
                        last_value = false;
                    }
                }
            } break;
            case Value::Type::kObject: {
                const auto& object = val->as<ObjectValue>();
                stream->writeText("{");
                // "key: val, key: val, .. }" in reverse order
                pending.push_back(&kObjectCloseTag);
                if (object.size() > 0) {
                    bool last_member = true;
                    for (const Member* it = object.end() - 1; it >= object.begin(); --it) {
                        if (!last_member) pending.push_back(&kListSeparatorTag);
                        pending.push_back(&it->fValue);
                        pending.push_back(&kKeySeparatorTag);
                        pending.push_back(&it->fKey);
                        last_member = false;
                    }
                }
            } break;
        }
    } while (!pending.empty());
}

}  // namespace

SkString Value::toString() const {
    SkDynamicMemoryWStream wstream;
    Write(*this, &wstream);
    const auto data = wstream.detachAsData();
    // TODO: is there a better way to pass data around without copying?
    return SkString(static_cast<const char*>(data->data()), data->size());
}

static constexpr size_t kMinChunkSize = 4096;

DOM::DOM(const char* data, size_t size) : fAlloc(kMinChunkSize) {
    DOMParser parser(fAlloc);

    fRoot = parser.parse(data, size);
}

void DOM::write(SkWStream* stream) const { Write(fRoot, stream); }

}  // namespace skjson
