Bug: 158620710

Clone this repo:
  1. c11b19b Update Android.bp by running cargo_embargo am: bb45bab744 by James Farrell · 8 weeks ago main master
  2. c8f2a4d Update Android.bp by running cargo_embargo am: 8ccb2c3d63 by James Farrell · 8 weeks ago
  3. bb45bab Update Android.bp by running cargo_embargo by James Farrell · 8 weeks ago
  4. 8ccb2c3 Update Android.bp by running cargo_embargo by James Farrell · 8 weeks ago
  5. 6d085f6 Migrate to cargo_embargo. am: f41a4d0d53 am: 34d3546c25 am: 10a7f87fa5 by Andrew Walbran · 7 months ago emu-34-2-dev

Protobuf code generator for protobuf crate

This crate is useful mostly from build.rs scripts to generate .rs files during the build.

How to generate code

There are three main ways to generate .rs files from .proto files:

  • using protoc command line tool and protoc-gen-rust plugin
  • using this crate Codegen with pure rust parser
  • using this crate Codegen with protoc parser

Which one should you use depends on your needs.

If you are using non-cargo build system (like Bazel), you might prefer using protoc-gen-rust plugin for protoc.

If you build with cargo, you probably want to use Codegen from this crate.

Protoc parser vs pure rust parser

There are two protobuf parsers which can be plugged into this crate:

  • protoc-based parser (protoc is a command like utility from Google protobuf)
  • pure rust parser (protobuf-parse crate)

protoc-based parser is expected to parse .proto files very correctly: all Google's protobuf implementations rely on it.

While there are no known bugs in protobuf-parse, it is not tested very well. Also protobuf-parse does not implement certain rarely used features of .proto parser, mostly complex message options specified in .proto files. I never saw anyone using them, but you have been warned.

Note protoc command can be obtained from protoc-bin-vendored crate.

Example

// Use this in build.rs
protobuf_codegen::Codegen::new()
    // Use `protoc` parser, optional.
    .protoc()
    // Use `protoc-bin-vendored` bundled protoc command, optional.
    .protoc_path(&protoc_bin_vendored::protoc_bin_path().unwrap())
    // All inputs and imports from the inputs must reside in `includes` directories.
    .includes(&["src/protos"])
    // Inputs must reside in some of include paths.
    .input("src/protos/apple.proto")
    .input("src/protos/banana.proto")
    // Specify output directory relative to Cargo output directory.
    .cargo_out_dir("protos")
    .run_from_script();

How to use protoc-gen-rust

If you have to.

(Note protoc can be invoked programmatically with protoc crate)

  1. Install protobuf for protoc binary.

On OS X Homebrew can be used:

brew install protobuf

On Ubuntu, protobuf-compiler package can be installed:

apt-get install protobuf-compiler

Protobuf is needed only for code generation, rust-protobuf runtime does not use C++ protobuf library.

  1. Install protoc-gen-rust program (which is protoc plugin)

It can be installed either from source or with cargo install protobuf-codegen command.

  1. Add protoc-gen-rust to $PATH

If you installed it with cargo, it should be

PATH="$HOME/.cargo/bin:$PATH"
  1. Generate .rs files:
protoc --rust_out . foo.proto

This will generate .rs files in current directory.

Customize generate code

Sometimes generated code need to be adjusted, e. g. to have custom derives.

rust-protobuf provides two options to do that:

  • generated .rs files contain @@protoc_insertion_point(...) markers (similar markers inserts Google's protobuf generator for C++ or Java). Simple script sed one-liners can be used to replace these markers with custom annotations.
  • Codegen::customize_callback can be used to patch generated code when invoked from build.rs script.

Serde

rust-protobuf since version 3 no longer directly supports serde.

Rust-protobuf 3 fully supports:

Which covers the most of serde use cases.

If you still need serde, generic customization callback (see above) can be used to insert #[serde(...)] annotations.

Example project in the rust-protobuf repository demonstrates how to do it.