It is common to want to match only a subset of fields in large protobufs, and doing that in rust right now requires manually clearing out the fields in the `actual` message that we don't care about. This is a pain, and a worse experience when compared to C++.
Like in C++, when doing partial matching, only fields set in the expected protobuf message are compared, while extra fields set only in the actual message are ignored.
When using the C++ kernel we leverage `proto2::util::MessageDifferencer`, and for the UPB kernel we use the `kUpb_CompareOption_Partial` option.
PiperOrigin-RevId: 964125682
This is just a slightly more Rust idiomatic way of being clear that you are knowingly using unsafe to soundly extend a lifetime.
PiperOrigin-RevId: 926763735
This code makes use of some Rust features that are not supported in Rust 1.85 (our currently supported version), so we cannot enable the codegen for this feature yet.
This CL introduces support for [Protobuf Extensions](https://engdoc.corp.google.com/eng/doc/devguide/proto/programming-guides/proto2.html#extensions) to the Rust Protobuf library, a key feature for full Proto2 API parity.
Key changes include:
1. **Code Generation:**
* Added `compiler/rust/extension.cc` and `extension.h` to handle the generation of Rust code for extension definitions.
* Updated `generator.cc` and `message.cc` to invoke extension generation for both top-level and nested extensions.
* Generates `ExtensionId` constants for each extension.
2. **Runtime API (`rust/extension.rs`):**
* Introduced the generic `ExtensionId<Extendee, T>` type to identify and type-check extensions.
* Defined traits for extension operations: `ExtHas`, `ExtGet`, `ExtSet`, `ExtClear`, and `ExtGetMut`.
* Implemented methods on `ExtensionId` that dispatch to the trait implementations provided by the active kernel.
3. **Kernel Implementations:**
* **C++ Kernel (`rust/cpp_kernel/extension.rs`):** Implemented extension traits by calling into new C++ FFI functions (defined in `rust/cpp_kernel/extension.cc`) that interact with the C++ `ExtensionSet`.
* **UPB Kernel (`rust/upb_kernel/extension.rs`):** Implemented extension traits using UPB's MiniTable-based extension API. Extension MiniTables are registered at static initialization time using the `linkme` crate.
4. **Build System:**
* Updated `protobuf/rust/BUILD` and `protobuf/compiler/rust/BUILD` to include new files.
* Added a dependency on `//third_party/rust/linkme/v0_3` for the UPB kernel's extension registration.
5. **Testing:**
* Added `test/extensions.proto` and `test/extensions_separate_file.proto` to define various extension types.
* Added `test/shared/extensions_test.rs` with comprehensive tests covering presence, getters, setters, defaults, nested extensions, submessage extensions, repeated extensions, serialization, and `MergeFrom`.
This change enables Rust users to define and interact with Protobuf extensions in a type-safe manner, compatible with both the C++ and UPB runtimes.
PiperOrigin-RevId: 896506594
This change moves the `OwnedMessageInterop`, `MessageViewInterop`, and `MessageMutInterop` traits from `codegen_traits.rs` into new `interop.rs` files within both the `cpp_kernel` and `upb_kernel` directories.
The `KernelMessage`, `KernelMessageView`, and `KernelMessageMut` traits in each kernel's `message.rs` are updated to include the respective kernel-specific interop traits. This ensures that the interop functionality is tied to the specific kernel implementation.
The `shared.rs` module now re-exports the interop traits from `crate::__internal::runtime::interop`, which will resolve to the correct kernel's interop module.
It would be possible to take this farther by making the interop traits return strongly typed pointers to `upb_Message*` and `proto2::MessageLite*` instead of `c_void`, but that would be a breaking change.
PiperOrigin-RevId: 892470084
MessageMutInner was Copy+Clone, which had been convenient for some internal use. But, with them being .into() SomeMessageMut this was a potential footgun, since it was very easy to into() the same one twice which would be formally unsound if it was reachable (including that you could send each of them to a different thread and concurrently modify them).
As these were implementation detail types this is only a defensive fix and no actual soundness issues were identified.
PiperOrigin-RevId: 888615057
The `Enum` trait now requires several other traits, including `Singular`, `Into<i32>`, `Copy`, `Proxied`, `EntityType`, and `SealedInternal`. This simplifies bounds in functions that operate on types implementing `Enum`, as they no longer need to explicitly list `+ Singular` and other common requirements.
PiperOrigin-RevId: 888286136
This CL contains no functional change, it is a pure splitting of the existing files.
I elected to move the C++ kernel files to `cpp_kernel/` which already contained the C++ API for the C++ kernel. Unfortunately this required removing the existing `third_party/protobuf/rust/cpp_kernel/BUILD` file, because, the Rust parts of the cpp kernel have circular dependencies with the shared code in `third_party/protobuf/rust`.
PiperOrigin-RevId: 886884124
The intent of this directory would be for a layer of Rust bindings that directly map to upb semantics; Rust Protobuf runtime would be layer on top of that Rust, instead of directly on the upb C api.
PiperOrigin-RevId: 624282429
For the cpp runtime, call the `Message::CopyFrom` method.
For the upb runtime, expose the message `MiniTable` and call `upb_Message_DeepCopy`.
PiperOrigin-RevId: 595166276
To satisfy the layering check, we need to depend on :gtest for the headers, in
addition to :gtest_main which provides the main() function.
There are a bunch of formatting changes as a side effect of this, but they
should be harmless.
PiperOrigin-RevId: 594318263
This change moves almost everything in the `upb/` directory up one level, so
that for example `upb/upb/generated_code_support.h` becomes just
`upb/generated_code_support.h`. The only exceptions I made to this were that I
left `upb/cmake` and `upb/BUILD` where they are, mostly because that avoids
conflict with other files and the current locations seem reasonable for now.
The `python/` directory is a little bit of a challenge because we had to merge
the existing directory there with `upb/python/`. I made `upb/python/BUILD` into
the BUILD file for the merged directory, and it effectively loads the contents
of the other BUILD file via `python/build_targets.bzl`, but I plan to clean
this up soon.
PiperOrigin-RevId: 568651768
A couple weeks ago we moved upb into the protobuf Git repo, and this change
continues the merger of the two repos by making them into a single Bazel repo.
This was mostly a matter of deleting upb's WORKSPACE file and fixing up a bunch
of references to reflect the new structure.
Most of the changes are pretty mechanical, but one thing that needed more
invasive changes was the Python script for generating CMakeLists.txt,
make_cmakelists.py. The WORKSPACE file it relied on no longer exists with this
change, so I updated it to hardcode the information it needed from that file.
PiperOrigin-RevId: 564810016
In this CL I'd like to call existing C++ Protobuf API from the V0 Rust API. Since parts of the C++ API are defined inline and using (obviously) C++ name mangling, we need to create a "thunks.cc" file that:
1) Generates code for C++ API function we use from Rust
2) Exposes these functions without any name mangling (meaning using `extern "C"`)
In this CL we add Bazel logic to generate "thunks" file, compile it, and propagate its object to linking. We also add logic to protoc to generate this "thunks" file.
The protoc logic is rather rudimentary still. I hope to focus on protoc code quality in my followup work on V0 Rust API using C++ kernel.
PiperOrigin-RevId: 523479839
This turns out to be quite of a yak shave to be able to perfectly test both kernels without having to pass extra Blaze flags.
PiperOrigin-RevId: 521850709