Skip to content

About

A protocol buffers kernel and gRPC stack with the Google protobuf v4 application API

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5,377 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pbrs

Crates.io Documentation License

pbrs is a Protocol Buffers runtime and code generator with the Google protobuf v4 application API. The workspace also includes pbrs-grpc for gRPC over HTTP/2 and protobuf-tonic for using pbrs messages with tonic 0.14+.

Documentation · gRPC example · Benchmark results · Run benchmarks · Parity audit

Status: conformance is tested through Protocol Buffers Edition 2023. Edition 2024 generation supports a defined subset. The gRPC crates are previews; see the support policy for supported versions and deployment guidance. The benchmark results show measured improvements and remaining CPU, allocation and bulk losses. Each result names the source it tested; full performance and release qualification remain open. See implementation status for compatibility details.

If you use proto2 messages with required children or MessageSet, regenerate bindings to get the merge and MessageSet fixes. Contributors should start with what to work on next.

Regenerate bindings to let lazy child getters reuse earlier wire validation. Applications that read or mutate nested trees can also select Config::owned_message_fields(true). The default lazy profile supports partial reads and forwarding unchanged messages. See the current measurements and tradeoffs.

Features

  • Google protobuf v4 API: generated types use Parse, Serialize, Clear, proto!, ProtoStr, RepeatedView, and DynamicMessage.
  • Recorded conformance: Google's conformance_test_runner v35.1 passes 5,631 binary + JSON cases and 909 text cases with no unexpected results.
  • Formats and reflection: proto2, proto3, Edition 2023, well-known types (WKT), dynamic reflection, JSON, and text format.
  • Storage: small-string optimization, zero-allocation empty collections, lazy materialization after wire validation, and specialized packed-scalar handling are built into the runtime.

pbrs is an application API alternative, not a drop-in replacement for official generated internals or prost::Message. See the upb comparison and implementation status for the tested boundaries.

Quick start: install, generate, use

This quick start generates Rust from proto/person.proto during your Cargo build. Direct .proto generation requires protoc on your PATH; see code generation options if you want checked-in descriptors instead.

  1. Add pbrs as both a runtime and build dependency:

    [dependencies]
    pbrs = "0.2"
    
    [build-dependencies]
    pbrs = "0.2"
  2. Add a proto file at proto/person.proto:

    syntax = "proto3";
    package tutorial;
    
    message Person {
      string name = 1;
      int32 id = 2;
      string email = 3;
      repeated string phones = 4;
    }
  3. Generate Rust in build.rs:

    fn main() -> Result<(), Box<dyn std::error::Error>> {
        pbrs::codegen::compile_protos(&["proto/person.proto"], &["proto"])?;
        Ok(())
    }
  4. Include and use the generated type:

    use pbrs::prelude::*;
    
    include!(concat!(env!("OUT_DIR"), "/person.rs"));
    
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        let mut person = Person::new();
        person.set_name("Ada Lovelace");
        person.set_id(42);
        person.set_email("ada@example.com");
        person.phones_mut().push("555-0100");
    
        let bytes: Vec<u8> = person.serialize()?;
        let decoded = Person::parse(&bytes)?;
    
        assert_eq!(decoded.name(), "Ada Lovelace");
        assert_eq!(decoded.id(), 42);
    
        println!("Parsed: {} (ID: {})", decoded.name(), decoded.id());
        Ok(())
    }

For protos that define services, compile_protos emits native pbrs-grpc stubs by default. tonic users must opt in with Config::emit_tonic_stubs(true).

Which crate do I need?

Need Use Published Checkout candidate
Protocol Buffers messages, reflection, JSON/text, or code generation pbrs 0.2.0 0.2.1 (unreleased)
Native gRPC client and server pbrs-grpc 0.1.0-alpha.2 (published) 0.1.0-alpha.3 (unreleased preview)
tonic 0.14+ with pbrs messages protobuf-tonic 0.1.0-alpha.2 (published) 0.1.0-alpha.3 (unreleased preview)
Runnable service with health and reflection examples/greeter — Example

The installation examples use published versions. Checkout candidates and newer APIs are not available from crates.io until released.

Code generation options

Generating directly from .proto files needs protoc. Generating from a previously compiled descriptor set does not run protoc during the application build.

Task Needs protoc? Notes
Build the core pbrs crate No The crate uses a bundled FileDescriptorSet.
Build pbrs-grpc and protobuf-tonic (0.1.0-alpha.2 and later, or this checkout) No They build from checked descriptor sets.
Build the older pbrs-grpc / protobuf-tonic 0.1.0-alpha.1 crates Yes Those alphas predate the checked-descriptor change.
Run compile_protos or protoc-gen-pbrs on application .proto files Yes protoc must be on PATH.
Run Config::compile_descriptor_set from a checked descriptor set No during the app build Creating or updating the descriptor set still needs protoc.

There is no enforced universal protoc version; see the support matrix.

Direct .proto generation with build.rs

Use this when your build environment has protoc available:

fn main() -> Result<(), Box<dyn std::error::Error>> {
    pbrs::codegen::compile_protos(&["proto/person.proto"], &["proto"])?;
    Ok(())
}

Then include the generated file in src/lib.rs or src/main.rs:

include!(concat!(env!("OUT_DIR"), "/person.rs"));

Checked descriptor set generation

