thrift · API

thrift.protocol

Apache Thrift wire protocols in pure Mojo — serialization only, no RPC.

Two protocols are implemented, each as a reader over a borrowed Span[UInt8] and a writer that appends to an owned List[UInt8]:

  • TCompactProtocolReader / TCompactProtocolWriter — the variable-length encoding described in doc/specs/thrift-compact-protocol.md. This is what Apache Parquet uses for its footer and page headers.
  • TBinaryProtocolReader / TBinaryProtocolWriter — the fixed-width big-endian encoding from doc/specs/thrift-binary-protocol.md, in both strict (versioned) and non-strict message framing.

Both conform to the TProtocolReader / TProtocolWriter traits, so generated struct code can be written once and used with either.

Everything is bounds checked. A truncated buffer, a bad protocol id or version, a negative length, a container whose declared element count cannot possibly fit in the bytes that remain, or a nesting depth beyond MAX_SKIP_DEPTH raises rather than reading out of bounds or allocating on a size an attacker chose.

Structs

TCompactProtocolReader

struct TCompactProtocolReader[origin: ImmOrigin]

Decodes TCompactProtocol from a borrowed byte span.

Implements Copyable, Movable, TProtocolReader

Fields
data: Span[UInt8, origin]
pos: Int

__init__

def __init__(out self, data: Span[UInt8, origin])
def __init__(out self, data: Span[UInt8, origin], pos: Int)

offset

def offset(self) -> Int

remaining

def remaining(self) -> Int

read_message_begin

def read_message_begin(mut self) -> Tuple[String, Int8, Int32]

read_message_end

def read_message_end(mut self)

read_struct_begin

def read_struct_begin(mut self)

read_struct_end

def read_struct_end(mut self)

read_field_begin

def read_field_begin(mut self) -> Tuple[Int8, Int16]

read_field_end

def read_field_end(mut self)

read_map_begin

def read_map_begin(mut self) -> Tuple[Int8, Int8, Int]

read_map_end

def read_map_end(mut self)

read_list_begin

def read_list_begin(mut self) -> Tuple[Int8, Int]

read_list_end

def read_list_end(mut self)

read_set_begin

def read_set_begin(mut self) -> Tuple[Int8, Int]

read_set_end

def read_set_end(mut self)

read_bool

def read_bool(mut self) -> Bool

read_byte

def read_byte(mut self) -> Int8

read_i16

def read_i16(mut self) -> Int16

read_i32

def read_i32(mut self) -> Int32

read_i64

def read_i64(mut self) -> Int64

read_double

def read_double(mut self) -> Float64

read_binary

def read_binary(mut self) -> List[UInt8]

read_binary_view

def read_binary_view(mut self) -> Span[UInt8, origin]

Zero-copy variant of read_binary, valid as long as the input is.

read_string

def read_string(mut self) -> String

read_uuid

def read_uuid(mut self) -> List[UInt8]

skip

def skip(mut self, ttype: Int8)

TCompactProtocolWriter

struct TCompactProtocolWriter

Encodes TCompactProtocol into an owned byte list.

Implements Copyable, Defaultable, Movable, Sized, TProtocolWriter

Fields
out: List[UInt8]

__init__

def __init__(out self)
def __init__(out self, capacity: Int)

__len__

def __len__(self) -> Int

take

def take(deinit self) -> List[UInt8]

bytes

def bytes(self) -> List[UInt8]

write_message_begin

def write_message_begin(mut self, name: StringSpan, mtype: Int8, seqid: Int32)

write_message_end

def write_message_end(mut self)

write_struct_begin

def write_struct_begin(mut self)

write_struct_end

def write_struct_end(mut self)

write_field_begin

def write_field_begin(mut self, ftype: Int8, fid: Int16)

write_field_end

def write_field_end(mut self)

write_field_stop

def write_field_stop(mut self)

write_map_begin

def write_map_begin(mut self, ktype: Int8, vtype: Int8, size: Int)

write_map_end

def write_map_end(mut self)

write_list_begin

def write_list_begin(mut self, etype: Int8, size: Int)

write_list_end

def write_list_end(mut self)

write_set_begin

def write_set_begin(mut self, etype: Int8, size: Int)

write_set_end

def write_set_end(mut self)

write_bool

def write_bool(mut self, value: Bool)

write_byte

def write_byte(mut self, value: Int8)

write_i16

def write_i16(mut self, value: Int16)

write_i32

def write_i32(mut self, value: Int32)

write_i64

def write_i64(mut self, value: Int64)

write_double

def write_double(mut self, value: Float64)

write_binary

def write_binary(mut self, value: Span[UInt8])

write_string

def write_string(mut self, value: StringSpan)

write_uuid

def write_uuid(mut self, value: Span[UInt8])

TBinaryProtocolReader

struct TBinaryProtocolReader[origin: ImmOrigin]

