pbrs 0.2.0

Pure-Rust Protocol Buffers kernel with the Google protobuf v4 application API
Documentation
# pbrs

[![Crates.io](https://img.shields.io/crates/v/pbrs.svg)](https://crates.io/crates/pbrs)
[![Documentation](https://docs.rs/pbrs/badge.svg)](https://docs.rs/pbrs)
[![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE-MIT)

`pbrs` is a pure-Rust Protocol Buffers runtime and code generator for Rust
developers who want the Google protobuf v4 application API without a C or C++
runtime. This workspace also contains `pbrs-grpc` for native gRPC over HTTP/2
and `protobuf-tonic` for tonic 0.14+ users.

**Current status:** published versions are available for evaluation, with
recorded conformance through Protocol Buffers Edition 2023; production
qualification and stronger performance claims still require the evidence in
the [roadmap](docs/ROADMAP.md).

## Why use pbrs?

- **Pure Rust build:** `pbrs` compiles with `rustc`. It does not wrap Google's
  `upb` C library through foreign function interface (FFI).
- **Google protobuf v4-shaped API:** generated types use the application-level
  traits and shapes such as `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.
- **Broad protobuf surface:** proto2, proto3, Edition 2023 behavior,
  well-known types (WKT), dynamic reflection, JSON formatting, and text
  formatting are in scope.
- **Performance-oriented 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](docs/upb.md) and [implementation status](docs/status.md) 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](#code-generation-options) if you want checked-in
descriptors instead.

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

   ```toml
   [dependencies]
   pbrs = "0.2"

   [build-dependencies]
   pbrs = "0.2"
   ```

2. Add a proto file at `proto/person.proto`:

   ```protobuf
   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`:

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

4. Include and use the generated type:

   ```rust
   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)`](protobuf-tonic/README.md).

## Which crate do I need?

| Need | Use | Notes |
|---|---|---|
| Protocol Buffers messages, parsing, serialization, reflection, JSON/text, or code generation | [`pbrs`]. | Core crate and `protoc-gen-pbrs` plugin |
| Native Rust gRPC without tonic | [`pbrs-grpc`]pbrs-grpc | HTTP/2 gRPC client/server kernel built on `h2`, `rustls`, and Graviola |
| tonic 0.14+ services that use `pbrs` messages | [`protobuf-tonic`]protobuf-tonic | Codec adapter; not a `prost::Message` drop-in |
| End-to-end reference service | [`examples/greeter`]examples/greeter | Generated stubs, health checks, and server reflection |

## Workspace Crates

| Crate | What it contains | crates.io Status |
|---|---|---|
| [`pbrs`]. | Core Protocol Buffers runtime: parser, serializer, code generator (`protoc-gen-pbrs`), dynamic messages, well-known types, JSON format, and text format. | `0.2.0` (Published; qualification in progress) |
| [`pbrs-grpc`]pbrs-grpc | Standalone pure-Rust HTTP/2 gRPC client and server kernel. It does not depend on C or tonic. | `0.1.0-alpha.2` (Pre-release / Preview) |
| [`protobuf-tonic`]protobuf-tonic | tonic 0.14+ `Codec` adapter for clients and servers that use regenerated `pbrs` message types. | `0.1.0-alpha.2` (Pre-release / Preview) |
| [`examples/greeter`]examples/greeter | Complete example with generated stubs, gRPC health checking (`grpc.health.v1`), and server reflection (`grpc.reflection.v1`). | Example only (`publish = false`) |

## 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](#support-matrix).

### Direct `.proto` generation with `build.rs`

Use this when your build environment has `protoc` available:

```rust
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`:

```rust
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:

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

Then compile from that descriptor set:

```rust
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](docs/guides/codegen.md) 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:

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

Run `protoc` with the `--pbrs_out` flag:

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

Or use the helper script:

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

## gRPC choices

| Stack | Choose it when | Read more |
|---|---|---|
| `pbrs-grpc` native kernel | You want a pure-Rust gRPC client/server stack independent of tonic. | [gRPC guide]docs/grpc.md, [`pbrs-grpc/README.md`]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`]protobuf-tonic/README.md |

For a complete service with generated stubs, health checking, and server
reflection, see [`examples/greeter`](examples/greeter).

## Support matrix

Recorded against this repository on stable `rustc` 1.98. Declared
`rust-version` is the continuous integration (CI) minimum supported Rust
version (MSRV) job, not this host's toolchain. Releases follow the
[release guide](docs/RELEASE.md): tag/dispatch only; `main` pushes do not
publish.

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 | Tested | `protoc` | Stub default |
|---|---|---|---|---|
| [`pbrs`]. | 1.85 | rustc 1.98 (this host); CI `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`]pbrs-grpc | 1.85 | rustc 1.98 (this host); CI `msrv-core` 1.85 `--lib` (incl. `tcp::tests`), stable Linux + macOS | **Current source:** no compiler needed to build from checked FileDescriptorSets; required to regenerate descriptors or compile application `.proto`. **Older `0.1.0-alpha.1`:** still requires `protoc`. | Native kernel (`compile_protos` default) |
| [`protobuf-tonic`]protobuf-tonic | 1.88 | rustc 1.98 (this host); CI `msrv-tonic` 1.88 | **Current source:** no compiler needed to build from the checked FileDescriptorSet. **Older `0.1.0-alpha.1`:** still requires `protoc`. Direct `.proto` compilation needs it in either version. | Must call [`Config::emit_tonic_stubs(true)`]protobuf-tonic/README.md; not a `prost::Message` drop-in |
| [`examples/greeter`]examples/greeter | 1.85 | rustc 1.98 (this host); CI 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 descriptor fixtures are tested, but generated
  consumers and conformance beyond Edition 2023 are **not qualified**.
- Windows CI is **untested**.

## Performance and stack selection

Use the [benchmark report](docs/benchmarks.md) for versioned,
workload-specific comparisons with prost, the Google Rust/upb wrapper, buffa,
tonic, and grpc-go. Those results include wins, losses, and caveats; they do
not establish universal feature parity or superiority. The
[roadmap scorecard](docs/ROADMAP.md#scorecard) defines the evidence needed for
stronger claims.

For large payloads and copy behavior, also see
[Large payloads / zero-copy](docs/zero-copy.md).

## 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](docs/status.md#skipped-rusttestshared-files)
has documented exclusions.

Run the conformance suite locally:

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

## Documentation

| Topic | Start here |
|---|---|
| Architecture and crate boundaries | [Architecture overview]docs/architecture.md |
| Runtime design and storage choices | [Design and internals]docs/design.md |
| API and representation differences from Google's C-based upb kernel | [Relative to upb]docs/upb.md |
| Performance numbers, caveats, and losses | [Benchmarks and performance]docs/benchmarks.md |
| Large payloads and copy behavior | [Large payloads / zero-copy]docs/zero-copy.md |
| Supported features and conformance breakdown | [Implementation status]docs/status.md |
| Native `pbrs-grpc` services | [Native gRPC kernel guide]docs/grpc.md |
| Code generation, RPC shapes, interceptors, and operations recipes | [Task guides and recipes]docs/guides/rpc-shapes.md |
| tonic 0.14+ integration | [Tonic adapter guide]protobuf-tonic/README.md |
| Toolchain and `protoc` requirements | [Support matrix]#support-matrix |
| Publishing policy | [Release policy]docs/RELEASE.md |
| Roadmap and stronger-claim evidence | [Implementation plan and scorecard]docs/ROADMAP.md |
| Current execution planning | [Granular execution plan]docs/plan/README.md, [task cards]docs/plan/tasks.json, [execution queue]TODO.md |
| gRPC performance program | [World-class gRPC program]docs/plan/world-class/README.md and [worker cards]docs/plan/world-class/tasks.json |

## License

Licensed under either of:

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE)
- MIT License ([LICENSE-MIT]LICENSE-MIT)

at your option.