| // Protocol Buffers - Google's data interchange format |
| // Copyright 2026 Google LLC. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file or at |
| // https://developers.google.com/open-source/licenses/bsd |
| |
| //! Reflection support for the C++ kernel. |
| //! |
| //! The descriptor itself is fetched through a per-message thunk emitted into |
| //! that message's generated C++ code, so that only protos which actually need |
| //! reflection pull in the full C++ runtime. |
| |
| use super::*; |
| |
| 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))] |
| unsafe extern "C" { |
| /// 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, |
| single_line: bool, |
| hide_unknown_fields: bool, |
| ) -> RustStringRawParts; |
| |
| /// From reflection.cc |
| /// |
| /// # Safety |
| /// - `m` is a legally dereferenceable and mutable MessageLite* that supports reflection. |
| /// - `input` is a valid `PtrAndLen` pointing to readable memory for its length. |
| fn proto2_rust_Message_parse_from_text_format(m: RawMessage, input: PtrAndLen) -> bool; |
| } |
| |
| /// Returns the protobuf TextFormat representation of `msg` with custom options. |
| #[cfg(not(lite_runtime))] |
| pub fn print_to_text_format<T: crate::WithReflection>( |
| msg: &T, |
| single_line: bool, |
| hide_unknown_fields: bool, |
| ) -> String { |
| let raw = msg.as_view().get_raw_message(Private); |
| // SAFETY: `raw` points to a live message, and `WithReflection` guarantees it |
| // supports reflection. |
| unsafe { proto2_rust_Message_print_to_text_format(raw, single_line, hide_unknown_fields) } |
| .into() |
| } |
| |
| /// Parses a message from its protobuf TextFormat representation. |
| #[cfg(not(lite_runtime))] |
| pub fn parse_from_text_format<T: crate::WithReflection>(input: &str) -> Result<T, ParseError> { |
| let mut msg = T::default(); |
| let raw = msg.get_raw_message_mut(Private); |
| // SAFETY: |
| // - `raw` points to a live, mutable message, and `WithReflection` guarantees it supports |
| // reflection. |
| // - `input` is converted from a valid `&str` slice. |
| unsafe { proto2_rust_Message_parse_from_text_format(raw, input.as_bytes().into()) } |
| .then_some(msg) |
| .ok_or(ParseError) |
| } |