Decodes TBinaryProtocol (strict or non-strict) from a byte span.

Implements Copyable, Movable, TProtocolReader

Fields
data: Span[UInt8, origin]
pos: Int
strict_read: Bool

__init__

def __init__(out self, data: Span[UInt8, origin])
def __init__(out self, data: Span[UInt8, origin], *, strict_read: Bool)

offset

def offset(self) -> Int

remaining

def remaining(self) -> Int

read_message_begin

def read_message_begin(mut self) -> Tuple[String, Int8, Int32]

read_message_end

def read_message_end(mut self)

read_struct_begin

def read_struct_begin(mut self)

read_struct_end

def read_struct_end(mut self)

read_field_begin

def read_field_begin(mut self) -> Tuple[Int8, Int16]

read_field_end

def read_field_end(mut self)

read_map_begin

def read_map_begin(mut self) -> Tuple[Int8, Int8, Int]

read_map_end

def read_map_end(mut self)

read_list_begin

def read_list_begin(mut self) -> Tuple[Int8, Int]

read_list_end

def read_list_end(mut self)

read_set_begin

def read_set_begin(mut self) -> Tuple[Int8, Int]

read_set_end

def read_set_end(mut self)

read_bool

def read_bool(mut self) -> Bool

read_byte

def read_byte(mut self) -> Int8

read_i16

def read_i16(mut self) -> Int16

read_i32

def read_i32(mut self) -> Int32

read_i64

def read_i64(mut self) -> Int64

read_double

def read_double(mut self) -> Float64

read_binary

def read_binary(mut self) -> List[UInt8]

read_binary_view

def read_binary_view(mut self) -> Span[UInt8, origin]

read_string

def read_string(mut self) -> String

read_uuid

def read_uuid(mut self) -> List[UInt8]

skip

def skip(mut self, ttype: Int8)

TBinaryProtocolWriter

struct TBinaryProtocolWriter

Encodes TBinaryProtocol into an owned byte list.

Implements Copyable, Defaultable, Movable, Sized, TProtocolWriter

Fields
out: List[UInt8]
strict_write: Bool

__init__

def __init__(out self)
def __init__(out self, *, strict_write: Bool)

__len__

def __len__(self) -> Int

take

def take(deinit self) -> List[UInt8]

bytes

def bytes(self) -> List[UInt8]

write_message_begin

def write_message_begin(mut self, name: StringSpan, mtype: Int8, seqid: Int32)

write_message_end

def write_message_end(mut self)

write_struct_begin

def write_struct_begin(mut self)

write_struct_end

def write_struct_end(mut self)

write_field_begin

def write_field_begin(mut self, ftype: Int8, fid: Int16)

write_field_end

def write_field_end(mut self)

write_field_stop

def write_field_stop(mut self)

write_map_begin

def write_map_begin(mut self, ktype: Int8, vtype: Int8, size: Int)

write_map_end

def write_map_end(mut self)

write_list_begin

def write_list_begin(mut self, etype: Int8, size: Int)

write_list_end

def write_list_end(mut self)

write_set_begin

def write_set_begin(mut self, etype: Int8, size: Int)

write_set_end

def write_set_end(mut self)

write_bool

def write_bool(mut self, value: Bool)

write_byte

def write_byte(mut self, value: Int8)

write_i16

def write_i16(mut self, value: Int16)

write_i32

def write_i32(mut self, value: Int32)

write_i64

def write_i64(mut self, value: Int64)

write_double

def write_double(mut self, value: Float64)

write_binary

def write_binary(mut self, value: Span[UInt8])

write_string

def write_string(mut self, value: StringSpan)

write_uuid

def write_uuid(mut self, value: Span[UInt8])

Traits

TProtocolReader

The read half of the Thrift protocol surface.

Generated struct readers are written against this trait, so the same code decodes compact and binary streams.

read_message_begin

def read_message_begin(mut self) -> Tuple[String, Int8, Int32]

read_message_end

def read_message_end(mut self)

read_struct_begin

def read_struct_begin(mut self)

read_struct_end

def read_struct_end(mut self)

read_field_begin

def read_field_begin(mut self) -> Tuple[Int8, Int16]

read_field_end

def read_field_end(mut self)

read_map_begin

def read_map_begin(mut self) -> Tuple[Int8, Int8, Int]

read_map_end

def read_map_end(mut self)

read_list_begin

def read_list_begin(mut self) -> Tuple[Int8, Int]

read_list_end

def read_list_end(mut self)

read_set_begin

def read_set_begin(mut self) -> Tuple[Int8, Int]

read_set_end

def read_set_end(mut self)

read_bool

def read_bool(mut self) -> Bool

read_byte

def read_byte(mut self) -> Int8

read_i16

def read_i16(mut self) -> Int16

read_i32

def read_i32(mut self) -> Int32

read_i64

def read_i64(mut self) -> Int64

