|
|
@ -24,16 +24,16 @@ namespace compiler { |
|
|
|
namespace rust { |
|
|
|
namespace rust { |
|
|
|
namespace { |
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|
|
|
void MessageNew(Context<Descriptor> msg) { |
|
|
|
void MessageNew(Context& ctx, const Descriptor& msg) { |
|
|
|
switch (msg.opts().kernel) { |
|
|
|
switch (ctx.opts().kernel) { |
|
|
|
case Kernel::kCpp: |
|
|
|
case Kernel::kCpp: |
|
|
|
msg.Emit({{"new_thunk", Thunk(msg, "new")}}, R"rs( |
|
|
|
ctx.Emit({{"new_thunk", Thunk(ctx, msg, "new")}}, R"rs( |
|
|
|
Self { inner: $pbr$::MessageInner { msg: unsafe { $new_thunk$() } } } |
|
|
|
Self { inner: $pbr$::MessageInner { msg: unsafe { $new_thunk$() } } } |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
case Kernel::kUpb: |
|
|
|
case Kernel::kUpb: |
|
|
|
msg.Emit({{"new_thunk", Thunk(msg, "new")}}, R"rs( |
|
|
|
ctx.Emit({{"new_thunk", Thunk(ctx, msg, "new")}}, R"rs( |
|
|
|
let arena = $pbr$::Arena::new(); |
|
|
|
let arena = $pbr$::Arena::new(); |
|
|
|
Self { |
|
|
|
Self { |
|
|
|
inner: $pbr$::MessageInner { |
|
|
|
inner: $pbr$::MessageInner { |
|
|
@ -48,16 +48,16 @@ void MessageNew(Context<Descriptor> msg) { |
|
|
|
ABSL_LOG(FATAL) << "unreachable"; |
|
|
|
ABSL_LOG(FATAL) << "unreachable"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void MessageSerialize(Context<Descriptor> msg) { |
|
|
|
void MessageSerialize(Context& ctx, const Descriptor& msg) { |
|
|
|
switch (msg.opts().kernel) { |
|
|
|
switch (ctx.opts().kernel) { |
|
|
|
case Kernel::kCpp: |
|
|
|
case Kernel::kCpp: |
|
|
|
msg.Emit({{"serialize_thunk", Thunk(msg, "serialize")}}, R"rs( |
|
|
|
ctx.Emit({{"serialize_thunk", Thunk(ctx, msg, "serialize")}}, R"rs( |
|
|
|
unsafe { $serialize_thunk$(self.inner.msg) } |
|
|
|
unsafe { $serialize_thunk$(self.inner.msg) } |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
case Kernel::kUpb: |
|
|
|
case Kernel::kUpb: |
|
|
|
msg.Emit({{"serialize_thunk", Thunk(msg, "serialize")}}, R"rs( |
|
|
|
ctx.Emit({{"serialize_thunk", Thunk(ctx, msg, "serialize")}}, R"rs( |
|
|
|
let arena = $pbr$::Arena::new(); |
|
|
|
let arena = $pbr$::Arena::new(); |
|
|
|
let mut len = 0; |
|
|
|
let mut len = 0; |
|
|
|
unsafe { |
|
|
|
unsafe { |
|
|
@ -71,12 +71,12 @@ void MessageSerialize(Context<Descriptor> msg) { |
|
|
|
ABSL_LOG(FATAL) << "unreachable"; |
|
|
|
ABSL_LOG(FATAL) << "unreachable"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void MessageDeserialize(Context<Descriptor> msg) { |
|
|
|
void MessageDeserialize(Context& ctx, const Descriptor& msg) { |
|
|
|
switch (msg.opts().kernel) { |
|
|
|
switch (ctx.opts().kernel) { |
|
|
|
case Kernel::kCpp: |
|
|
|
case Kernel::kCpp: |
|
|
|
msg.Emit( |
|
|
|
ctx.Emit( |
|
|
|
{ |
|
|
|
{ |
|
|
|
{"deserialize_thunk", Thunk(msg, "deserialize")}, |
|
|
|
{"deserialize_thunk", Thunk(ctx, msg, "deserialize")}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
R"rs( |
|
|
|
R"rs( |
|
|
|
let success = unsafe { |
|
|
|
let success = unsafe { |
|
|
@ -92,7 +92,7 @@ void MessageDeserialize(Context<Descriptor> msg) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
case Kernel::kUpb: |
|
|
|
case Kernel::kUpb: |
|
|
|
msg.Emit({{"deserialize_thunk", Thunk(msg, "parse")}}, R"rs( |
|
|
|
ctx.Emit({{"deserialize_thunk", Thunk(ctx, msg, "parse")}}, R"rs( |
|
|
|
let arena = $pbr$::Arena::new(); |
|
|
|
let arena = $pbr$::Arena::new(); |
|
|
|
let msg = unsafe { |
|
|
|
let msg = unsafe { |
|
|
|
$deserialize_thunk$(data.as_ptr(), data.len(), arena.raw()) |
|
|
|
$deserialize_thunk$(data.as_ptr(), data.len(), arena.raw()) |
|
|
@ -115,15 +115,15 @@ void MessageDeserialize(Context<Descriptor> msg) { |
|
|
|
ABSL_LOG(FATAL) << "unreachable"; |
|
|
|
ABSL_LOG(FATAL) << "unreachable"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void MessageExterns(Context<Descriptor> msg) { |
|
|
|
void MessageExterns(Context& ctx, const Descriptor& msg) { |
|
|
|
switch (msg.opts().kernel) { |
|
|
|
switch (ctx.opts().kernel) { |
|
|
|
case Kernel::kCpp: |
|
|
|
case Kernel::kCpp: |
|
|
|
msg.Emit( |
|
|
|
ctx.Emit( |
|
|
|
{ |
|
|
|
{ |
|
|
|
{"new_thunk", Thunk(msg, "new")}, |
|
|
|
{"new_thunk", Thunk(ctx, msg, "new")}, |
|
|
|
{"delete_thunk", Thunk(msg, "delete")}, |
|
|
|
{"delete_thunk", Thunk(ctx, msg, "delete")}, |
|
|
|
{"serialize_thunk", Thunk(msg, "serialize")}, |
|
|
|
{"serialize_thunk", Thunk(ctx, msg, "serialize")}, |
|
|
|
{"deserialize_thunk", Thunk(msg, "deserialize")}, |
|
|
|
{"deserialize_thunk", Thunk(ctx, msg, "deserialize")}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
R"rs( |
|
|
|
R"rs( |
|
|
|
fn $new_thunk$() -> $pbi$::RawMessage; |
|
|
|
fn $new_thunk$() -> $pbi$::RawMessage; |
|
|
@ -134,11 +134,11 @@ void MessageExterns(Context<Descriptor> msg) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
case Kernel::kUpb: |
|
|
|
case Kernel::kUpb: |
|
|
|
msg.Emit( |
|
|
|
ctx.Emit( |
|
|
|
{ |
|
|
|
{ |
|
|
|
{"new_thunk", Thunk(msg, "new")}, |
|
|
|
{"new_thunk", Thunk(ctx, msg, "new")}, |
|
|
|
{"serialize_thunk", Thunk(msg, "serialize")}, |
|
|
|
{"serialize_thunk", Thunk(ctx, msg, "serialize")}, |
|
|
|
{"deserialize_thunk", Thunk(msg, "parse")}, |
|
|
|
{"deserialize_thunk", Thunk(ctx, msg, "parse")}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
R"rs( |
|
|
|
R"rs( |
|
|
|
fn $new_thunk$(arena: $pbi$::RawArena) -> $pbi$::RawMessage; |
|
|
|
fn $new_thunk$(arena: $pbi$::RawArena) -> $pbi$::RawMessage; |
|
|
@ -151,36 +151,37 @@ void MessageExterns(Context<Descriptor> msg) { |
|
|
|
ABSL_LOG(FATAL) << "unreachable"; |
|
|
|
ABSL_LOG(FATAL) << "unreachable"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void MessageDrop(Context<Descriptor> msg) { |
|
|
|
void MessageDrop(Context& ctx, const Descriptor& msg) { |
|
|
|
if (msg.is_upb()) { |
|
|
|
if (ctx.is_upb()) { |
|
|
|
// Nothing to do here; drop glue (which will run drop(self.arena)
|
|
|
|
// Nothing to do here; drop glue (which will run drop(self.arena)
|
|
|
|
// automatically) is sufficient.
|
|
|
|
// automatically) is sufficient.
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
msg.Emit({{"delete_thunk", Thunk(msg, "delete")}}, R"rs( |
|
|
|
ctx.Emit({{"delete_thunk", Thunk(ctx, msg, "delete")}}, R"rs( |
|
|
|
unsafe { $delete_thunk$(self.inner.msg); } |
|
|
|
unsafe { $delete_thunk$(self.inner.msg); } |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void GetterForViewOrMut(Context<FieldDescriptor> field, bool is_mut) { |
|
|
|
void GetterForViewOrMut(Context& ctx, const FieldDescriptor& field, |
|
|
|
auto fieldName = field.desc().name(); |
|
|
|
bool is_mut) { |
|
|
|
auto fieldType = field.desc().type(); |
|
|
|
auto fieldName = field.name(); |
|
|
|
auto getter_thunk = Thunk(field, "get"); |
|
|
|
auto fieldType = field.type(); |
|
|
|
auto setter_thunk = Thunk(field, "set"); |
|
|
|
auto getter_thunk = Thunk(ctx, field, "get"); |
|
|
|
auto clearer_thunk = Thunk(field, "clear"); |
|
|
|
auto setter_thunk = Thunk(ctx, field, "set"); |
|
|
|
|
|
|
|
auto clearer_thunk = Thunk(ctx, field, "clear"); |
|
|
|
// If we're dealing with a Mut, the getter must be supplied
|
|
|
|
// If we're dealing with a Mut, the getter must be supplied
|
|
|
|
// self.inner.msg() whereas a View has to be supplied self.msg
|
|
|
|
// self.inner.msg() whereas a View has to be supplied self.msg
|
|
|
|
auto self = is_mut ? "self.inner.msg()" : "self.msg"; |
|
|
|
auto self = is_mut ? "self.inner.msg()" : "self.msg"; |
|
|
|
|
|
|
|
|
|
|
|
if (fieldType == FieldDescriptor::TYPE_MESSAGE) { |
|
|
|
if (fieldType == FieldDescriptor::TYPE_MESSAGE) { |
|
|
|
Context<Descriptor> d = field.WithDesc(field.desc().message_type()); |
|
|
|
const Descriptor& msg = *field.message_type(); |
|
|
|
// TODO: support messages which are defined in other crates.
|
|
|
|
// TODO: support messages which are defined in other crates.
|
|
|
|
if (!IsInCurrentlyGeneratingCrate(d)) { |
|
|
|
if (!IsInCurrentlyGeneratingCrate(ctx, msg)) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
auto prefix = "crate::" + GetCrateRelativeQualifiedPath(d); |
|
|
|
auto prefix = "crate::" + GetCrateRelativeQualifiedPath(ctx, msg); |
|
|
|
field.Emit( |
|
|
|
ctx.Emit( |
|
|
|
{ |
|
|
|
{ |
|
|
|
{"prefix", prefix}, |
|
|
|
{"prefix", prefix}, |
|
|
|
{"field", fieldName}, |
|
|
|
{"field", fieldName}, |
|
|
@ -190,8 +191,8 @@ void GetterForViewOrMut(Context<FieldDescriptor> field, bool is_mut) { |
|
|
|
{ |
|
|
|
{ |
|
|
|
"view_body", |
|
|
|
"view_body", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
if (field.is_upb()) { |
|
|
|
if (ctx.is_upb()) { |
|
|
|
field.Emit({}, R"rs( |
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
let submsg = unsafe { $getter_thunk$($self$) }; |
|
|
|
let submsg = unsafe { $getter_thunk$($self$) }; |
|
|
|
match submsg { |
|
|
|
match submsg { |
|
|
|
None => $prefix$View::new($pbi$::Private, |
|
|
|
None => $prefix$View::new($pbi$::Private, |
|
|
@ -200,7 +201,7 @@ void GetterForViewOrMut(Context<FieldDescriptor> field, bool is_mut) { |
|
|
|
} |
|
|
|
} |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
field.Emit({}, R"rs( |
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
let submsg = unsafe { $getter_thunk$($self$) }; |
|
|
|
let submsg = unsafe { $getter_thunk$($self$) }; |
|
|
|
$prefix$View::new($pbi$::Private, submsg) |
|
|
|
$prefix$View::new($pbi$::Private, submsg) |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
@ -216,18 +217,18 @@ void GetterForViewOrMut(Context<FieldDescriptor> field, bool is_mut) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto rsType = PrimitiveRsTypeName(field.desc()); |
|
|
|
auto rsType = PrimitiveRsTypeName(field); |
|
|
|
if (fieldType == FieldDescriptor::TYPE_STRING || |
|
|
|
if (fieldType == FieldDescriptor::TYPE_STRING || |
|
|
|
fieldType == FieldDescriptor::TYPE_BYTES) { |
|
|
|
fieldType == FieldDescriptor::TYPE_BYTES) { |
|
|
|
field.Emit({{"field", fieldName}, |
|
|
|
ctx.Emit({{"field", fieldName}, |
|
|
|
{"self", self}, |
|
|
|
{"self", self}, |
|
|
|
{"getter_thunk", getter_thunk}, |
|
|
|
{"getter_thunk", getter_thunk}, |
|
|
|
{"setter_thunk", setter_thunk}, |
|
|
|
{"setter_thunk", setter_thunk}, |
|
|
|
{"RsType", rsType}, |
|
|
|
{"RsType", rsType}, |
|
|
|
{"maybe_mutator", |
|
|
|
{"maybe_mutator", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
if (is_mut) { |
|
|
|
if (is_mut) { |
|
|
|
field.Emit({}, R"rs( |
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
pub fn r#$field$_mut(&self) -> $pb$::Mut<'_, $RsType$> { |
|
|
|
pub fn r#$field$_mut(&self) -> $pb$::Mut<'_, $RsType$> { |
|
|
|
static VTABLE: $pbi$::BytesMutVTable =
|
|
|
|
static VTABLE: $pbi$::BytesMutVTable =
|
|
|
|
$pbi$::BytesMutVTable::new( |
|
|
|
$pbi$::BytesMutVTable::new( |
|
|
@ -248,9 +249,9 @@ void GetterForViewOrMut(Context<FieldDescriptor> field, bool is_mut) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
} |
|
|
|
} |
|
|
|
}}}, |
|
|
|
}}}, |
|
|
|
R"rs( |
|
|
|
R"rs( |
|
|
|
pub fn r#$field$(&self) -> $pb$::View<'_, $RsType$> { |
|
|
|
pub fn r#$field$(&self) -> $pb$::View<'_, $RsType$> { |
|
|
|
let s = unsafe { $getter_thunk$($self$).as_ref() }; |
|
|
|
let s = unsafe { $getter_thunk$($self$).as_ref() }; |
|
|
|
unsafe { __pb::ProtoStr::from_utf8_unchecked(s).into() } |
|
|
|
unsafe { __pb::ProtoStr::from_utf8_unchecked(s).into() } |
|
|
@ -259,19 +260,19 @@ void GetterForViewOrMut(Context<FieldDescriptor> field, bool is_mut) { |
|
|
|
$maybe_mutator$ |
|
|
|
$maybe_mutator$ |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
field.Emit({{"field", fieldName}, |
|
|
|
ctx.Emit({{"field", fieldName}, |
|
|
|
{"getter_thunk", getter_thunk}, |
|
|
|
{"getter_thunk", getter_thunk}, |
|
|
|
{"setter_thunk", setter_thunk}, |
|
|
|
{"setter_thunk", setter_thunk}, |
|
|
|
{"clearer_thunk", clearer_thunk}, |
|
|
|
{"clearer_thunk", clearer_thunk}, |
|
|
|
{"self", self}, |
|
|
|
{"self", self}, |
|
|
|
{"RsType", rsType}, |
|
|
|
{"RsType", rsType}, |
|
|
|
{"maybe_mutator", |
|
|
|
{"maybe_mutator", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
// TODO: once the rust public api is accessible,
|
|
|
|
// TODO: once the rust public api is accessible,
|
|
|
|
// by tooling, ensure that this only appears for the
|
|
|
|
// by tooling, ensure that this only appears for the
|
|
|
|
// mutational pathway
|
|
|
|
// mutational pathway
|
|
|
|
if (is_mut && fieldType) { |
|
|
|
if (is_mut && fieldType) { |
|
|
|
field.Emit({}, R"rs( |
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
pub fn r#$field$_mut(&self) -> $pb$::Mut<'_, $RsType$> { |
|
|
|
pub fn r#$field$_mut(&self) -> $pb$::Mut<'_, $RsType$> { |
|
|
|
static VTABLE: $pbi$::PrimitiveVTable<$RsType$> = |
|
|
|
static VTABLE: $pbi$::PrimitiveVTable<$RsType$> = |
|
|
|
$pbi$::PrimitiveVTable::new( |
|
|
|
$pbi$::PrimitiveVTable::new( |
|
|
@ -290,9 +291,9 @@ void GetterForViewOrMut(Context<FieldDescriptor> field, bool is_mut) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
} |
|
|
|
} |
|
|
|
}}}, |
|
|
|
}}}, |
|
|
|
R"rs( |
|
|
|
R"rs( |
|
|
|
pub fn r#$field$(&self) -> $pb$::View<'_, $RsType$> { |
|
|
|
pub fn r#$field$(&self) -> $pb$::View<'_, $RsType$> { |
|
|
|
unsafe { $getter_thunk$($self$) } |
|
|
|
unsafe { $getter_thunk$($self$) } |
|
|
|
} |
|
|
|
} |
|
|
@ -302,93 +303,89 @@ void GetterForViewOrMut(Context<FieldDescriptor> field, bool is_mut) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void AccessorsForViewOrMut(Context<Descriptor> msg, bool is_mut) { |
|
|
|
void AccessorsForViewOrMut(Context& ctx, const Descriptor& msg, bool is_mut) { |
|
|
|
for (int i = 0; i < msg.desc().field_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.field_count(); ++i) { |
|
|
|
auto field = msg.WithDesc(*msg.desc().field(i)); |
|
|
|
const FieldDescriptor& field = *msg.field(i); |
|
|
|
if (field.desc().is_repeated()) continue; |
|
|
|
if (field.is_repeated()) continue; |
|
|
|
// TODO - add cord support
|
|
|
|
// TODO - add cord support
|
|
|
|
if (field.desc().options().has_ctype()) continue; |
|
|
|
if (field.options().has_ctype()) continue; |
|
|
|
// TODO
|
|
|
|
// TODO
|
|
|
|
if (field.desc().type() == FieldDescriptor::TYPE_ENUM || |
|
|
|
if (field.type() == FieldDescriptor::TYPE_ENUM || |
|
|
|
field.desc().type() == FieldDescriptor::TYPE_GROUP) |
|
|
|
field.type() == FieldDescriptor::TYPE_GROUP) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
GetterForViewOrMut(field, is_mut); |
|
|
|
GetterForViewOrMut(ctx, field, is_mut); |
|
|
|
msg.printer().PrintRaw("\n"); |
|
|
|
ctx.printer().PrintRaw("\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
|
|
void GenerateRs(Context<Descriptor> msg) { |
|
|
|
void GenerateRs(Context& ctx, const Descriptor& msg) { |
|
|
|
if (msg.desc().map_key() != nullptr) { |
|
|
|
if (msg.map_key() != nullptr) { |
|
|
|
ABSL_LOG(WARNING) << "unsupported map field: " << msg.desc().full_name(); |
|
|
|
ABSL_LOG(WARNING) << "unsupported map field: " << msg.full_name(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
msg.Emit( |
|
|
|
ctx.Emit({{"Msg", msg.name()}, |
|
|
|
{{"Msg", msg.desc().name()}, |
|
|
|
{"Msg::new", [&] { MessageNew(ctx, msg); }}, |
|
|
|
{"Msg::new", [&] { MessageNew(msg); }}, |
|
|
|
{"Msg::serialize", [&] { MessageSerialize(ctx, msg); }}, |
|
|
|
{"Msg::serialize", [&] { MessageSerialize(msg); }}, |
|
|
|
{"Msg::deserialize", [&] { MessageDeserialize(ctx, msg); }}, |
|
|
|
{"Msg::deserialize", [&] { MessageDeserialize(msg); }}, |
|
|
|
{"Msg::drop", [&] { MessageDrop(ctx, msg); }}, |
|
|
|
{"Msg::drop", [&] { MessageDrop(msg); }}, |
|
|
|
{"Msg_externs", [&] { MessageExterns(ctx, msg); }}, |
|
|
|
{"Msg_externs", [&] { MessageExterns(msg); }}, |
|
|
|
{"accessor_fns", |
|
|
|
{"accessor_fns", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
for (int i = 0; i < msg.field_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.desc().field_count(); ++i) { |
|
|
|
auto& field = *msg.field(i); |
|
|
|
auto field = msg.WithDesc(*msg.desc().field(i)); |
|
|
|
ctx.Emit({{"comment", FieldInfoComment(ctx, field)}}, R"rs( |
|
|
|
msg.Emit({{"comment", FieldInfoComment(field)}}, R"rs( |
|
|
|
|
|
|
|
// $comment$
|
|
|
|
// $comment$
|
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
GenerateAccessorMsgImpl(field); |
|
|
|
GenerateAccessorMsgImpl(ctx, field); |
|
|
|
msg.printer().PrintRaw("\n"); |
|
|
|
ctx.printer().PrintRaw("\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
}}, |
|
|
|
}}, |
|
|
|
{"oneof_accessor_fns", |
|
|
|
{"oneof_accessor_fns", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.real_oneof_decl_count(); ++i) { |
|
|
|
GenerateOneofAccessors( |
|
|
|
GenerateOneofAccessors(ctx, *msg.real_oneof_decl(i)); |
|
|
|
msg.WithDesc(*msg.desc().real_oneof_decl(i))); |
|
|
|
ctx.printer().PrintRaw("\n"); |
|
|
|
msg.printer().PrintRaw("\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
}}, |
|
|
|
}}, |
|
|
|
{"accessor_externs", |
|
|
|
{"accessor_externs", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
for (int i = 0; i < msg.field_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.desc().field_count(); ++i) { |
|
|
|
GenerateAccessorExternC(ctx, *msg.field(i)); |
|
|
|
GenerateAccessorExternC(msg.WithDesc(*msg.desc().field(i))); |
|
|
|
ctx.printer().PrintRaw("\n"); |
|
|
|
msg.printer().PrintRaw("\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
}}, |
|
|
|
}}, |
|
|
|
{"oneof_externs", |
|
|
|
{"oneof_externs", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
for (int i = 0; i < msg.real_oneof_decl_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { |
|
|
|
GenerateOneofExternC(ctx, *msg.real_oneof_decl(i)); |
|
|
|
GenerateOneofExternC(msg.WithDesc(*msg.desc().real_oneof_decl(i))); |
|
|
|
ctx.printer().PrintRaw("\n"); |
|
|
|
msg.printer().PrintRaw("\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
}}, |
|
|
|
}}, |
|
|
|
{"nested_msgs", |
|
|
|
{"nested_msgs", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
// If we have no nested types or oneofs, bail out without
|
|
|
|
// If we have no nested types or oneofs, bail out without emitting
|
|
|
|
// emitting an empty mod SomeMsg_.
|
|
|
|
// an empty mod SomeMsg_.
|
|
|
|
if (msg.nested_type_count() == 0 && |
|
|
|
if (msg.desc().nested_type_count() == 0 && |
|
|
|
msg.real_oneof_decl_count() == 0) { |
|
|
|
msg.desc().real_oneof_decl_count() == 0) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
ctx.Emit( |
|
|
|
msg.Emit( |
|
|
|
{{"Msg", msg.name()}, |
|
|
|
{{"Msg", msg.desc().name()}, |
|
|
|
{"nested_msgs", |
|
|
|
{"nested_msgs", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
for (int i = 0; i < msg.nested_type_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.desc().nested_type_count(); ++i) { |
|
|
|
GenerateRs(ctx, *msg.nested_type(i)); |
|
|
|
auto nested_msg = msg.WithDesc(msg.desc().nested_type(i)); |
|
|
|
} |
|
|
|
GenerateRs(nested_msg); |
|
|
|
}}, |
|
|
|
} |
|
|
|
{"oneofs", |
|
|
|
}}, |
|
|
|
[&] { |
|
|
|
{"oneofs", |
|
|
|
for (int i = 0; i < msg.real_oneof_decl_count(); ++i) { |
|
|
|
[&] { |
|
|
|
GenerateOneofDefinition(ctx, *msg.real_oneof_decl(i)); |
|
|
|
for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { |
|
|
|
} |
|
|
|
GenerateOneofDefinition( |
|
|
|
}}}, |
|
|
|
msg.WithDesc(*msg.desc().real_oneof_decl(i))); |
|
|
|
R"rs( |
|
|
|
} |
|
|
|
|
|
|
|
}}}, |
|
|
|
|
|
|
|
R"rs( |
|
|
|
|
|
|
|
#[allow(non_snake_case)] |
|
|
|
#[allow(non_snake_case)] |
|
|
|
pub mod $Msg$_ { |
|
|
|
pub mod $Msg$_ { |
|
|
|
$nested_msgs$ |
|
|
|
$nested_msgs$ |
|
|
@ -396,10 +393,12 @@ void GenerateRs(Context<Descriptor> msg) { |
|
|
|
$oneofs$ |
|
|
|
$oneofs$ |
|
|
|
} // mod $Msg$_
|
|
|
|
} // mod $Msg$_
|
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
}}, |
|
|
|
}}, |
|
|
|
{"accessor_fns_for_views", [&] { AccessorsForViewOrMut(msg, false); }}, |
|
|
|
{"accessor_fns_for_views", |
|
|
|
{"accessor_fns_for_muts", [&] { AccessorsForViewOrMut(msg, true); }}}, |
|
|
|
[&] { AccessorsForViewOrMut(ctx, msg, false); }}, |
|
|
|
R"rs( |
|
|
|
{"accessor_fns_for_muts", |
|
|
|
|
|
|
|
[&] { AccessorsForViewOrMut(ctx, msg, true); }}}, |
|
|
|
|
|
|
|
R"rs( |
|
|
|
#[allow(non_camel_case_types)] |
|
|
|
#[allow(non_camel_case_types)] |
|
|
|
// TODO: Implement support for debug redaction
|
|
|
|
// TODO: Implement support for debug redaction
|
|
|
|
#[derive(Debug)] |
|
|
|
#[derive(Debug)] |
|
|
@ -542,9 +541,9 @@ void GenerateRs(Context<Descriptor> msg) { |
|
|
|
$nested_msgs$ |
|
|
|
$nested_msgs$ |
|
|
|
)rs"); |
|
|
|
)rs"); |
|
|
|
|
|
|
|
|
|
|
|
if (msg.is_cpp()) { |
|
|
|
if (ctx.is_cpp()) { |
|
|
|
msg.printer().PrintRaw("\n"); |
|
|
|
ctx.printer().PrintRaw("\n"); |
|
|
|
msg.Emit({{"Msg", msg.desc().name()}}, R"rs( |
|
|
|
ctx.Emit({{"Msg", msg.name()}}, R"rs( |
|
|
|
impl $Msg$ { |
|
|
|
impl $Msg$ { |
|
|
|
pub fn __unstable_wrap_cpp_grant_permission_to_break(msg: $pbi$::RawMessage) -> Self { |
|
|
|
pub fn __unstable_wrap_cpp_grant_permission_to_break(msg: $pbi$::RawMessage) -> Self { |
|
|
|
Self { inner: $pbr$::MessageInner { msg } } |
|
|
|
Self { inner: $pbr$::MessageInner { msg } } |
|
|
@ -558,39 +557,37 @@ void GenerateRs(Context<Descriptor> msg) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Generates code for a particular message in `.pb.thunk.cc`.
|
|
|
|
// Generates code for a particular message in `.pb.thunk.cc`.
|
|
|
|
void GenerateThunksCc(Context<Descriptor> msg) { |
|
|
|
void GenerateThunksCc(Context& ctx, const Descriptor& msg) { |
|
|
|
ABSL_CHECK(msg.is_cpp()); |
|
|
|
ABSL_CHECK(ctx.is_cpp()); |
|
|
|
if (msg.desc().map_key() != nullptr) { |
|
|
|
if (msg.map_key() != nullptr) { |
|
|
|
ABSL_LOG(WARNING) << "unsupported map field: " << msg.desc().full_name(); |
|
|
|
ABSL_LOG(WARNING) << "unsupported map field: " << msg.full_name(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
msg.Emit( |
|
|
|
ctx.Emit( |
|
|
|
{{"abi", "\"C\""}, // Workaround for syntax highlight bug in VSCode.
|
|
|
|
{{"abi", "\"C\""}, // Workaround for syntax highlight bug in VSCode.
|
|
|
|
{"Msg", msg.desc().name()}, |
|
|
|
{"Msg", msg.name()}, |
|
|
|
{"QualifiedMsg", cpp::QualifiedClassName(&msg.desc())}, |
|
|
|
{"QualifiedMsg", cpp::QualifiedClassName(&msg)}, |
|
|
|
{"new_thunk", Thunk(msg, "new")}, |
|
|
|
{"new_thunk", Thunk(ctx, msg, "new")}, |
|
|
|
{"delete_thunk", Thunk(msg, "delete")}, |
|
|
|
{"delete_thunk", Thunk(ctx, msg, "delete")}, |
|
|
|
{"serialize_thunk", Thunk(msg, "serialize")}, |
|
|
|
{"serialize_thunk", Thunk(ctx, msg, "serialize")}, |
|
|
|
{"deserialize_thunk", Thunk(msg, "deserialize")}, |
|
|
|
{"deserialize_thunk", Thunk(ctx, msg, "deserialize")}, |
|
|
|
{"nested_msg_thunks", |
|
|
|
{"nested_msg_thunks", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
for (int i = 0; i < msg.desc().nested_type_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.nested_type_count(); ++i) { |
|
|
|
Context<Descriptor> nested_msg = |
|
|
|
GenerateThunksCc(ctx, *msg.nested_type(i)); |
|
|
|
msg.WithDesc(msg.desc().nested_type(i)); |
|
|
|
|
|
|
|
GenerateThunksCc(nested_msg); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}}, |
|
|
|
}}, |
|
|
|
{"accessor_thunks", |
|
|
|
{"accessor_thunks", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
for (int i = 0; i < msg.desc().field_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.field_count(); ++i) { |
|
|
|
GenerateAccessorThunkCc(msg.WithDesc(*msg.desc().field(i))); |
|
|
|
GenerateAccessorThunkCc(ctx, *msg.field(i)); |
|
|
|
} |
|
|
|
} |
|
|
|
}}, |
|
|
|
}}, |
|
|
|
{"oneof_thunks", |
|
|
|
{"oneof_thunks", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { |
|
|
|
for (int i = 0; i < msg.real_oneof_decl_count(); ++i) { |
|
|
|
GenerateOneofThunkCc(msg.WithDesc(*msg.desc().real_oneof_decl(i))); |
|
|
|
GenerateOneofThunkCc(ctx, *msg.real_oneof_decl(i)); |
|
|
|
} |
|
|
|
} |
|
|
|
}}}, |
|
|
|
}}}, |
|
|
|
R"cc( |
|
|
|
R"cc( |
|
|
|