|  | // Protocol Buffers - Google's data interchange format | 
|  | // Copyright 2025 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 | 
|  |  | 
|  | use super::sys::{ | 
|  | message::array as sys_array, message::map as sys_map, message::message as sys_msg, | 
|  | mini_table::mini_table as sys_mt, | 
|  | }; | 
|  | use super::StringView; | 
|  | use super::{Arena, AssociatedMiniTable}; | 
|  | use core::marker::PhantomData; | 
|  | use paste::paste; | 
|  |  | 
|  | pub type RawMessage = sys_msg::RawMessage; | 
|  |  | 
|  | #[derive(Debug)] | 
|  | pub struct MessagePtr<T> { | 
|  | raw: RawMessage, | 
|  | _phantom: PhantomData<T>, | 
|  | } | 
|  |  | 
|  | impl<T> Copy for MessagePtr<T> {} | 
|  |  | 
|  | impl<T> Clone for MessagePtr<T> { | 
|  | fn clone(&self) -> Self { | 
|  | *self | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<T> MessagePtr<T> { | 
|  | pub fn raw(&self) -> RawMessage { | 
|  | self.raw | 
|  | } | 
|  | } | 
|  |  | 
|  | macro_rules! scalar_accessors { | 
|  | ( $ty:ty, $rust_ty_name:ident, $upb_ty_name:ident) => { | 
|  | paste! { | 
|  | impl<T: AssociatedMiniTable> MessagePtr<T> { | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - The field at `index` must be a $ty field. | 
|  | pub unsafe fn [< get_ $rust_ty_name _at_index >] (self, index: u32, default_value: $ty) -> $ty { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | unsafe { sys_msg::[< upb_Message_Get $upb_ty_name >](self.raw, f, default_value) } | 
|  | } | 
|  |  | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable to a mutable message. | 
|  | /// - The field at `index` must be a $ty field. | 
|  | pub unsafe fn [< set_base_field_ $rust_ty_name _at_index >] (self, index: u32, value: $ty) { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | unsafe { sys_msg::[< upb_Message_SetBaseField $upb_ty_name >](self.raw, f, value) } | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | scalar_accessors!(bool, bool, Bool); | 
|  | scalar_accessors!(i32, i32, Int32); | 
|  | scalar_accessors!(i64, i64, Int64); | 
|  | scalar_accessors!(u32, u32, UInt32); | 
|  | scalar_accessors!(u64, u64, UInt64); | 
|  | scalar_accessors!(f32, f32, Float); | 
|  | scalar_accessors!(f64, f64, Double); | 
|  | scalar_accessors!(StringView, string, String); | 
|  |  | 
|  | impl<T: AssociatedMiniTable> MessagePtr<T> { | 
|  | /// Constructs a new mutable message pointer. | 
|  | /// Will only return None if arena allocation fails. | 
|  | pub fn new(arena: &Arena) -> Option<MessagePtr<T>> { | 
|  | let raw = unsafe { sys_msg::upb_Message_New(T::mini_table(), arena.raw()) }; | 
|  | raw.map(|raw| MessagePtr { raw, _phantom: PhantomData }) | 
|  | } | 
|  |  | 
|  | /// # Safety | 
|  | /// - `raw` must be a dereferenceable message pointer of message associated with `T::mini_table()`. | 
|  | pub unsafe fn wrap(raw: RawMessage) -> MessagePtr<T> { | 
|  | MessagePtr { raw, _phantom: PhantomData } | 
|  | } | 
|  |  | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable to a mutable message. | 
|  | pub unsafe fn clear(self) { | 
|  | unsafe { sys_msg::upb_Message_Clear(self.raw, T::mini_table()) } | 
|  | } | 
|  |  | 
|  | /// Copies the contents of `src` to `self`, using `arena` for allocations. | 
|  | /// `arena` should be the one associated with `self`. | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable to a mutable message. | 
|  | pub unsafe fn deep_copy(self, src: Self, arena: &Arena) -> bool { | 
|  | unsafe { sys_msg::upb_Message_DeepCopy(self.raw, src.raw, T::mini_table(), arena.raw()) } | 
|  | } | 
|  |  | 
|  | /// Returns a pointer to a mutable message which is a clone of `self` on `arena`. | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | pub unsafe fn deep_clone(self, arena: &Arena) -> Option<MessagePtr<T>> { | 
|  | let raw = unsafe { sys_msg::upb_Message_DeepClone(self.raw, T::mini_table(), arena.raw()) }; | 
|  | raw.map(|raw| MessagePtr { raw, _phantom: PhantomData }) | 
|  | } | 
|  |  | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - `index` must be within bounds of `T::mini_table()`. | 
|  | pub unsafe fn clear_field_at_index(self, index: u32) { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | unsafe { sys_msg::upb_Message_ClearBaseField(self.raw, f) } | 
|  | } | 
|  |  | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - `index` must be within bounds of `T::mini_table()`. | 
|  | pub unsafe fn has_field_at_index(self, index: u32) -> bool { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | unsafe { sys_msg::upb_Message_HasBaseField(self.raw, f) } | 
|  | } | 
|  |  | 
|  | /// Returns a constant message pointer, or None if the field is not present. | 
|  | /// | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - The field at `index` must be a message field of type `ChildT`. | 
|  | pub unsafe fn get_message_at_index<ChildT>(self, index: u32) -> Option<MessagePtr<ChildT>> { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  |  | 
|  | let raw = unsafe { sys_msg::upb_Message_GetMessage(self.raw, f) }; | 
|  | raw.map(|raw| MessagePtr { raw, _phantom: PhantomData }) | 
|  | } | 
|  |  | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - The field at `index` must be a message field of type `ChildT`. | 
|  | /// - Caller must ensure that `value` outlives `self` (typically by being on the same arena). | 
|  | pub unsafe fn set_base_field_message_at_index<ChildT>( | 
|  | self, | 
|  | index: u32, | 
|  | value: MessagePtr<ChildT>, | 
|  | ) { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | unsafe { sys_msg::upb_Message_SetBaseFieldMessage(self.raw, f, value.raw) } | 
|  | } | 
|  |  | 
|  | /// Returns a mutable message pointer, creating the field if it is not present. | 
|  | /// | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable to a mutable message. | 
|  | /// - The field at `index` must be a message field of type `ChildT`. | 
|  | pub unsafe fn get_or_create_mutable_message_at_index<ChildT>( | 
|  | self, | 
|  | index: u32, | 
|  | arena: &Arena, | 
|  | ) -> Option<MessagePtr<ChildT>> { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  |  | 
|  | let raw = unsafe { | 
|  | sys_msg::upb_Message_GetOrCreateMutableMessage( | 
|  | self.raw, | 
|  | T::mini_table(), | 
|  | f, | 
|  | arena.raw(), | 
|  | ) | 
|  | }; | 
|  | raw.map(|raw| MessagePtr { raw, _phantom: PhantomData }) | 
|  | } | 
|  |  | 
|  | /// Returns a constant pointer to an array. May return None if the repeated field is empty. | 
|  | /// | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - The field at `index` must be a repeated field. | 
|  | pub unsafe fn get_array_at_index(self, index: u32) -> Option<sys_array::RawArray> { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | let raw = unsafe { sys_msg::upb_Message_GetArray(self.raw, f) }; | 
|  | raw | 
|  | } | 
|  |  | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - The field at `index` must be a repeated field. | 
|  | /// - Caller must ensure that `value` outlives `self` (typically by being on the same arena). | 
|  | pub unsafe fn set_array_at_index(self, index: u32, value: sys_array::RawArray) { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | let value_ptr: *const *const core::ffi::c_void = | 
|  | &(value.as_ptr() as *const core::ffi::c_void); | 
|  | unsafe { | 
|  | sys_msg::upb_Message_SetBaseField(self.raw, f, value_ptr as *const core::ffi::c_void) | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Returns a mutable pointer to an array. Will only return None if arena allocation fails. | 
|  | /// | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable to a mutable message. | 
|  | /// - The field at `index` must be a repeated field. | 
|  | pub unsafe fn get_or_create_mutable_array_at_index( | 
|  | self, | 
|  | index: u32, | 
|  | arena: &Arena, | 
|  | ) -> Option<sys_array::RawArray> { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | let raw = unsafe { sys_msg::upb_Message_GetOrCreateMutableArray(self.raw, f, arena.raw()) }; | 
|  | raw | 
|  | } | 
|  |  | 
|  | /// Returns a constant pointer to a map. May return None if the map is empty. | 
|  | /// | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - The field at `index` must be a map. | 
|  | pub unsafe fn get_map_at_index(self, index: u32) -> Option<sys_map::RawMap> { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | unsafe { sys_msg::upb_Message_GetMap(self.raw, f) } | 
|  | } | 
|  |  | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - The field at `index` must be a repeated field. | 
|  | /// - Caller must ensure that `value` outlives `self` (typically by being on the same arena). | 
|  | pub unsafe fn set_map_at_index(self, index: u32, value: sys_map::RawMap) { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | let value_ptr: *const *const core::ffi::c_void = | 
|  | &(value.as_ptr() as *const core::ffi::c_void); | 
|  | unsafe { | 
|  | sys_msg::upb_Message_SetBaseField(self.raw, f, value_ptr as *const core::ffi::c_void) | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Returns a mutable pointer to a map. Will only return None if arena allocation fails. | 
|  | /// | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable to a mutable message. | 
|  | /// - The field at `index` must be a map. | 
|  | pub unsafe fn get_or_create_mutable_map_at_index( | 
|  | self, | 
|  | index: u32, | 
|  | arena: &Arena, | 
|  | ) -> Option<sys_map::RawMap> { | 
|  | unsafe { | 
|  | let f = sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index); | 
|  | let map_entry_mini_table = sys_mt::upb_MiniTable_SubMessage(T::mini_table(), f); | 
|  | sys_msg::upb_Message_GetOrCreateMutableMap( | 
|  | self.raw, | 
|  | map_entry_mini_table, | 
|  | f, | 
|  | arena.raw(), | 
|  | ) | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Returns the number associated with the active field in a oneof, or 0 if the oneof is unset. | 
|  | /// `index` can be the field number of any field in the oneof. | 
|  | /// | 
|  | /// # Safety | 
|  | /// - `self` must be legally dereferenceable. | 
|  | /// - The field at `index` must be part of a oneof. | 
|  | pub unsafe fn which_oneof_field_number_by_index(self, index: u32) -> u32 { | 
|  | let f = unsafe { sys_mt::upb_MiniTable_GetFieldByIndex(T::mini_table(), index) }; | 
|  | unsafe { sys_msg::upb_Message_WhichOneofFieldNumber(self.raw, f) } | 
|  | } | 
|  | } |