@ -22,42 +22,82 @@ void SingularMessage::InMsgImpl(Context<FieldDescriptor> field) const {
auto prefix = " crate:: " + GetCrateRelativeQualifiedPath ( d ) ;
if ( field . is_cpp ( ) ) {
field . Emit ( { { " prefix " , prefix } ,
{ " field " , field . desc ( ) . name ( ) } ,
{ " getter_thunk " , Thunk ( field , " get " ) } } ,
R " rs(
pub fn r # $ field $ ( & self ) - > $ prefix $ View {
// For C++ kernel, getters automatically return the
// default_instance if the field is unset.
let submsg = unsafe { $ getter_thunk $ ( self . inner . msg ) } ;
$ prefix $ View : : new ( $ pbi $ : : Private , submsg )
}
) rs " );
} else {
field . Emit ( { { " prefix " , prefix } ,
{ " field " , field . desc ( ) . name ( ) } ,
{ " getter_thunk " , Thunk ( field , " get " ) } } ,
R " rs(
pub fn r # $ field $ ( & self ) - > $ prefix $ View {
let submsg = unsafe { $ getter_thunk $ ( self . inner . msg ) } ;
// For upb, getters return null if the field is unset, so we need to
// check for null and return the default instance manually. Note that
// a null ptr received from upb manifests as Option::None
match submsg {
field . Emit (
{
{ " prefix " , prefix } ,
{ " field " , field . desc ( ) . name ( ) } ,
{ " getter_thunk " , Thunk ( field , " get " ) } ,
{ " clearer_thunk " , Thunk ( field , " clear " ) } ,
{
" view_body " ,
[ & ] {
if ( field . is_upb ( ) ) {
field . Emit ( { } , R " rs(
let submsg = unsafe { $ getter_thunk $ ( self . inner . msg ) } ;
// For upb, getters return null if the field is unset, so we need
// to check for null and return the default instance manually.
// Note that a nullptr received from upb manifests as Option::None
match submsg {
// TODO:(b/304357029)
None = > $ prefix $ View : : new ( $ pbi $ : : Private , $ pbr $ : : ScratchSpace : : zeroed_block ( $ pbi $ : : Private ) ) ,
None = > $ prefix $ View : : new ( $ pbi $ : : Private ,
$ pbr $ : : ScratchSpace : : zeroed_block ( $ pbi $ : : Private ) ) ,
Some ( field ) = > $ prefix $ View : : new ( $ pbi $ : : Private , field ) ,
}
}
) rs " );
}
} else {
field . Emit ( { } , R " rs(
// For C++ kernel, getters automatically return the
// default_instance if the field is unset.
let submsg = unsafe { $ getter_thunk $ ( self . inner . msg ) } ;
$ prefix $ View : : new ( $ pbi $ : : Private , submsg )
) rs " );
}
} ,
} ,
{ " submessage_mut " ,
[ & ] {
if ( field . is_upb ( ) ) {
field . Emit ( { } , R " rs(
let submsg_opt = unsafe { $ getter_thunk $ ( self . inner . msg ) } ;
match submsg_opt {
None = > {
$ prefix $ Mut : : new ( $ pbi $ : : Private ,
& mut self . inner ,
$ pbr $ : : ScratchSpace : : zeroed_block ( $ pbi $ : : Private ) )
} ,
Some ( submsg ) = > {
$ prefix $ Mut : : new ( $ pbi $ : : Private , & mut self . inner , submsg )
}
}
) rs " );
} else {
field . Emit ( { } , R " rs(
let submsg = unsafe { $ getter_thunk $ ( self . inner . msg ) } ;
$ prefix $ Mut : : new ( $ pbi $ : : Private , & mut self . inner , submsg )
) rs " );
}
} } ,
} ,
R " rs(
pub fn r # $ field $ ( & self ) - > $ prefix $ View {
$ view_body $
}
pub fn $ field $ _mut ( & mut self ) - > $ prefix $ Mut {
$ submessage_mut $
}
pub fn $ field $ _clear ( & mut self ) {
unsafe { $ clearer_thunk $ ( self . inner . msg ) }
}
) rs " );
}
void SingularMessage : : InExternC ( Context < FieldDescriptor > field ) const {
field . Emit (
{
{ " getter_thunk " , Thunk ( field , " get " ) } ,
{ " clearer_thunk " , Thunk ( field , " clear " ) } ,
{ " ReturnType " ,
[ & ] {
if ( field . is_cpp ( ) ) {
@ -72,6 +112,7 @@ void SingularMessage::InExternC(Context<FieldDescriptor> field) const {
} ,
R " rs(
fn $ getter_thunk $ ( raw_msg : $ pbi $ : : RawMessage ) - > $ ReturnType $ ;
fn $ clearer_thunk $ ( raw_msg : $ pbi $ : : RawMessage ) ;
) rs " );
}
@ -79,11 +120,13 @@ void SingularMessage::InThunkCc(Context<FieldDescriptor> field) const {
field . Emit ( { { " QualifiedMsg " ,
cpp : : QualifiedClassName ( field . desc ( ) . containing_type ( ) ) } ,
{ " getter_thunk " , Thunk ( field , " get " ) } ,
{ " clearer_thunk " , Thunk ( field , " clear " ) } ,
{ " field " , cpp : : FieldName ( & field . desc ( ) ) } } ,
R " cc(
const void * $ getter_thunk $ ( $ QualifiedMsg $ * msg ) {
return static_cast < const void * > ( & msg - > $ field $ ( ) ) ;
}
void $ clearer_thunk $ ( $ QualifiedMsg $ * msg ) { msg - > clear_ $ field $ ( ) ; }
) cc " );
}