dep-protobuf/rust/cpp_kernel/raw.rs
Joshua Haberman 7c958618b6 Added infrastructure for Rust Extensions support, but left it disabled for now.
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
2026-04-08 08:08:46 -07:00

74 lines
2.6 KiB
Rust

use super::*;
/// Defines a set of opaque, unique, non-accessible pointees.
///
/// The [Rustonomicon][nomicon] currently recommends a zero-sized struct,
/// though this should use [`extern type`] when that is stabilized.
/// [nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
/// [`extern type`]: https://github.com/rust-lang/rust/issues/43467
#[doc(hidden)]
pub mod _opaque_pointees {
/// Opaque pointee for [`RawMessage`]
///
/// This type is not meant to be dereferenced in Rust code.
/// It is only meant to provide type safety for raw pointers
/// which are manipulated behind FFI.
///
/// [`RawMessage`]: super::RawMessage
#[repr(C)]
pub struct RawMessageData {
_data: [u8; 0],
_marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>,
}
/// Opaque pointee for [`RawRepeatedField`]
///
/// This type is not meant to be dereferenced in Rust code.
/// It is only meant to provide type safety for raw pointers
/// which are manipulated behind FFI.
#[repr(C)]
pub struct RawRepeatedFieldData {
_data: [u8; 0],
_marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>,
}
/// Opaque pointee for [`RawMap`]
///
/// This type is not meant to be dereferenced in Rust code.
/// It is only meant to provide type safety for raw pointers
/// which are manipulated behind FFI.
#[repr(C)]
pub struct RawMapData {
_data: [u8; 0],
_marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>,
}
/// Opaque pointee for [`CppStdString`]
///
/// This type is not meant to be dereferenced in Rust code.
/// It is only meant to provide type safety for raw pointers
/// which are manipulated behind FFI.
#[repr(C)]
pub struct CppStdStringData {
_data: [u8; 0],
_marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>,
}
}
/// A raw pointer to the underlying message for this runtime.
#[doc(hidden)]
pub type RawMessage = NonNull<_opaque_pointees::RawMessageData>;
/// A raw pointer to the underlying repeated field container for this runtime.
#[doc(hidden)]
pub type RawRepeatedField = NonNull<_opaque_pointees::RawRepeatedFieldData>;
/// A raw pointer to the underlying arena for this runtime.
#[doc(hidden)]
pub type RawMap = NonNull<_opaque_pointees::RawMapData>;
/// A raw pointer to a std::string.
#[doc(hidden)]
pub type CppStdString = NonNull<_opaque_pointees::CppStdStringData>;
pub type RawMapIter = UntypedMapIterator;