# Oak Proto Rust Library

This is a transitional library that's serving as the single dependency to add
when you need to depend on any Oak protos from a Bazel build.

If the proto you need isn't yet built by this library, you can add it to the
build.rs file (and update the dependencies for the build script target as
needed.)

This library is imported into some environments where Prost and/or build scripts
are not available. To support building our Rust targets in these environmnets,
we also include pre-generated Prost Rust code in the `generated` directory.

The bazel `write_source_files` helps us with this. It creates a rule for copying
the generated files, as well as a rule that verifies that they exist in the
right place.

If proto changes are made, you should run:
`bazel run oak_proto_rust:copy_generated_files`

If you forget, your presubmit will fail, with a message telling you to run that
command.

## Generation Types

We have three different libraries:

- `oak_proto_rust` - generated code for `message` items in a proto file.
- `oak_grpc` - gRPC (tonic) generated code for `service` items in a proto file.
- `oak_micro_rpc` - microRPC generated code for `service` items in a proto file.

When adding items to `oak_grpc` or `oak_micro_rpc`, ensure that no `message`
`struct`s are generated. For consistency, we should refer to all proto messages
via the `oak_proto_rust` crate.

This can be achieved by ensuring that `ExternPath` items are included in the
`oak_proto_utils::CodegenOptions` provided to gRPC copmilation calls or
`micro_rpc_build::CompileOptions` provided to microRPC compilation calls. When
you provide an `ExternPath` mapping, then whenever a proto message in a package
starting with the specified proto is encountered, rather than having Prost
generate a struct for that message, it instead replaces the references with a
Rust crate path, with the assumption that the messages have been compiled in
another crate.

For example, if you include an extern path mapping like `.oak` =>
`::oak_proto_rust::oak`, then whnever the compiler encounters a proto message
with a fully qualified name starting with `.oak`, it won't generate any code for
that message, instead it will transform the proto package into a Rust crate name
(essentially, it turns the `.` into `::`), and then it will replace the
specified pakacage prefix with the specified Rust crate prefix.

The `lib.rs` module setup in `oak_proto_rust/grpc`, `oak_proto_rust/micro_rpc`,
should never import any proto message structs via `use` declarations, those libs
should only contain `include_proto!` invocations for the services generated by
those crates.