Use this when you want application builds to avoid running protoc. First create and check in a descriptor set with imports included:

protoc -I proto --include_imports --descriptor_set_out=proto/person.fds proto/person.proto

Then compile from that descriptor set:

fn main() -> Result<(), Box<dyn std::error::Error>> {
    pbrs::codegen::Config::new()
        .out_dir(std::env::var("OUT_DIR")?)
        .compile_descriptor_set("proto/person.fds", &["person.proto"], &["proto"])?;
    Ok(())
}

Descriptor targets use include-relative names such as person.proto. The descriptor and available source imports are tracked for rebuilds. See the codegen guide for native stubs, tonic stubs, and messages-only generation.

Against this checkout, a consumer using a checked descriptor set can cold-build messages, native stubs, and tonic stubs without protoc on its build PATH. The older 0.1.0-alpha.1 adapter archives still require it.

protoc-gen-pbrs plugin

Install or build the plugin binary:

cargo install --path . --bin protoc-gen-pbrs

Run protoc with the --pbrs_out flag:

protoc --pbrs_out=./gen --proto_path=./proto ./proto/hello.proto

Or use the helper script:

./scripts/gen.sh -I proto -o gen proto/your.proto

gRPC choices

Stack Choose it when Read more
pbrs-grpc native kernel You want the native gRPC client and server. gRPC guide, pbrs-grpc/README.md
protobuf-tonic adapter You already use tonic 0.14+ and can use regenerated pbrs stubs instead of prost messages. Middleware must accept those message traits. protobuf-tonic/README.md

For a complete service with generated stubs, health checking, and server reflection, see examples/greeter.

Support matrix

The table lists minimum Rust versions and configured CI checks. Actual compiler versions and results are recorded in the evidence guide. Releases follow the release guide; pushes to main do not publish crates.

The maintained crates and tools use Rust language Edition 2024, available from rustc 1.85. Frozen reference/comparator and discarded-experiment manifests keep their original edition for reproducibility. This is independent of Protocol Buffers Edition 2024.

Crate Declared MSRV CI checks protoc Stub default
pbrs 1.85 msrv-core 1.85 --lib, stable Linux + macOS Not required to build the crate (bundled FileDescriptorSet). Required for compile_protos / protoc-gen-pbrs. Messages; .proto service blocks emit native pbrs-grpc stubs
pbrs-grpc 1.85 msrv-core 1.85 --lib and stalled-upload checks, stable Linux + macOS Current source builds from checked FileDescriptorSets. Regenerating descriptors or compiling application .proto requires protoc; the older 0.1.0-alpha.1 release also requires it to build. Native kernel (compile_protos default)
protobuf-tonic 1.88 msrv-tonic 1.88 Current source builds from the checked FileDescriptorSet. Direct .proto compilation requires protoc; the older 0.1.0-alpha.1 release also requires it to build. Call Config::emit_tonic_stubs(true); not a prost::Message drop-in
examples/greeter 1.85 Stable Linux (--workspace) + macOS onboarding Required Native kernel default

Untested / unsupported (not a support commitment):

  • tonic 0.12 and 0.13 are unsupported.
  • Protocol Buffers Edition 2024 has descriptor and generated-consumer coverage for a defined subset; complete conformance beyond Edition 2023 is not qualified.
  • Windows CI is untested.

Performance and stack selection

The benchmark report is the short results page: codec, message shapes, gRPC vs tonic, and gRPC vs grpc-go. Each section names its host and what was compared. The roadmap scorecard tracks the remaining comparisons.

For large payloads and copy behavior, also see Large payloads / zero-copy.

Conformance and testing

pbrs is tested against Google's official protobuf test suite:

Suite Recorded result Scope
Official conformance_test_runner v35.1 required tests (×2) 5,631 binary + JSON, 0 unexpected failures Pinned runner through Edition 2023
Text format tests 909 text tests, 0 unexpected failures Pinned runner through Edition 2023
Recommended tests (--enforce_recommended) Passed with 0 unexpected failures Does not imply every upstream suite

The separate rust/test/shared coverage lists its exclusions. The enum-map repair and closed-enum tests record the later compatibility runs.

Run the conformance suite locally:

./scripts/fetch-protobuf.sh
./scripts/conformance.sh

Documentation

The documentation map helps you choose a guide. For task status, use python3 scripts/plan-status.py --ready; for API details, run cargo doc --workspace --no-deps --open.

Topic Start here
Architecture and crate boundaries Architecture overview
Runtime design and storage choices Design and internals
API and representation differences from Google's C-based upb kernel Relative to upb
Measurements and known losses Benchmarks
Large payloads and copy behavior Large payloads / zero-copy
Supported features and conformance breakdown Implementation status
Native pbrs-grpc services Native gRPC kernel guide
Code generation, RPC shapes, interceptors, and operations recipes Task guides and recipes
tonic 0.14+ integration Tonic adapter guide
Toolchain and protoc requirements Support matrix
Publishing policy Release policy
Roadmap and remaining work Implementation plan and scorecard
Next contribution and audit findings Execution queue, repository audit, task contracts
gRPC performance work Performance plan and task cards
Adopting pbrs in existing prost/tonic systems Adoption program
Every-cell comparison against tonic and prost Workload comparison plan

License

Licensed under either of:

at your option.

About

A protocol buffers kernel and gRPC stack with the Google protobuf v4 application API

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages