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::vtable::{
new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, MessageOptionalVTable,
MessageVTable, PrimitiveOptionalMutVTable, PrimitiveVTable, PrimitiveWithRawVTable,
new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, MessageVTable,
PrimitiveOptionalMutVTable, PrimitiveVTable, PrimitiveWithRawVTable,
ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, RawVTableMutator,
RawVTableOptionalMutatorData,
};

@ -134,10 +134,14 @@ impl<'msg, T: ProxiedWithRawVTable + ?Sized> RawVTableMutator<'msg, T> {
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`.
unsafe { self.vtable.cast().as_ref() }
}
pub fn msg_ref(self) -> MutatorMessageRef<'msg> {
self.msg_ref
}
}
/// [`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 }
}
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`.
unsafe { self.optional_vtable.cast().as_ref() }
}
@ -507,10 +515,8 @@ impl<'msg, T: PrimitiveWithRawVTable> RawVTableOptionalMutatorData<'msg, T> {
}
#[derive(Debug)]
#[allow(unused)]
pub struct MessageOptionalVTable {
pub base: MessageVTable,
pub struct MessageVTable {
pub getter: unsafe extern "C" fn(msg: RawMessage) -> RawMessage,
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;
fn make_view(_private: $pbi$::Private,
_mut_inner: $pbi$::RawVTableMutator<'_, Self>)
mut_inner: $pbi$::RawVTableMutator<'_, 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,
_inner: $pbi$::RawVTableMutator<'_, Self>)
inner: $pbi$::RawVTableMutator<'_, 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$ {
type OptionalVTable = $pbi$::MessageOptionalVTable;
type OptionalVTable = $pbi$::MessageVTable;
fn upcast_vtable(_private: $pbi$::Private,
optional_vtable: &'static Self::OptionalVTable)
-> &'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 AbsentMutData<'a> = $pbr$::MessageAbsentMutData<'a, $Msg$>;
fn clear_present_field(_present_mutator: Self::PresentMutData<'_>)
fn clear_present_field(present_mutator: Self::PresentMutData<'_>)
-> 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<'_> {
todo!();
unsafe {
$pbi$::RawVTableOptionalMutatorData::new($pbi$::Private,
absent_mutator.msg_ref(),
absent_mutator.optional_vtable())
}
}
}

Loading…
Cancel
Save