|
|
|
@ -7,11 +7,13 @@ |
|
|
|
|
|
|
|
|
|
#include <string> |
|
|
|
|
|
|
|
|
|
#include "absl/log/absl_check.h" |
|
|
|
|
#include "google/protobuf/compiler/cpp/helpers.h" |
|
|
|
|
#include "google/protobuf/compiler/rust/accessors/accessor_case.h" |
|
|
|
|
#include "google/protobuf/compiler/rust/accessors/generator.h" |
|
|
|
|
#include "google/protobuf/compiler/rust/context.h" |
|
|
|
|
#include "google/protobuf/compiler/rust/naming.h" |
|
|
|
|
#include "google/protobuf/compiler/rust/upb_helpers.h" |
|
|
|
|
#include "google/protobuf/descriptor.h" |
|
|
|
|
#include "google/protobuf/descriptor.pb.h" |
|
|
|
|
|
|
|
|
@ -41,30 +43,33 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, |
|
|
|
|
auto& value_type = *field.message_type()->map_value(); |
|
|
|
|
std::string field_name = FieldNameWithCollisionAvoidance(field); |
|
|
|
|
|
|
|
|
|
ctx.Emit({{"field", RsSafeName(field_name)}, |
|
|
|
|
{"raw_field_name", field_name}, // Never r# prefixed
|
|
|
|
|
{"Key", RsTypePath(ctx, key_type)}, |
|
|
|
|
{"Value", RsTypePath(ctx, value_type)}, |
|
|
|
|
{"view_lifetime", ViewLifetime(accessor_case)}, |
|
|
|
|
{"view_self", ViewReceiver(accessor_case)}, |
|
|
|
|
{"getter_thunk", ThunkName(ctx, field, "get")}, |
|
|
|
|
{"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}, |
|
|
|
|
{"getter", |
|
|
|
|
[&] { |
|
|
|
|
if (ctx.is_upb()) { |
|
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
|
ctx.Emit( |
|
|
|
|
{{"field", RsSafeName(field_name)}, |
|
|
|
|
{"raw_field_name", field_name}, // Never r# prefixed
|
|
|
|
|
{"Key", RsTypePath(ctx, key_type)}, |
|
|
|
|
{"Value", RsTypePath(ctx, value_type)}, |
|
|
|
|
{"view_lifetime", ViewLifetime(accessor_case)}, |
|
|
|
|
{"view_self", ViewReceiver(accessor_case)}, |
|
|
|
|
{"upb_mt_field_index", UpbMiniTableFieldIndex(field)}, |
|
|
|
|
{"getter", |
|
|
|
|
[&] { |
|
|
|
|
if (ctx.is_upb()) { |
|
|
|
|
ctx.Emit(R"rs( |
|
|
|
|
pub fn $field$($view_self$) |
|
|
|
|
-> $pb$::MapView<$view_lifetime$, $Key$, $Value$> { |
|
|
|
|
unsafe { |
|
|
|
|
$getter_thunk$(self.raw_msg()) |
|
|
|
|
let f = $pbr$::upb_MiniTable_GetFieldByIndex( |
|
|
|
|
<Self as $pbr$::AssociatedMiniTable>::mini_table(), |
|
|
|
|
$upb_mt_field_index$); |
|
|
|
|
$pbr$::upb_Message_GetMap(self.raw_msg(), f) |
|
|
|
|
.map_or_else( |
|
|
|
|
$pbr$::empty_map::<$Key$, $Value$>, |
|
|
|
|
|raw| $pb$::MapView::from_raw($pbi$::Private, raw) |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
})rs"); |
|
|
|
|
} else { |
|
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
|
} else { |
|
|
|
|
ctx.Emit({{"getter_thunk", ThunkName(ctx, field, "get")}}, R"rs( |
|
|
|
|
pub fn $field$($view_self$) |
|
|
|
|
-> $pb$::MapView<$view_lifetime$, $Key$, $Value$> { |
|
|
|
|
unsafe { |
|
|
|
@ -72,48 +77,66 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, |
|
|
|
|
$getter_thunk$(self.raw_msg())) |
|
|
|
|
} |
|
|
|
|
})rs"); |
|
|
|
|
} |
|
|
|
|
}}, |
|
|
|
|
{"getter_mut", |
|
|
|
|
[&] { |
|
|
|
|
if (accessor_case == AccessorCase::VIEW) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (ctx.is_upb()) { |
|
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
|
} |
|
|
|
|
}}, |
|
|
|
|
{"getter_mut", |
|
|
|
|
[&] { |
|
|
|
|
if (accessor_case == AccessorCase::VIEW) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (ctx.is_upb()) { |
|
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
|
pub fn $field$_mut(&mut self) |
|
|
|
|
-> $pb$::MapMut<'_, $Key$, $Value$> { |
|
|
|
|
let raw = unsafe { |
|
|
|
|
$getter_mut_thunk$(self.raw_msg(), |
|
|
|
|
self.arena().raw()) |
|
|
|
|
}; |
|
|
|
|
let inner = $pbr$::InnerMapMut::new( |
|
|
|
|
raw, self.arena()); |
|
|
|
|
unsafe { $pb$::MapMut::from_inner($pbi$::Private, inner) } |
|
|
|
|
unsafe { |
|
|
|
|
let parent_mini_table = |
|
|
|
|
<Self as $pbr$::AssociatedMiniTable>::mini_table(); |
|
|
|
|
|
|
|
|
|
let f = |
|
|
|
|
$pbr$::upb_MiniTable_GetFieldByIndex( |
|
|
|
|
parent_mini_table, |
|
|
|
|
$upb_mt_field_index$); |
|
|
|
|
|
|
|
|
|
let map_entry_mini_table = |
|
|
|
|
$pbr$::upb_MiniTable_SubMessage( |
|
|
|
|
parent_mini_table, |
|
|
|
|
f); |
|
|
|
|
|
|
|
|
|
let raw_map = |
|
|
|
|
$pbr$::upb_Message_GetOrCreateMutableMap( |
|
|
|
|
self.raw_msg(), |
|
|
|
|
map_entry_mini_table, |
|
|
|
|
f, |
|
|
|
|
self.arena().raw()).unwrap(); |
|
|
|
|
let inner = $pbr$::InnerMapMut::new( |
|
|
|
|
raw_map, self.arena()); |
|
|
|
|
$pb$::MapMut::from_inner($pbi$::Private, inner) |
|
|
|
|
} |
|
|
|
|
})rs"); |
|
|
|
|
} else { |
|
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
|
} else { |
|
|
|
|
ctx.Emit({{"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}}, |
|
|
|
|
R"rs( |
|
|
|
|
pub fn $field$_mut(&mut self) |
|
|
|
|
-> $pb$::MapMut<'_, $Key$, $Value$> { |
|
|
|
|
let inner = $pbr$::InnerMapMut::new( |
|
|
|
|
unsafe { $getter_mut_thunk$(self.raw_msg()) }); |
|
|
|
|
unsafe { $pb$::MapMut::from_inner($pbi$::Private, inner) } |
|
|
|
|
})rs"); |
|
|
|
|
} |
|
|
|
|
}}, |
|
|
|
|
{"setter", |
|
|
|
|
[&] { |
|
|
|
|
if (accessor_case == AccessorCase::VIEW) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
|
} |
|
|
|
|
}}, |
|
|
|
|
{"setter", |
|
|
|
|
[&] { |
|
|
|
|
if (accessor_case == AccessorCase::VIEW) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
ctx.Emit({}, R"rs( |
|
|
|
|
pub fn set_$raw_field_name$(&mut self, src: impl $pb$::IntoProxied<$pb$::Map<$Key$, $Value$>>) { |
|
|
|
|
// TODO: b/355493062 - Fix this extra copy.
|
|
|
|
|
self.$field$_mut().copy_from(src.into_proxied($pbi$::Private).as_view()); |
|
|
|
|
} |
|
|
|
|
)rs"); |
|
|
|
|
}}}, |
|
|
|
|
R"rs( |
|
|
|
|
}}}, |
|
|
|
|
R"rs( |
|
|
|
|
$getter$ |
|
|
|
|
$getter_mut$ |
|
|
|
|
$setter$ |
|
|
|
@ -121,6 +144,8 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Map::InExternC(Context& ctx, const FieldDescriptor& field) const { |
|
|
|
|
if (ctx.is_upb()) return; |
|
|
|
|
|
|
|
|
|
ctx.Emit( |
|
|
|
|
{ |
|
|
|
|
{"getter_thunk", ThunkName(ctx, field, "get")}, |
|
|
|
@ -148,6 +173,8 @@ void Map::InExternC(Context& ctx, const FieldDescriptor& field) const { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Map::InThunkCc(Context& ctx, const FieldDescriptor& field) const { |
|
|
|
|
ABSL_CHECK(ctx.is_cpp()); |
|
|
|
|
|
|
|
|
|
ctx.Emit({{"field", cpp::FieldName(&field)}, |
|
|
|
|
{"Key", MapElementTypeName(*field.message_type()->map_key())}, |
|
|
|
|
{"Value", MapElementTypeName(*field.message_type()->map_value())}, |
|
|
|
|