internal change PiperOrigin-RevId: 1002449807
diff --git a/rust/codegen_traits.rs b/rust/codegen_traits.rs index 8602c40..828b9f1 100644 --- a/rust/codegen_traits.rs +++ b/rust/codegen_traits.rs
@@ -69,9 +69,14 @@ type MessageMut<'msg>: MessageMut<'msg, Message = Self>; } -/// A marker trait for messages that support reflection. +/// A trait for messages that support reflection. #[cfg(not(lite_runtime))] -pub trait WithReflection: Message + KernelWithReflection {} +pub trait WithReflection: Message + KernelWithReflection { + /// Returns the fully-qualified name of the message, implemented by the kernel. + fn full_name() -> &'static str { + <Self as KernelWithReflection>::kernel_full_name(crate::__internal::Private) + } +} /// A trait that all generated message views implement. #[diagnostic::on_unimplemented(
diff --git a/rust/cpp_kernel/reflection.cc b/rust/cpp_kernel/reflection.cc index 9ce5e3a..deb8fd5 100644 --- a/rust/cpp_kernel/reflection.cc +++ b/rust/cpp_kernel/reflection.cc
@@ -1,6 +1,7 @@ #include <string> #include "absl/log/absl_check.h" +#include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" #include "google/protobuf/message_lite.h" #include "rust/cpp_kernel/strings.h" @@ -8,6 +9,14 @@ extern "C" { +// Returns the full name of the message from its Descriptor. +google::protobuf::rust::PtrAndLen proto2_rust_Descriptor_full_name( + const google::protobuf::Descriptor* desc) { + ABSL_CHECK(desc != nullptr) << "Descriptor is null."; + return google::protobuf::rust::PtrAndLen{desc->full_name().data(), + desc->full_name().size()}; +} + // Converts a message to its TextFormat representation. google::protobuf::rust::RustStringRawParts proto2_rust_Message_print_to_text_format( const google::protobuf::MessageLite* m, bool single_line, bool hide_unknown_fields) {
diff --git a/rust/cpp_kernel/reflection.rs b/rust/cpp_kernel/reflection.rs index 6ee19ac..c48b9fc 100644 --- a/rust/cpp_kernel/reflection.rs +++ b/rust/cpp_kernel/reflection.rs
@@ -13,7 +13,15 @@ use super::*; -pub trait KernelWithReflection: MessageDescriptorInterop {} +pub trait KernelWithReflection: MessageDescriptorInterop { + fn kernel_full_name(_private: Private) -> &'static str { + let desc = Self::__unstable_get_descriptor(); + // SAFETY: + // - This function is only called via `WithReflection::full_name`. Gencode only implements + // `WithReflection` for messages with reflection, so `desc` is a real descriptor. + unsafe { std::str::from_utf8_unchecked(proto2_rust_Descriptor_full_name(desc).as_ref()) } + } +} impl<T: MessageDescriptorInterop> KernelWithReflection for T {} #[cfg(not(lite_runtime))] @@ -21,6 +29,12 @@ /// From reflection.cc /// /// # Safety + /// - `desc` points to a valid `proto2::Descriptor`. + fn proto2_rust_Descriptor_full_name(desc: *const std::ffi::c_void) -> PtrAndLen; + + /// From reflection.cc + /// + /// # Safety /// - `m` is a legally dereferenceable MessageLite* that supports reflection. fn proto2_rust_Message_print_to_text_format( m: RawMessage,
diff --git a/rust/upb_kernel/reflection.rs b/rust/upb_kernel/reflection.rs index 7e83b96..80009fa 100644 --- a/rust/upb_kernel/reflection.rs +++ b/rust/upb_kernel/reflection.rs
@@ -20,7 +20,11 @@ /// /// `UpbGetMessagePtr<Msg = Self>` ties the message pointer that reflection APIs operate on to the /// `MessageDef` they look up by `Self`, so the two can never describe different message types. -pub trait KernelWithReflection: UpbWithReflection + UpbGetMessagePtr<Msg = Self> {} +pub trait KernelWithReflection: UpbWithReflection + UpbGetMessagePtr<Msg = Self> { + fn kernel_full_name(_private: Private) -> &'static str { + Self::FULL_NAME + } +} impl<T: UpbWithReflection + UpbGetMessagePtr<Msg = T>> KernelWithReflection for T {} /// Returns the protobuf TextFormat representation of `msg` with custom options.