Document
struct DocumentOwns the JSON input bytes and a packed tape of entries.
A Document is the storage unit produced by parsers. A Value view
references a tape entry inside a Document by index; when a Value
is mutated, the document is materialized into an owned tree
(OwnedValue in value/owned.mojo).
Side pools:
key_poolstores unescaped object keys. Object KEY entries store a pool offset rather than an offset intoinput, so unescaped keys survive even when the original bytes are released.string_poolstores unescaped STRING values that needed materialisation (e.g. escapes). Clean strings stay zero-copy as STRING (offset, length) entries intoinput.float_poolstoresFloat64values, since 64-bit IEEE 754 doesn't fit in 60 bits.int_poolholds integers too wide for the 60-bit inline payload, both signed (TAPE_TAG_INT_POOL) and unsigned (TAPE_TAG_UINT, stored as a bit pattern).
Implements Copyable, Movable
- Fields
input: Stringtape: List[UInt64]key_pool: List[String]string_pool: List[String]float_pool: List[Float64]int_pool: List[Int64]
__init__
def __init__(out self) def __init__(out self, var input: String) copy
def copy(self) -> Self append_null
def append_null(mut self) -> Int append_bool
def append_bool(mut self, b: Bool) -> Int append_int
def append_int(mut self, value: Int64) -> Int Append an integer, inline when it fits and pooled when not.
The inline payload is 60 bits, so anything outside
[-259, 259) has to spill. It used to be truncated instead,
which turned 576460752303423488 into its negative -- no
error, no warning, a different number.
append_uint
def append_uint(mut self, value: UInt64) -> Int Append a magnitude above Int64.MAX.
Stored as a bit pattern in the same pool; the tag is what says to read it back unsigned.
append_float
def append_float(mut self, value: Float64) -> Int append_string
def append_string(mut self, offset: Int, length: Int) -> Int Append a STRING entry referencing bytes [offset:offset+length] of input.
append_key
def append_key(mut self, var key: String) -> Int Intern a key into key_pool and append a KEY entry referencing it.
append_key_inline
def append_key_inline(mut self, offset: Int, length: Int) -> Int Append a zero-copy KEY entry referencing input[offset:offset+length].
Used for the by-far-common case where the JSON key contains no escapes -- avoids the per-key heap allocation, memcpy, and key_pool append.
append_string_owned
def append_string_owned(mut self, var value: String) -> Int Append a STRING_OWNED entry whose bytes live in string_pool.
Used for JSON strings that contain escapes (where a zero-copy
slice into input would expose the escaped bytes). Clean
strings stay on the zero-copy append_string path.
append_array
def append_array(mut self, count: Int, child_start_idx: Int) -> Int append_object
def append_object(mut self, pair_count: Int, child_start_idx: Int) -> Int get_tag
def get_tag(self, tape_idx: Int) -> UInt8 get_payload
def get_payload(self, tape_idx: Int) -> UInt64 get_bool
def get_bool(self, tape_idx: Int) -> Bool get_int
def get_int(self, tape_idx: Int) -> Int64 Read an integer entry, inline or pooled.
get_uint
def get_uint(self, tape_idx: Int) -> UInt64 Read an entry as an unsigned magnitude.
A TAPE_TAG_UINT entry is one that only fits here; the signed
tags are accepted too so a caller can ask this question of any
non-negative integer without checking the tag first.
get_float
def get_float(self, tape_idx: Int) -> Float64 get_string_offset
def get_string_offset(self, tape_idx: Int) -> Int get_string_length
def get_string_length(self, tape_idx: Int) -> Int get_string
def get_string(self, tape_idx: Int) -> String Materialize a STRING / STRING_OWNED entry as a fresh String.
- For
TAPE_TAG_STRING(clean / zero-copy), the returned string is a fresh copy of the slice ofinputreferenced by the (offset, length) payload. Safe even ifinputis later consumed. - For
TAPE_TAG_STRING_OWNED(had escapes at parse time), the string is read out ofstring_pooland returned as-is.
key_equals
def key_equals(self, tape_idx: Int, key: String) -> Bool Whether a KEY entry spells key, without materializing it.
get_key
def get_key(self, tape_idx: Int) -> String Return the unescaped key for a KEY / KEY_INLINE entry.
Dispatches on the tag: TAPE_TAG_KEY is a key_pool index (used
when the key had escapes, or when an upstream source produced
the key as an owned string); TAPE_TAG_KEY_INLINE is a
zero-copy (offset, length) slice into input that we copy
out on read.
get_count
def get_count(self, tape_idx: Int) -> Int Element count for ARRAY, pair count for OBJECT.
get_child_start
def get_child_start(self, tape_idx: Int) -> Int Tape index where this container's children start.
root
def root(self) -> Int Tape index of the root entry. Defined as the LAST entry, since builders write children before their parent so the parent can record a backwards-pointing child_start_idx.
size
def size(self) -> Int