read_double

def read_double(mut self) -> Float64

read_binary

def read_binary(mut self) -> List[UInt8]

read_string

def read_string(mut self) -> String

read_uuid

def read_uuid(mut self) -> List[UInt8]

skip

def skip(mut self, ttype: Int8)

offset

def offset(self) -> Int

remaining

def remaining(self) -> Int

TProtocolWriter

The write half of the Thrift protocol surface.

write_message_begin

def write_message_begin(mut self, name: StringSpan, mtype: Int8, seqid: Int32)

write_message_end

def write_message_end(mut self)

write_struct_begin

def write_struct_begin(mut self)

write_struct_end

def write_struct_end(mut self)

write_field_begin

def write_field_begin(mut self, ftype: Int8, fid: Int16)

write_field_end

def write_field_end(mut self)

write_field_stop

def write_field_stop(mut self)

write_map_begin

def write_map_begin(mut self, ktype: Int8, vtype: Int8, size: Int)

write_map_end

def write_map_end(mut self)

write_list_begin

def write_list_begin(mut self, etype: Int8, size: Int)

write_list_end

def write_list_end(mut self)

write_set_begin

def write_set_begin(mut self, etype: Int8, size: Int)

write_set_end

def write_set_end(mut self)

write_bool

def write_bool(mut self, value: Bool)

write_byte

def write_byte(mut self, value: Int8)

write_i16

def write_i16(mut self, value: Int16)

write_i32

def write_i32(mut self, value: Int32)

write_i64

def write_i64(mut self, value: Int64)

write_double

def write_double(mut self, value: Float64)

write_binary

def write_binary(mut self, value: Span[UInt8])

write_string

def write_string(mut self, value: StringSpan)

write_uuid

def write_uuid(mut self, value: Span[UInt8])

Functions

type_name

def type_name(t: Int8) -> String

A human name for a Thrift type id, for error messages.

zigzag_i32

def zigzag_i32(n: Int32) -> UInt64

(n << 1) ^ (n >> 31), computed wide so it cannot overflow.

zigzag_i64

def zigzag_i64(n: Int64) -> UInt64

(n << 1) ^ (n >> 63) in the unsigned domain (Int64.MIN is fine).

unzigzag_i64

def unzigzag_i64(u: UInt64) -> Int64

The inverse of zigzag_i64.

unzigzag_i32

def unzigzag_i32(u: UInt64) -> Int32

The inverse of zigzag_i32, range-checked.

skip_value

def skip_value[P: TProtocolReader, //](mut p: P, ttype: Int8, depth: Int)

Consume one value of ttype without materialising it.

Forward compatibility depends on this: a reader that meets a field id it does not know must still be able to step over the value, whatever shape it has.

Aliases

comptime T_STOP = Int8(0)
comptime T_VOID = Int8(1)
comptime T_BOOL = Int8(2)
comptime T_BYTE = Int8(3)
comptime T_DOUBLE = Int8(4)
comptime T_I16 = Int8(6)
comptime T_I32 = Int8(8)
comptime T_I64 = Int8(10)
comptime T_STRING = Int8(11)
comptime T_STRUCT = Int8(12)
comptime T_MAP = Int8(13)
comptime T_SET = Int8(14)
comptime T_LIST = Int8(15)
comptime T_UUID = Int8(16)
comptime T_I08 = T_BYTE
comptime T_BINARY = T_STRING
comptime COMPACT_PROTOCOL_ID = UInt8(130)
comptime COMPACT_VERSION = UInt8(1)
comptime COMPACT_VERSION_MASK = UInt8(31)
comptime COMPACT_TYPE_MASK = UInt8(224)
comptime COMPACT_TYPE_SHIFT_AMOUNT = 5
comptime C_STOP = UInt8(0)
comptime C_BOOLEAN_TRUE = UInt8(1)
comptime C_BOOLEAN_FALSE = UInt8(2)
comptime C_BYTE = UInt8(3)
comptime C_I16 = UInt8(4)
comptime C_I32 = UInt8(5)
comptime C_I64 = UInt8(6)
comptime C_DOUBLE = UInt8(7)
comptime C_BINARY = UInt8(8)
comptime C_LIST = UInt8(9)
comptime C_SET = UInt8(10)
comptime C_MAP = UInt8(11)
comptime C_STRUCT = UInt8(12)
comptime C_UUID = UInt8(13)
comptime BINARY_VERSION_1 = UInt32(2147549184)
comptime BINARY_VERSION_MASK = UInt32(4294901760)
comptime MESSAGE_CALL = Int8(1)
comptime MESSAGE_REPLY = Int8(2)
comptime MESSAGE_EXCEPTION = Int8(3)
comptime MESSAGE_ONEWAY = Int8(4)
comptime MAX_SKIP_DEPTH = 64
comptime MAX_VARINT_BYTES = 10