From e320c85283b913fc15d9ef2dc4bad04eb60d262e Mon Sep 17 00:00:00 2001 From: Hong Shin Date: Wed, 24 Jan 2024 14:13:04 -0800 Subject: [PATCH] Move MessageVTable to $pbr$ from $pbi$ Part 3 of 4 (added a stage). The getter and mut_getter bifurcate based on the kernel. upb returns Option, while cpp returns the RawMessage. This means that we can't have a unified MessageVTable in vtable.rs, so we've split these out in {upb.rs and cpp.rs}. $field$_entry is now prepped and populated for the $field$_mut swappage in the following CL. PiperOrigin-RevId: 601230880 --- rust/cpp.rs | 18 ++++++++++++++ rust/internal.rs | 7 +++--- rust/upb.rs | 18 ++++++++++++++ rust/vtable.rs | 7 ------ .../rust/accessors/singular_message.cc | 18 +++++++++++++- src/google/protobuf/compiler/rust/message.cc | 24 +++++++++++++++---- 6 files changed, 75 insertions(+), 17 deletions(-) diff --git a/rust/cpp.rs b/rust/cpp.rs index ce8cdcad46..35ee4afe6d 100644 --- a/rust/cpp.rs +++ b/rust/cpp.rs @@ -158,6 +158,24 @@ pub type BytesAbsentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData< pub type InnerBytesMut<'msg> = crate::vtable::RawVTableMutator<'msg, [u8]>; pub type InnerPrimitiveMut<'msg, T> = crate::vtable::RawVTableMutator<'msg, T>; +#[derive(Debug)] +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), +} + +impl MessageVTable { + pub const fn new( + _private: Private, + getter: unsafe extern "C" fn(msg: RawMessage) -> RawMessage, + mut_getter: unsafe extern "C" fn(msg: RawMessage) -> RawMessage, + clearer: unsafe extern "C" fn(msg: RawMessage), + ) -> Self { + MessageVTable { getter, mut_getter, clearer } + } +} + /// The raw contents of every generated message. #[derive(Debug)] pub struct MessageInner { diff --git a/rust/internal.rs b/rust/internal.rs index ac7d67367b..b1b77db3bd 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -11,10 +11,9 @@ pub use crate::r#enum::Enum; pub use crate::vtable::{ - new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, MessageVTable, - PrimitiveOptionalMutVTable, PrimitiveVTable, PrimitiveWithRawVTable, - ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, RawVTableMutator, - RawVTableOptionalMutatorData, + new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, PrimitiveOptionalMutVTable, + PrimitiveVTable, PrimitiveWithRawVTable, ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, + RawVTableMutator, RawVTableOptionalMutatorData, }; pub use crate::ProtoStr; use std::ptr::NonNull; diff --git a/rust/upb.rs b/rust/upb.rs index e9c0e1334c..6a1c65e169 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -240,6 +240,24 @@ pub type BytesAbsentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData< pub type InnerBytesMut<'msg> = crate::vtable::RawVTableMutator<'msg, [u8]>; pub type InnerPrimitiveMut<'msg, T> = crate::vtable::RawVTableMutator<'msg, T>; +#[derive(Debug)] +pub struct MessageVTable { + pub getter: unsafe extern "C" fn(msg: RawMessage) -> Option, + pub mut_getter: unsafe extern "C" fn(msg: RawMessage, arena: RawArena) -> RawMessage, + pub clearer: unsafe extern "C" fn(msg: RawMessage), +} + +impl MessageVTable { + pub const fn new( + _private: Private, + getter: unsafe extern "C" fn(msg: RawMessage) -> Option, + mut_getter: unsafe extern "C" fn(msg: RawMessage, arena: RawArena) -> RawMessage, + clearer: unsafe extern "C" fn(msg: RawMessage), + ) -> Self { + MessageVTable { getter, mut_getter, clearer } + } +} + /// The raw contents of every generated message. #[derive(Debug)] pub struct MessageInner { diff --git a/rust/vtable.rs b/rust/vtable.rs index f577f994fb..3e8802a329 100644 --- a/rust/vtable.rs +++ b/rust/vtable.rs @@ -513,10 +513,3 @@ impl<'msg, T: PrimitiveWithRawVTable> RawVTableOptionalMutatorData<'msg, T> { self } } - -#[derive(Debug)] -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), -} diff --git a/src/google/protobuf/compiler/rust/accessors/singular_message.cc b/src/google/protobuf/compiler/rust/accessors/singular_message.cc index 06a57d54e4..b617d7dce8 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_message.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_message.cc @@ -31,6 +31,7 @@ void SingularMessage::InMsgImpl(Context& ctx, const FieldDescriptor& field, {"getter_thunk", ThunkName(ctx, field, "get")}, {"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}, {"clearer_thunk", ThunkName(ctx, field, "clear")}, + {"hazzer_thunk", ThunkName(ctx, field, "has")}, { "getter_body", [&] { @@ -95,7 +96,18 @@ void SingularMessage::InMsgImpl(Context& ctx, const FieldDescriptor& field, //~ this to $field$_mut and update all unit tests pub fn $field$_entry(&mut self) -> $pb$::FieldEntry<'_, $msg_type$> { - todo!() + static VTABLE: $pbr$::MessageVTable = + $pbr$::MessageVTable::new($pbi$::Private, + $getter_thunk$, + $getter_mut_thunk$, + $clearer_thunk$); + unsafe { + let has = $hazzer_thunk$(self.raw_msg()); + $pbi$::new_vtable_field_entry($pbi$::Private, + self.as_mutator_message_ref(), + &VTABLE, + has) + } } )rs"); }}, @@ -123,6 +135,7 @@ void SingularMessage::InExternC(Context& ctx, {"getter_thunk", ThunkName(ctx, field, "get")}, {"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}, {"clearer_thunk", ThunkName(ctx, field, "clear")}, + {"hazzer_thunk", ThunkName(ctx, field, "has")}, {"getter_mut", [&] { if (ctx.is_cpp()) { @@ -153,6 +166,7 @@ void SingularMessage::InExternC(Context& ctx, fn $getter_thunk$(raw_msg: $pbi$::RawMessage) -> $ReturnType$; $getter_mut$ fn $clearer_thunk$(raw_msg: $pbi$::RawMessage); + fn $hazzer_thunk$(raw_msg: $pbi$::RawMessage) -> bool; )rs"); } @@ -162,6 +176,7 @@ void SingularMessage::InThunkCc(Context& ctx, {"getter_thunk", ThunkName(ctx, field, "get")}, {"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}, {"clearer_thunk", ThunkName(ctx, field, "clear")}, + {"hazzer_thunk", ThunkName(ctx, field, "has")}, {"field", cpp::FieldName(&field)}}, R"cc( const void* $getter_thunk$($QualifiedMsg$* msg) { @@ -171,6 +186,7 @@ void SingularMessage::InThunkCc(Context& ctx, return static_cast(msg->mutable_$field$()); } void $clearer_thunk$($QualifiedMsg$* msg) { msg->clear_$field$(); } + bool $hazzer_thunk$($QualifiedMsg$* msg) { return msg->has_$field$(); } )cc"); } diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index 2185babecc..bf46010110 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -520,7 +520,21 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { } }}, {"settable_impl", [&] { MessageSettableValue(ctx, msg); }}, - {"repeated_impl", [&] { MessageProxiedInRepeated(ctx, msg); }}}, + {"repeated_impl", [&] { MessageProxiedInRepeated(ctx, msg); }}, + {"unwrap_upb", + [&] { + if (ctx.is_upb()) { + ctx.Emit( + ".unwrap_or_else(||$pbr$::ScratchSpace::zeroed_block($pbi$::" + "Private))"); + } + }}, + {"upb_arena", + [&] { + if (ctx.is_upb()) { + ctx.Emit(", inner.msg_ref().arena($pbi$::Private).raw()"); + } + }}}, R"rs( #[allow(non_camel_case_types)] //~ TODO: Implement support for debug redaction @@ -583,7 +597,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { } impl $pbi$::ProxiedWithRawVTable for $Msg$ { - type VTable = $pbi$::MessageVTable; + type VTable = $pbr$::MessageVTable; fn make_view(_private: $pbi$::Private, mut_inner: $pbi$::RawVTableMutator<'_, Self>) @@ -591,21 +605,21 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { let msg = unsafe { (mut_inner.vtable().getter)(mut_inner.msg_ref().msg()) }; - $Msg$View::new($pbi$::Private, msg) + $Msg$View::new($pbi$::Private, msg$unwrap_upb$) } fn make_mut(_private: $pbi$::Private, inner: $pbi$::RawVTableMutator<'_, Self>) -> $pb$::Mut<'_, Self> { let raw_submsg = unsafe { - (inner.vtable().mut_getter)(inner.msg_ref().msg()) + (inner.vtable().mut_getter)(inner.msg_ref().msg()$upb_arena$) }; $Msg$Mut::from_parent($pbi$::Private, inner.msg_ref(), raw_submsg) } } impl $pbi$::ProxiedWithRawOptionalVTable for $Msg$ { - type OptionalVTable = $pbi$::MessageVTable; + type OptionalVTable = $pbr$::MessageVTable; fn upcast_vtable(_private: $pbi$::Private, optional_vtable: &'static Self::OptionalVTable)