flare_mlake · API · grpc

flare.grpc.proto

flare.grpc.proto -- proto3 wire-format codec.

gRPC payloads are protobuf messages. Until now handler bodies had to hand-roll List[UInt8] payloads with no serializer; this module is that serializer -- the runtime the generated code (or a hand-written message struct) targets.

proto3 binary wire format (https://protobuf.dev/programming-guides/encoding/): a message is a flat sequence of (tag, value) records. The tag is a varint (field_number << 3) | wire_type:

  • 0 VARINT -- int32/64, uint32/64, sint32/64 (zigzag), bool, enum
  • 1 I64 -- fixed64, sfixed64, double
  • 2 LEN -- string, bytes, embedded message, packed repeated
  • 5 I32 -- fixed32, sfixed32, float

:class:ProtoWriter appends typed fields to an owned buffer; :class:ProtoReader walks a buffer field by field and decodes by wire type, with :meth:ProtoReader.skip for unknown fields (proto3 forward compatibility). proto3 omits scalar fields equal to their default (0 / false / empty) on the wire -- the writers here are low-level (they always emit), so the caller / codegen applies the default-skip policy.

This is a sans-I/O codec: bytes in, bytes out. No reflection, no descriptors -- those live in :mod:flare.grpc.reflection.

Structs

ProtoWriter

struct ProtoWriter

Accumulates proto3-encoded fields into an owned byte buffer.

Example:

var w = ProtoWriter()
w.write_string(1, "hello")     # field 1: string
w.write_int64(2, 42)           # field 2: int64
w.write_bool(3, True)          # field 3: bool
var payload = w.take()         # List[UInt8] ready for LPM framing

Implements Copyable, Movable

Fields
buf: List[UInt8]

__init__

def __init__(out self)

__len__

def __len__(self) -> Int

take

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

Move the accumulated bytes out, leaving the writer empty.

bytes

def bytes(self) -> List[UInt8]

Copy the accumulated bytes (writer stays usable).

write_uint64

def write_uint64(mut self, field: Int, value: UInt64)

write_int64

def write_int64(mut self, field: Int, value: Int64)

write_sint64

def write_sint64(mut self, field: Int, value: Int64)

write_bool

def write_bool(mut self, field: Int, value: Bool)

write_enum

def write_enum(mut self, field: Int, value: Int)

write_fixed64

def write_fixed64(mut self, field: Int, value: UInt64)

write_fixed32

def write_fixed32(mut self, field: Int, value: UInt32)

write_double

def write_double(mut self, field: Int, value: Float64)

write_float

def write_float(mut self, field: Int, value: Float32)

write_bytes

def write_bytes(mut self, field: Int, value: Span[UInt8])

A length-delimited field: the tag, the length, then the bytes.

The bytes are copied in one go. A byte at a time is invisible on a string field and is the whole cost of a large one — Arrow Flight puts a record batch in data_body, so this copy is as big as the data the server is sending.

write_string

def write_string(mut self, field: Int, value: String)

write_message

def write_message(mut self, field: Int, sub: Span[UInt8])

Embed a pre-encoded sub-message (its own proto3 bytes).

ProtoReader

struct ProtoReader

Walks a proto3-encoded buffer field by field.

Typical loop::

var r = ProtoReader(payload)
while r.has_more():
    var tw = r.read_tag()       # (field_number, wire_type)
    if tw[0] == 1 and tw[1] == WIRE_LEN:
        var name = r.read_string()
    elif tw[0] == 2 and tw[1] == WIRE_VARINT:
        var age = r.read_int64()
    else:
        r.skip(tw[1])           # unknown field: forward-compat

Implements Copyable, Movable

Fields
data: List[UInt8]
pos: Int

__init__

def __init__(out self, buf: Span[UInt8])

Takes its own copy, so the reader outlives the span it was given.

One copy, for the same reason write_bytes makes one: a response being decoded is as large as the payload in it.

has_more

def has_more(self) -> Bool

read_tag

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

read_uint64

def read_uint64(mut self) -> UInt64

read_int64

def read_int64(mut self) -> Int64

read_sint64

def read_sint64(mut self) -> Int64

read_bool

def read_bool(mut self) -> Bool

read_enum

def read_enum(mut self) -> Int

read_fixed64

def read_fixed64(mut self) -> UInt64

read_fixed32

def read_fixed32(mut self) -> UInt32

read_double

def read_double(mut self) -> Float64

read_float

def read_float(mut self) -> Float32

read_bytes

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

read_string

def read_string(mut self) -> String

skip

def skip(mut self, wire: Int)

Advance past one field's value of the given wire type (proto3 unknown-field forward compatibility).

Aliases

comptime WIRE_VARINT = Int(0)
comptime WIRE_I64 = Int(1)
comptime WIRE_LEN = Int(2)
comptime WIRE_I32 = Int(5)