It uses the same nodes that Map<> would use for the respectice types.
This makes the type compatible with visitation and removes some custom types
supporting DynamicMapField.
Remove most of the vtable, since this can now be done directly in MapFieldBase without derived type support.
PiperOrigin-RevId: 717984824
Given:
oneof hello_world {}
We now generate:
fn hello_world(&self) -> HelloWorldOneof
fn hello_world_case(&self) -> HelloWorldCase
This change is to help mitigate a realistic risk of collisions in cases like:
message M {
oneof x { ... }
enum X { ... }
}
PiperOrigin-RevId: 714998247
Before this fix, the overload resolution rules would accidentally attempt to call the accessor named clear() instead of the fn that would actually clear the message (Rust automatically prefers an inherent impl fn over a trait impl fn if both exist with the same name).
PiperOrigin-RevId: 713309633
The unnecessary [< >] around the ident in that specific macro expansion makes it the name as a literal which would then later be reparsed back into an ident, which makes it lose the r# in the process and break.
PiperOrigin-RevId: 712562736
This was disabled because it couldn't pass with the upb C generated accessors. Now that we only use the upb minitables, this can be safely enabled.
PiperOrigin-RevId: 712560415
While in general Proto enum numbers are more of arbitary wire tag numbers, sometimes the ordering is used for semantic meaning, and this allows for the enums to be used in things that require ordering eg BTreeMap.
Rust defaults to language enums _not_ being Ord with the derive(Ord) opt in, but it is largely for reasons which don't apply to protobuf enums.
PiperOrigin-RevId: 709831238
Before this change, the way it works is that we emit one .rs file per input .proto file, and a multi-src proto_library are handled by considering the first file as specially the 'primary' one which specially re-exports everything defined in other files.
After this change, we instead emit the .rs file per .proto file equally, and then we additionally emit a generated.rs file which re-exports all of them.
PiperOrigin-RevId: 707569226
For now the error message describes how to build protoc and
protoc-gen-upb_minitable from source using CMake. Hopefully this will be
temporary, since we should be able to point to prebuilt binaries for both once
we have a real release out.
PiperOrigin-RevId: 707147611
It's not yet possible to import any of the well-known types from a proto file
in another crate. To enable this I think we'll need to generate a function that
dependent crates can call to determine the directory that contains the
well-known types.
PiperOrigin-RevId: 706745114
Proto file paths generally need to be globally unique, or at least unique
within the same binary. A file conflict might be tolerated in protobuf
implementations without reflection, but ones that do support reflection will
have trouble building a descriptor pool that has one more than one proto file
with the same path.
This change therefore updates the example crate to put the proto files inside a
`proto_example/` directory since this lessens the chance of a conflict. Not
that we really care about the example crate conflicting with anything, but I
think this makes it a better example to follow.
PiperOrigin-RevId: 705982825
I also added a check to ensure that `protoc --version` matches the protobuf
runtime version. The minitable generator plugin version should also match, but
unfortunately we can't easily check this today because it does not provide a
way to check its version.
PiperOrigin-RevId: 705944904
The specific format is something which you could more easily copy-paste back into a test, either:
`SomeEnumName::CorrespondingNamedConstant` or
`SomeEnumName::from(someint)` for open enums with an unrecognized value.
For now this is emitting the string literals for the names in a generated match statement in .rs; this makes it work for both cpp and upb kernels, as well as hopefully reduces bloat if there is no cross-language lto.
At a future time we could consider calling into C++ to get the enum names there, which is a more optimized path and could reduce having the names in the binary twice in some cases.
PiperOrigin-RevId: 705910092
== Functionality ==
Given a Rust function signature `pub fn handle_request(&mut self, req: FooRequestView, mut rsp: FooResponseMut) -> bool`, where `FooRequestView` and `FooResponseMut` are Protobuf Rust proxy types. This change enables Crubit to generate C++ bindings for `handle_request` with the C++ function signature `bool handle_request(const FooRequest* req, FooResponse* rsp)`.
== Crubit changes ==
Within a blaze build the Protobuf generated crate has two names. When the generated code gets compiled the name of the crate is the name of the `proto_library`. Later in the build the crate is renamed to the name of the `rust_proto_library`, which is what developers using Rust Protobufs see. So when the `cc_bindings_from_rs_aspect` runs the name of a Protobuf crate is the name of the `proto_library` and when the Crubit bindings get compiled the Protobuf crate in its dependencies has the name of the `rust_proto_library`. Therefore, in Crubit's generated code we rename the crate to its proto_library name via `extern crate` statements. We pass this information to Crubit via cmdline flag that gets set from within the build rules.
== Protobuf Rust changes ==
When building for the C++ kernel, Protobuf Rust View and Mut types get annotated with the `__crubit::annotate` attribute. The attribute describes the C++
message type to which the Rust type should be converted and it also includes the header that declares the C++ message type. Additionally, the type is marked `repr(transparent)` so that Crubit can verify that the ABI layout of a Protobuf Rust proxy type is pointer-like i.e. the view/mut structs have a single pointer field and any number of ZSTs. With this knowledge Crubit can generate code to convert the pointer-like Rust struct to a C++ pointer (and vice versa). No explicit conversion functions need to be specified.
An example of an annotation:
```
#[__crubit::annotate(
cpp_type = "const FooRequest*",
cpp_type_include = "path/to/foo_request.proto.h",
)]
#[repr(transparent)]
struct FooRequestView { ... }
```
PiperOrigin-RevId: 705850175
Also update the protobuf_example crate to use the OUT_DIR instead of the source in the /src dir.
This will avoids problems of the outdir having stale files that shouldn't be there anymore still being picked up in the build.
PiperOrigin-RevId: 705609005
The invariant is that PtrAndLen may hold ptr+len values which are legal for _either_ C++ string_view or Rust slices: constructing one from either Rust or C++ permits the laxest constraints, and care must be taken when converting a PtrAndLen into either type.
For "into Rust slice" case to handle is that len=0 ptr must be non-null, so len=0 ptr=null gets turned into an arbitrary non-null pointer as provided by std::ptr::NonNull::dangling() (any preexisting non-null ptr is kept in that direction).
For the "into C++ slice" the risk is more obscure that a Rust non-null pointer could potentially be an illegal pointer (such that ptr+0 is not a legal operation in C++), so when going into C++ we map any len=0 cases into ptr=null to avoid this as a possible risk.
PiperOrigin-RevId: 704776210
I found that `cargo test` fails without this, because even with `no_run`, Cargo
will still try to compile the code. It would be nice to have a working example
here, but unfortunately it's non-trivial to set that up since we would need a
real generated proto.
I also tweaked cargo_test.sh to run the doc tests so that we have CI coverage
for those.
PiperOrigin-RevId: 703611549
This is necessary for the generated code to work correctly even when it's
placed in a module instead of directly in the crate root. Now we can finally
delete the last of the gencode post-processing from the protobuf_gencode crate.
To get this to work properly I had to update the `Context` object to keep track
of the current module depth. This way we know how many `super::` prefixes we
need to prepend to an identifier to get back to the top level.
I had to some refactoring of our naming helper functions to get everything
working properly:
- Deleted `GetCrateRelativeQualifiedPath()`, since it seems simpler if we just
always provide unambiguous paths. I added some new `RsTypePath()` overloads
as a replacement.
- Made `RustModuleForContainingType()` a private implementation detail of
naming.cc, since the `RustModule()` functions are more user-friendly and
accomplish the same thing.
- Moved the logic for prepending super:: or the foreign crate name into
`RustModuleForContainingType()`. This way, all the helpers that call that
function automatically pick up the behavior we want.
PiperOrigin-RevId: 703555727
This required a tweak to the Bazel aspect to make it alias the appropriate
runtime (C++ or upb) under the name `protobuf`.
The nice thing about this is that it allows the same generated code to work
with both Bazel and Cargo. With Bazel the runtime crate is named `protobuf_cpp`
or `protobuf_upb`, whereas with the Cargo build it is just `protobuf`.
PiperOrigin-RevId: 703143472
This change updates the generated code to always prefix the names of crates
with `::` so that they can't conflict with local modules. I'm not aware of this
being an issue for anyone yet, but figured we might as well fix it proactively.
PiperOrigin-RevId: 703122266
Starting from the 2018 edition of Rust, paths starting with `::` must refer to
a crate, so when we refer to `::std` there is no risk of accidental collision
with another identifier.
Using `::std` instead of `::__std` is useful because it works even when the
generated code is in a module rather than directly in the crate root. This
allows us to remove one of the post-processing steps from the codegen crate.
PiperOrigin-RevId: 702858213
Temporarily rename the crates `staging-` while we're iterating on this.
This works for the protobuf and protobuf_codegen crates, but the protobuf_example crate fails to publish as cargo does not want build.rs to affect files outside of the OUT_DIR.
PiperOrigin-RevId: 702840478
Add trivial README.md files for this to pass.
This will catch some but not all issues with the crates that would cause them to be rejected by crates.io
PiperOrigin-RevId: 702766719
The Cargo.toml sets both path and version for its dependencies: the mechanism is that path is used if possible (which it is for our test script), but is automatically stripped from the .toml file when uploadeded to Crates.io
PiperOrigin-RevId: 702721439
Used the python rules as an example to fix this. Bazel now recognizes that the output files have been produced, where before there were build failures regarding the outputs not being produced.
Closes#18255
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/18255 from tempoz:tempoz-fix-rust-outputs dfad229785
PiperOrigin-RevId: 700285611