Skip to content

mojo-protobuf

mojo-protobuf is a Protocol Buffers serializer written in Mojo. The runtime and the code generator are Mojo. They do not wrap libprotobuf or any other C, C++, or Rust protobuf library.

  • Why ProtoBuf


    What the format is for, how tags and varints work on the wire, and why the encoder is not a small wrapper around a native library.

    Read Why ProtoBuf

  • Instructions


    Install Mojo 1.1.0 with pixi, generate Mojo from a .proto file, run the tests, and publish this site.

    Open Instructions

  • Examples


    Encode and decode generated types, match official protoc --encode bytes, and round-trip an empty present submessage.

    See Examples

  • Test data


    What lives under testdata/ (schemas, oracle bytes, descriptor blobs, official conformance inputs) and why each file is there.

    Read Test data


What it does

Feature Meaning
From-scratch Mojo The runtime and gld-protoc-mojo are Mojo. They do not wrap, link, or vendor libprotobuf.
proto3 wire Varint, ZigZag, tags, packed and unpacked repeated values, and empty present submessages (1a 00).
FileDescriptorSet A hand-written proto2 decoder reads the blob that protoc --descriptor_set_out writes.
Code generator gld-protoc-mojo emits Mojo structs with explicit encode_to / merge_from methods.
Implicit presence proto3 scalars omit zero, false, and empty string on encode.
Nested presence A set-but-empty nested message is written as tag plus length 0. Official Python does the same.
Packed repeated Encode writes one LEN record. Decode also accepts the older unpacked form.
Unknown fields Generated types keep unknown records and write them back. --unknown skip is opt-in.
Interop Golden vectors come from official protoc --encode. tests_interop/ pipes the same bytes.
Conformance conformance/adapter.mojo uses uint32-LE framing. Binary proto3 TestAllTypesProto3 only.
Package mojo-protobuf on prefix.dev/leo-gan/leo-gan. pixi add --channel https://prefix.dev/leo-gan/leo-gan mojo-protobuf.
proto3 types All proto3 scalars, enums, nested messages, packed and unpacked repeated, oneof, map, proto3 optional.

protoc is a build-time host tool. Python google.protobuf is a test oracle. Neither is required to encode or decode at runtime.


Quick start

Install pixi, then:

git clone https://github.com/leo-gan/gld-protobuf.git
cd gld-protobuf
pixi install
pixi run generate

Encode a generated Message:

pixi run mojo run -I src -I tests/generated examples/encode_message.mojo

Run the suite:

pixi run test

Requires Mojo 1.1.0. If pixi install fails on conda.modular.com, see Instructions.


Encode example

examples/encode_message.mojo builds a benchmark.v2.Message, encodes it, and decodes the same bytes:

from benchmark.v2 import Message

def main() raises:
    var msg = Message()
    msg.f_bool = True
    msg.f_int32 = 150
    msg.f_string = "hi"
    var buf = msg.encode()
    var again = Message.decode(buf)

A fuller value matches official protoc --encode byte for byte. Field-by-field hex and the empty-meta / packed-repeated cases are on Examples.