Rust: get all types onto a single blanket ProxiedInMapValue implementation for upb

I realized that as long as we implement `UpbTypeConversions` for enums, we can
easily get the blanket implementation for messages to work for enums as well.
Luckily the blanket implementation also happens to work for non-generated
types, so this gets us down to just one ProxiedInMapValue implementation for
upb.

PiperOrigin-RevId: 673927343
pull/18277/head
Adam Cozzette 7 months ago committed by Copybara-Service
parent ada599128c
commit 1142838bbc
  1. 104
      rust/upb.rs
  2. 108
      src/google/protobuf/compiler/rust/enum.cc

@ -9,8 +9,8 @@
use crate::__internal::{Enum, Private, SealedInternal}; use crate::__internal::{Enum, Private, SealedInternal};
use crate::{ use crate::{
IntoProxied, Map, MapIter, MapMut, MapView, Message, Mut, ProtoBytes, ProtoStr, ProtoString, IntoProxied, Map, MapIter, MapMut, MapView, Mut, ProtoBytes, ProtoStr, ProtoString, Proxied,
Proxied, ProxiedInMapValue, ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView, View, ProxiedInMapValue, ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView, View,
}; };
use core::fmt::Debug; use core::fmt::Debug;
use std::mem::{size_of, ManuallyDrop, MaybeUninit}; use std::mem::{size_of, ManuallyDrop, MaybeUninit};
@ -683,108 +683,10 @@ impl RawMapIter {
} }
} }
macro_rules! impl_ProxiedInMapValue_for_non_generated_value_types {
($key_t:ty ; $($t:ty),*) => {
$(
impl ProxiedInMapValue<$key_t> for $t {
fn map_new(_private: Private) -> Map<$key_t, Self> {
let arena = Arena::new();
let raw = unsafe {
upb_Map_New(arena.raw(),
<$key_t as UpbTypeConversions>::upb_type(),
<$t as UpbTypeConversions>::upb_type())
};
Map::from_inner(Private, InnerMap { raw, arena })
}
unsafe fn map_free(_private: Private, _map: &mut Map<$key_t, Self>) {
// No-op: the memory will be dropped by the arena.
}
fn map_clear(mut map: MapMut<$key_t, Self>) {
unsafe {
upb_Map_Clear(map.as_raw(Private));
}
}
fn map_len(map: MapView<$key_t, Self>) -> usize {
unsafe {
upb_Map_Size(map.as_raw(Private))
}
}
fn map_insert(mut map: MapMut<$key_t, Self>, key: View<'_, $key_t>, value: impl IntoProxied<Self>) -> bool {
let arena = map.raw_arena(Private);
unsafe {
upb_Map_InsertAndReturnIfInserted(
map.as_raw(Private),
<$key_t as UpbTypeConversions>::to_message_value(key),
<$t as UpbTypeConversions>::into_message_value_fuse_if_required(arena, value.into_proxied(Private)),
arena
)
}
}
fn map_get<'a>(map: MapView<'a, $key_t, Self>, key: View<'_, $key_t>) -> Option<View<'a, Self>> {
let mut val = MaybeUninit::uninit();
let found = unsafe {
upb_Map_Get(map.as_raw(Private), <$key_t as UpbTypeConversions>::to_message_value(key),
val.as_mut_ptr())
};
if !found {
return None;
}
Some(unsafe { <$t as UpbTypeConversions>::from_message_value(val.assume_init()) })
}
fn map_remove(mut map: MapMut<$key_t, Self>, key: View<'_, $key_t>) -> bool {
unsafe {
upb_Map_Delete(map.as_raw(Private),
<$key_t as UpbTypeConversions>::to_message_value(key),
ptr::null_mut())
}
}
fn map_iter(map: MapView<$key_t, Self>) -> MapIter<$key_t, Self> {
// SAFETY: View<Map<'_,..>> guarantees its RawMap outlives '_.
unsafe {
MapIter::from_raw(Private, RawMapIter::new(map.as_raw(Private)))
}
}
fn map_iter_next<'a>(
iter: &mut MapIter<'a, $key_t, Self>
) -> Option<(View<'a, $key_t>, View<'a, Self>)> {
// SAFETY: MapIter<'a, ..> guarantees its RawMapIter outlives 'a.
unsafe { iter.as_raw_mut(Private).next_unchecked() }
// SAFETY: MapIter<K, V> returns key and values message values
// with the variants for K and V active.
.map(|(k, v)| unsafe {(
<$key_t as UpbTypeConversions>::from_message_value(k),
<$t as UpbTypeConversions>::from_message_value(v),
)})
}
}
)*
}
}
macro_rules! impl_ProxiedInMapValue_for_key_types {
($($t:ty),*) => {
$(
impl_ProxiedInMapValue_for_non_generated_value_types!(
$t ; f32, f64, i32, u32, i64, u64, bool, ProtoString, ProtoBytes
);
)*
}
}
impl_ProxiedInMapValue_for_key_types!(i32, u32, i64, u64, bool, ProtoString);
impl<Key, MessageType> ProxiedInMapValue<Key> for MessageType impl<Key, MessageType> ProxiedInMapValue<Key> for MessageType
where where
Key: Proxied + UpbTypeConversions, Key: Proxied + UpbTypeConversions,
MessageType: Proxied + UpbTypeConversions + Message, MessageType: Proxied + UpbTypeConversions,
{ {
fn map_new(_private: Private) -> Map<Key, Self> { fn map_new(_private: Private) -> Map<Key, Self> {
let arena = Arena::new(); let arena = Arena::new();

@ -148,97 +148,29 @@ void EnumProxiedInMapValue(Context& ctx, const EnumDescriptor& desc) {
} }
return; return;
case Kernel::kUpb: case Kernel::kUpb:
for (const auto& t : kMapKeyTypes) { ctx.Emit(R"rs(
ctx.Emit({io::Printer::Sub("key_t", [&] { ctx.Emit(t.rs_key_t); }) impl $pbr$::UpbTypeConversions for $name$ {
.WithSuffix("")}, fn upb_type() -> $pbr$::CType {
R"rs( $pbr$::CType::Enum
impl $pb$::ProxiedInMapValue<$key_t$> for $name$ { }
fn map_new(_private: $pbi$::Private) -> $pb$::Map<$key_t$, Self> {
let arena = $pbr$::Arena::new();
let raw = unsafe {
$pbr$::upb_Map_New(
arena.raw(),
<$key_t$ as $pbr$::UpbTypeConversions>::upb_type(),
$pbr$::CType::Enum)
};
$pb$::Map::from_inner(
$pbi$::Private,
$pbr$::InnerMap::new(raw, arena))
}
unsafe fn map_free(_private: $pbi$::Private, _map: &mut $pb$::Map<$key_t$, Self>) {
// No-op: the memory will be dropped by the arena.
}
fn map_clear(mut map: $pb$::MapMut<$key_t$, Self>) {
unsafe {
$pbr$::upb_Map_Clear(map.as_raw($pbi$::Private));
}
}
fn map_len(map: $pb$::MapView<$key_t$, Self>) -> usize {
unsafe {
$pbr$::upb_Map_Size(map.as_raw($pbi$::Private))
}
}
fn map_insert(mut map: $pb$::MapMut<$key_t$, Self>, key: $pb$::View<'_, $key_t$>, value: impl $pb$::IntoProxied<Self>) -> bool {
let arena = map.inner($pbi$::Private).raw_arena();
unsafe {
$pbr$::upb_Map_InsertAndReturnIfInserted(
map.as_raw($pbi$::Private),
<$key_t$ as $pbr$::UpbTypeConversions>::to_message_value(key),
$pbr$::upb_MessageValue { int32_val: value.into_proxied($pbi$::Private).0 },
arena
)
}
}
fn map_get<'a>(map: $pb$::MapView<'a, $key_t$, Self>, key: $pb$::View<'_, $key_t$>) -> Option<$pb$::View<'a, Self>> { fn to_message_value(
let mut val = $std$::mem::MaybeUninit::uninit(); val: $pb$::View<'_, Self>) -> $pbr$::upb_MessageValue {
let found = unsafe { $pbr$::upb_MessageValue { int32_val: val.0 }
$pbr$::upb_Map_Get( }
map.as_raw($pbi$::Private),
<$key_t$ as $pbr$::UpbTypeConversions>::to_message_value(key),
val.as_mut_ptr())
};
if !found {
return None;
}
Some($name$(unsafe { val.assume_init().int32_val }))
}
fn map_remove(mut map: $pb$::MapMut<$key_t$, Self>, key: $pb$::View<'_, $key_t$>) -> bool { unsafe fn into_message_value_fuse_if_required(
let mut val = $std$::mem::MaybeUninit::uninit(); raw_parent_arena: $pbr$::RawArena,
unsafe { val: Self) -> $pbr$::upb_MessageValue {
$pbr$::upb_Map_Delete( $pbr$::upb_MessageValue { int32_val: val.0 }
map.as_raw($pbi$::Private), }
<$key_t$ as $pbr$::UpbTypeConversions>::to_message_value(key),
val.as_mut_ptr())
}
}
fn map_iter(map: $pb$::MapView<$key_t$, Self>) -> $pb$::MapIter<$key_t$, Self> {
// SAFETY: View<Map<'_,..>> guarantees its RawMap outlives '_.
unsafe {
$pb$::MapIter::from_raw($pbi$::Private, $pbr$::RawMapIter::new(map.as_raw($pbi$::Private)))
}
}
fn map_iter_next<'a>( unsafe fn from_message_value<'msg>(val: $pbr$::upb_MessageValue)
iter: &mut $pb$::MapIter<'a, $key_t$, Self> -> $pb$::View<'msg, Self> {
) -> Option<($pb$::View<'a, $key_t$>, $pb$::View<'a, Self>)> { $name$(unsafe { val.int32_val })
// SAFETY: MapIter<'a, ..> guarantees its RawMapIter outlives 'a. }
unsafe { iter.as_raw_mut($pbi$::Private).next_unchecked() } }
// SAFETY: MapIter<K, V> returns key and values message values )rs");
// with the variants for K and V active.
.map(|(k, v)| unsafe {(
<$key_t$ as $pbr$::UpbTypeConversions>::from_message_value(k),
Self(v.int32_val),
)})
}
}
)rs");
}
return; return;
} }
} }

Loading…
Cancel
Save