@ -9,6 +9,7 @@
# include "absl/log/absl_check.h"
# include "absl/log/absl_check.h"
# include "absl/log/absl_log.h"
# include "absl/log/absl_log.h"
# include "absl/strings/str_format.h"
# include "absl/strings/string_view.h"
# include "absl/strings/string_view.h"
# include "google/protobuf/compiler/cpp/helpers.h"
# include "google/protobuf/compiler/cpp/helpers.h"
# include "google/protobuf/compiler/cpp/names.h"
# include "google/protobuf/compiler/cpp/names.h"
@ -163,6 +164,10 @@ void MessageDrop(Context& ctx, const Descriptor& msg) {
) rs " );
) rs " );
}
}
bool IsStringOrBytes ( FieldDescriptor : : Type t ) {
return t = = FieldDescriptor : : TYPE_STRING | | t = = FieldDescriptor : : TYPE_BYTES ;
}
void GetterForViewOrMut ( Context & ctx , const FieldDescriptor & field ,
void GetterForViewOrMut ( Context & ctx , const FieldDescriptor & field ,
bool is_mut ) {
bool is_mut ) {
auto fieldName = field . name ( ) ;
auto fieldName = field . name ( ) ;
@ -218,89 +223,62 @@ void GetterForViewOrMut(Context& ctx, const FieldDescriptor& field,
}
}
auto rsType = PrimitiveRsTypeName ( field ) ;
auto rsType = PrimitiveRsTypeName ( field ) ;
if ( fieldType = = FieldDescriptor : : TYPE_STRING | |
auto asRef = IsStringOrBytes ( fieldType ) ? " .as_ref() " : " " ;
fieldType = = FieldDescriptor : : TYPE_BYTES ) {
auto vtable =
ctx . Emit ( { { " field " , fieldName } ,
IsStringOrBytes ( fieldType ) ? " BytesMutVTable " : " PrimitiveVTable " ;
{ " self " , self } ,
// PrimitiveVtable is parameterized based on the underlying primitive, like
{ " getter_thunk " , getter_thunk } ,
// u32 so we need to provide this additional type arg
{ " setter_thunk " , setter_thunk } ,
auto optionalTypeArgs =
{ " RsType " , rsType } ,
IsStringOrBytes ( fieldType ) ? " " : absl : : StrFormat ( " <%s> " , rsType ) ;
{ " maybe_mutator " ,
// need to stuff ProtoStr and [u8] behind a reference since they are DSTs
[ & ] {
auto stringTransform =
if ( is_mut ) {
IsStringOrBytes ( fieldType )
ctx . Emit ( { } , R " rs(
? " unsafe { __pb::ProtoStr::from_utf8_unchecked(res).into() } "
pub fn r # $ field $ _mut ( & self ) - > $ pb $ : : Mut < ' _ , $ RsType $ > {
: " res " ;
static VTABLE : $ pbi $ : : BytesMutVTable =
$ pbi $ : : BytesMutVTable : : new (
ctx . Emit ( { { " field " , fieldName } ,
$ pbi $ : : Private ,
{ " getter_thunk " , getter_thunk } ,
$ getter_thunk $ ,
{ " setter_thunk " , setter_thunk } ,
$ setter_thunk $ ,
{ " clearer_thunk " , clearer_thunk } ,
) ;
{ " self " , self } ,
{ " RsType " , rsType } ,
unsafe {
{ " as_ref " , asRef } ,
< $ pb $ : : Mut < $ RsType $ > > : : from_inner (
{ " vtable " , vtable } ,
$ pbi $ : : Private ,
{ " optional_type_args " , optionalTypeArgs } ,
$ pbi $ : : RawVTableMutator : : new (
{ " string_transform " , stringTransform } ,
$ pbi $ : : Private ,
{ " maybe_mutator " ,
self . inner ,
[ & ] {
& VTABLE ,
// TODO: check mutational pathway genn'd correctly
)
if ( is_mut ) {
)
ctx . Emit ( { } , R " rs(
}
pub fn r # $ field $ _mut ( & self ) - > $ pb $ : : Mut < ' _ , $ RsType $ > {
}
static VTABLE : $ pbi $ : : $ vtable $ $ optional_type_args $ =
) rs " );
$ pbi $ : : $ vtable $ : : new (
}
$ pbi $ : : Private ,
} } } ,
$ getter_thunk $ ,
R " rs(
$ setter_thunk $ ) ;
pub fn r # $ field $ ( & self ) - > $ pb $ : : View < ' _ , $ RsType $ > {
unsafe {
let s = unsafe { $ getter_thunk $ ( $ self $ ) . as_ref ( ) } ;
< $ pb $ : : Mut < $ RsType $ > > : : from_inner (
unsafe { __pb : : ProtoStr : : from_utf8_unchecked ( s ) . into ( ) }
$ pbi $ : : Private ,
}
$ pbi $ : : RawVTableMutator : : new (
$ maybe_mutator $
) rs " );
} else {
ctx . Emit ( { { " field " , fieldName } ,
{ " getter_thunk " , getter_thunk } ,
{ " setter_thunk " , setter_thunk } ,
{ " clearer_thunk " , clearer_thunk } ,
{ " self " , self } ,
{ " RsType " , rsType } ,
{ " maybe_mutator " ,
[ & ] {
// TODO: once the rust public api is accessible,
// by tooling, ensure that this only appears for the
// mutational pathway
if ( is_mut & & fieldType ) {
ctx . Emit ( { } , R " rs(
pub fn r # $ field $ _mut ( & self ) - > $ pb $ : : Mut < ' _ , $ RsType $ > {
static VTABLE : $ pbi $ : : PrimitiveVTable < $ RsType $ > =
$ pbi $ : : PrimitiveVTable : : new (
$ pbi $ : : Private ,
$ getter_thunk $ ,
$ setter_thunk $ ) ;
unsafe {
$ pb $ : : PrimitiveMut : : from_inner (
$ pbi $ : : Private ,
$ pbi $ : : Private ,
$ pbi $ : : RawVTableMutator : : new (
self . inner ,
$ pbi $ : : Private ,
& VTABLE
self . inner ,
) ,
& VTABLE
)
) ,
)
}
}
}
) rs " );
}
}
) rs " );
} } } ,
}
R " rs(
} } } ,
pub fn r # $ field $ ( & self ) - > $ pb $ : : View < ' _ , $ RsType $ > {
R " rs(
unsafe { $ getter_thunk $ ( $ self $ ) }
pub fn r # $ field $ ( & self ) - > $ pb $ : : View < ' _ , $ RsType $ > {
}
let res = unsafe { $ getter_thunk $ ( $ self $ ) $ as_ref $ } ;
$ string_transform $
}
$ maybe_mutator $
$ maybe_mutator $
) rs " );
) rs " );
}
}
}
void AccessorsForViewOrMut ( Context & ctx , const Descriptor & msg , bool is_mut ) {
void AccessorsForViewOrMut ( Context & ctx , const Descriptor & msg , bool is_mut ) {