# flare.grpc.framing

> A module of flare_mlake's API.

``gRPC`` length-prefix-message (LPM) framing codec.

Every gRPC message on the wire is a 5-byte header followed by an
opaque payload:

```
+--------+----------------+---------------+
| Flag   | Length (BE32)  | Payload bytes |
| (1B)   |   (4 bytes)    |  (Length B)   |
+--------+----------------+---------------+
```

- **Flag** (1 byte): bit 0 is the "compressed" flag (1 = the
  payload is compressed with the message-level codec negotiated
  via ``grpc-encoding``; 0 = uncompressed). All other bits are
  reserved and must be zero.
- **Length** (4 bytes, big-endian): the byte count of the
  payload that follows. The wire-level maximum is 2^32 - 1; a
  per-channel ``max-receive-message-length`` policy lives at a
  higher layer.
- **Payload**: opaque serialized protobuf (or other codec)
  bytes.

This is the wire format used by both unary RPCs (one frame in
each direction) and streaming RPCs (multiple frames per stream).
HTTP/2 DATA frames may carry a partial LPM frame or several
back-to-back; the decoder must therefore handle "need more data"
gracefully without throwing on a clean truncation at the
buffer boundary.

References:
- https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
- https://grpc.io/docs/what-is-grpc/core-concepts/ (call shapes)

## Structs

### `GrpcCompressionFlag`

```mojo
struct GrpcCompressionFlag
```

Typed wrapper around the LPM flag byte. ``is_compressed()`` returns True when bit 0 is set; ``raw`` exposes the byte for callers that need to forward greased / extension bits without interpretation.

Implements: `Copyable`, `Movable`

Fields:

- `raw: UInt8`

#### `is_compressed`

```mojo
def is_compressed(self) -> Bool
```

#### `has_reserved_bits`

```mojo
def has_reserved_bits(self) -> Bool
```

Return True if any reserved bit (bits 1..7) is set. Callers may treat this as a protocol violation; the codec itself accepts the bits to remain forward-compatible with future spec extensions.

### `GrpcMessage`

```mojo
struct GrpcMessage
```

A decoded LPM frame: flag + opaque payload bytes.

Implements: `Copyable`, `Movable`

Fields:

- `flag: GrpcCompressionFlag`
- `payload: List[UInt8]`

### `GrpcDecodeResult`

```mojo
struct GrpcDecodeResult
```

Outcome of an LPM decode attempt.

The decoder operates on a streaming buffer where the message
boundary may not yet be visible. ``needs_more`` is True when
the buffer is too short to contain a complete frame; callers
should accumulate more bytes and try again. ``message`` is
populated only when ``needs_more`` is False.

Implements: `Copyable`, `Movable`

Fields:

- `message: GrpcMessage`
- `consumed: Int`
- `needs_more: Bool`

## Functions

### `encode_grpc_message`

```mojo
def encode_grpc_message(payload: Span[UInt8], mut out: List[UInt8], compressed: Bool = False)
```

Append a length-prefix-message (LPM) frame to ``out``.

The frame is a single byte compression flag plus a 4-byte
big-endian length plus the payload bytes. The caller is
responsible for compressing the payload before calling this
function if ``compressed=True``; the framer just sets the
flag byte and prefixes the length.

The caller owns the buffer and may reuse the same
``List[UInt8]`` across calls so the underlying allocation
amortises across the stream. The encoder appends only; it
never reads from or truncates the existing contents.

### `decode_grpc_message`

```mojo
def decode_grpc_message(buf: Span[UInt8]) -> GrpcDecodeResult
```

Decode the first complete LPM frame at the start of ``buf``.

Returns ``needs_more=True`` (and an empty placeholder
message) when the buffer is shorter than the declared frame.
Raises only on hard errors -- in this version the only hard
error is a payload length that would overflow Mojo's ``Int``
when the framer eventually accumulates ``consumed`` bytes
(which would require a length declaration > 2^31; the wire
format allows up to 2^32 - 1 but Mojo's ``Int`` is 64-bit so
this is purely defensive).

## Aliases

### `GRPC_COMPRESSION_NONE`

```mojo
comptime GRPC_COMPRESSION_NONE = UInt8(0)
```

### `GRPC_COMPRESSION_COMPRESSED`

```mojo
comptime GRPC_COMPRESSION_COMPRESSED = UInt8(1)
```

LPM flag-byte values. Other bits are reserved (RFC for HTTP/2- based gRPC framing) and must be zero on the wire.
