Implement ProxiedWithRawVTable, ProxiedWithRawOptionalVTable, and ProxiedWithPresence for Messages

Stage 2 of 3.
Fleshed out the bodies required by the aforementioned contracts above.
We create MessageVTable and utilize the `unsafe fns` directly in `message.cc` -- a departure from PrimitiveVTables.

In the final followup CL, we will perform the field_entry swapover and update all unit tests.

PiperOrigin-RevId: 600567890
pull/15495/head
Hong Shin 10 months ago committed by Copybara-Service
parent 9e9bb4f729
commit 0d090df3e2
  1. 4
      rust/internal.rs
  2. 22
      rust/vtable.rs
  3. 38
      src/google/protobuf/compiler/rust/message.cc

@ -11,8 +11,8 @@
pub use crate::r#enum::Enum; pub use crate::r#enum::Enum;
pub use crate::vtable::{ pub use crate::vtable::{
new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, MessageOptionalVTable, new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, MessageVTable,
MessageVTable, PrimitiveOptionalMutVTable, PrimitiveVTable, PrimitiveWithRawVTable, PrimitiveOptionalMutVTable, PrimitiveVTable, PrimitiveWithRawVTable,
ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, RawVTableMutator, ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, RawVTableMutator,
RawVTableOptionalMutatorData, RawVTableOptionalMutatorData,
}; };

@ -134,10 +134,14 @@ impl<'msg, T: ProxiedWithRawVTable + ?Sized> RawVTableMutator<'msg, T> {
RawVTableMutator { msg_ref, vtable: NonNull::from(vtable).cast(), _phantom: PhantomData } RawVTableMutator { msg_ref, vtable: NonNull::from(vtable).cast(), _phantom: PhantomData }
} }
fn vtable(self) -> &'static T::VTable { pub fn vtable(self) -> &'static T::VTable {
// SAFETY: This was cast from `&'static T::VTable`. // SAFETY: This was cast from `&'static T::VTable`.
unsafe { self.vtable.cast().as_ref() } unsafe { self.vtable.cast().as_ref() }
} }
pub fn msg_ref(self) -> MutatorMessageRef<'msg> {
self.msg_ref
}
} }
/// [`RawVTableMutator`], but also includes has/clear. /// [`RawVTableMutator`], but also includes has/clear.
@ -197,7 +201,11 @@ impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> RawVTableOptionalMutatorDat
Self { msg_ref, optional_vtable: NonNull::from(vtable).cast(), _phantom: PhantomData } Self { msg_ref, optional_vtable: NonNull::from(vtable).cast(), _phantom: PhantomData }
} }
fn optional_vtable(self) -> &'static T::OptionalVTable { pub fn msg_ref(self) -> MutatorMessageRef<'msg> {
self.msg_ref
}
pub fn optional_vtable(self) -> &'static T::OptionalVTable {
// SAFETY: This was cast from `&'static T::OptionalVTable` in `new`. // SAFETY: This was cast from `&'static T::OptionalVTable` in `new`.
unsafe { self.optional_vtable.cast().as_ref() } unsafe { self.optional_vtable.cast().as_ref() }
} }
@ -507,10 +515,8 @@ impl<'msg, T: PrimitiveWithRawVTable> RawVTableOptionalMutatorData<'msg, T> {
} }
#[derive(Debug)] #[derive(Debug)]
#[allow(unused)] pub struct MessageVTable {
pub struct MessageOptionalVTable { pub getter: unsafe extern "C" fn(msg: RawMessage) -> RawMessage,
pub base: MessageVTable, pub mut_getter: unsafe extern "C" fn(msg: RawMessage) -> RawMessage,
pub clearer: unsafe extern "C" fn(msg: RawMessage),
} }
#[derive(Debug)]
pub struct MessageVTable {}

@ -586,25 +586,31 @@ void GenerateRs(Context& ctx, const Descriptor& msg) {
type VTable = $pbi$::MessageVTable; type VTable = $pbi$::MessageVTable;
fn make_view(_private: $pbi$::Private, fn make_view(_private: $pbi$::Private,
_mut_inner: $pbi$::RawVTableMutator<'_, Self>) mut_inner: $pbi$::RawVTableMutator<'_, Self>)
-> $pb$::View<'_, Self> { -> $pb$::View<'_, Self> {
todo!() let msg = unsafe {
(mut_inner.vtable().getter)(mut_inner.msg_ref().msg())
};
$Msg$View::new($pbi$::Private, msg)
} }
fn make_mut(_private: $pbi$::Private, fn make_mut(_private: $pbi$::Private,
_inner: $pbi$::RawVTableMutator<'_, Self>) inner: $pbi$::RawVTableMutator<'_, Self>)
-> $pb$::Mut<'_, Self> { -> $pb$::Mut<'_, Self> {
todo!() let raw_submsg = unsafe {
(inner.vtable().mut_getter)(inner.msg_ref().msg())
};
$Msg$Mut::from_parent($pbi$::Private, inner.msg_ref(), raw_submsg)
} }
} }
impl $pbi$::ProxiedWithRawOptionalVTable for $Msg$ { impl $pbi$::ProxiedWithRawOptionalVTable for $Msg$ {
type OptionalVTable = $pbi$::MessageOptionalVTable; type OptionalVTable = $pbi$::MessageVTable;
fn upcast_vtable(_private: $pbi$::Private, fn upcast_vtable(_private: $pbi$::Private,
optional_vtable: &'static Self::OptionalVTable) optional_vtable: &'static Self::OptionalVTable)
-> &'static Self::VTable { -> &'static Self::VTable {
&optional_vtable.base &optional_vtable
} }
} }
@ -612,14 +618,26 @@ void GenerateRs(Context& ctx, const Descriptor& msg) {
type PresentMutData<'a> = $pbr$::MessagePresentMutData<'a, $Msg$>; type PresentMutData<'a> = $pbr$::MessagePresentMutData<'a, $Msg$>;
type AbsentMutData<'a> = $pbr$::MessageAbsentMutData<'a, $Msg$>; type AbsentMutData<'a> = $pbr$::MessageAbsentMutData<'a, $Msg$>;
fn clear_present_field(_present_mutator: Self::PresentMutData<'_>) fn clear_present_field(present_mutator: Self::PresentMutData<'_>)
-> Self::AbsentMutData<'_> { -> Self::AbsentMutData<'_> {
todo!(); // SAFETY: The raw ptr msg_ref is valid
unsafe {
(present_mutator.optional_vtable().clearer);
(present_mutator.msg_ref().msg());
$pbi$::RawVTableOptionalMutatorData::new($pbi$::Private,
present_mutator.msg_ref(),
present_mutator.optional_vtable())
}
} }
fn set_absent_to_default(_absent_mutator: Self::AbsentMutData<'_>) fn set_absent_to_default(absent_mutator: Self::AbsentMutData<'_>)
-> Self::PresentMutData<'_> { -> Self::PresentMutData<'_> {
todo!(); unsafe {
$pbi$::RawVTableOptionalMutatorData::new($pbi$::Private,
absent_mutator.msg_ref(),
absent_mutator.optional_vtable())
}
} }
} }

Loading…
Cancel
Save