Move repeated fields and singular cords off of upb C accessor codegen.

PiperOrigin-RevId: 668158513
pull/17988/head
Protobuf Team Bot 6 months ago committed by Copybara-Service
parent 471ff77270
commit 807ecfd0fa
  1. 38
      rust/upb/message.rs
  2. 37
      src/google/protobuf/compiler/rust/accessors/repeated_field.cc
  3. 32
      src/google/protobuf/compiler/rust/accessors/singular_cord.cc

@ -6,7 +6,9 @@
// https://developers.google.com/open-source/licenses/bsd
use super::opaque_pointee::opaque_pointee;
use super::{upb_ExtensionRegistry, upb_MiniTable, upb_MiniTableField, RawArena, StringView};
use super::{
upb_ExtensionRegistry, upb_MiniTable, upb_MiniTableField, RawArena, RawArray, StringView,
};
use std::ptr::NonNull;
opaque_pointee!(upb_Message);
@ -120,6 +122,11 @@ extern "C" {
default_val: StringView,
) -> StringView;
/// Gets the const upb_Message* that is assigned to the field.
///
/// This may return None which must be treated the same as if it returned
/// Some of a valid RawMessage that is was the default message instance.
///
/// # Safety
/// - `m` and `f` must be valid to deref
/// - `f` must be a message-typed field associated with `m`
@ -128,6 +135,11 @@ extern "C" {
f: *const upb_MiniTableField,
) -> Option<RawMessage>;
/// Gets or creates a mutable upb_Message* assigned to the corresponding
/// field in the message.
///
/// This will only return None if the Arena allocation fails.
///
/// # Safety
/// - All arguments must be valid to deref
/// - `mini_table` must be the MiniTable associated with `m`
@ -139,6 +151,30 @@ extern "C" {
arena: RawArena,
) -> Option<RawMessage>;
/// Gets the const upb_Array* that is assigned to the field.
///
/// This may return None which must be treated the same as if it returned
/// Some of a valid RawArray that is empty.
///
/// # Safety
/// - `m` and `f` must be valid to deref
/// - `f` must be a repeated field associated with `m`
pub fn upb_Message_GetArray(m: RawMessage, f: *const upb_MiniTableField) -> Option<RawArray>;
/// Gets or creates a mutable upb_Array* assigned to the corresponding field
/// in the message.
///
/// This will only return None if the Arena allocation fails.
///
/// # Safety
/// - `m` and `f` must be valid to deref
/// - `f` must be a repeated field associated with `m`
pub fn upb_Message_GetOrCreateMutableArray(
m: RawMessage,
f: *const upb_MiniTableField,
arena: RawArena,
) -> Option<RawArray>;
/// # Safety
/// - `m` and `f` must be valid to deref
/// - `mini_table` must be the MiniTable associated with `m`

@ -7,6 +7,7 @@
#include <string>
#include "absl/log/absl_check.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/compiler/cpp/helpers.h"
#include "google/protobuf/compiler/rust/accessors/accessor_case.h"
@ -33,17 +34,19 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
{"view_self", ViewReceiver(accessor_case)},
{"getter_thunk", ThunkName(ctx, field, "get")},
{"getter_mut_thunk", ThunkName(ctx, field, "get_mut")},
{"upb_mt_field_index", UpbMiniTableFieldIndex(field)},
{"getter",
[&] {
if (ctx.is_upb()) {
ctx.Emit({}, R"rs(
pub fn $field$($view_self$) -> $pb$::RepeatedView<$view_lifetime$, $RsType$> {
unsafe {
$getter_thunk$(
self.raw_msg(),
/* optional size pointer */ std::ptr::null(),
) }
.map_or_else(
let f = $pbr$::upb_MiniTable_GetFieldByIndex(
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
$upb_mt_field_index$);
$pbr$::upb_Message_GetArray(
self.raw_msg(), f)
}.map_or_else(
$pbr$::empty_array::<$RsType$>,
|raw| unsafe {
$pb$::RepeatedView::from_raw($pbi$::Private, raw)
@ -73,15 +76,18 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
ctx.Emit({}, R"rs(
pub fn $field$_mut(&mut self) -> $pb$::RepeatedMut<'_, $RsType$> {
unsafe {
let f = $pbr$::upb_MiniTable_GetFieldByIndex(
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
$upb_mt_field_index$);
let raw_array = $pbr$::upb_Message_GetOrCreateMutableArray(
self.raw_msg(),
f,
self.arena().raw(),
).unwrap();
$pb$::RepeatedMut::from_inner(
$pbi$::Private,
$pbr$::InnerRepeatedMut::new(
$getter_mut_thunk$(
self.raw_msg(),
/* optional size pointer */ std::ptr::null(),
self.arena().raw(),
),
self.arena(),
raw_array, self.arena(),
),
)
}
@ -109,13 +115,12 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
return;
}
if (ctx.is_upb()) {
ctx.Emit({{"field_index", UpbMiniTableFieldIndex(field)}},
R"rs(
ctx.Emit(R"rs(
pub fn set_$raw_field_name$(&mut self, src: impl $pb$::IntoProxied<$pb$::Repeated<$RsType$>>) {
let minitable_field = unsafe {
$pbr$::upb_MiniTable_GetFieldByIndex(
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
$field_index$
$upb_mt_field_index$
)
};
let val = src.into_proxied($pbi$::Private);
@ -155,6 +160,8 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
void RepeatedField::InExternC(Context& ctx,
const FieldDescriptor& field) const {
if (ctx.is_upb()) return;
ctx.Emit({{"getter_thunk", ThunkName(ctx, field, "get")},
{"getter_mut_thunk", ThunkName(ctx, field, "get_mut")},
{"move_setter_thunk", ThunkName(ctx, field, "move_set")},
@ -219,6 +226,8 @@ const char* CppRepeatedContainerType(const FieldDescriptor& field) {
void RepeatedField::InThunkCc(Context& ctx,
const FieldDescriptor& field) const {
ABSL_CHECK(ctx.is_cpp());
ctx.Emit({{"field", cpp::FieldName(&field)},
{"ElementType", CppElementType(field)},
{"ContainerType", CppRepeatedContainerType(field)},

@ -7,13 +7,16 @@
#include <string>
#include "absl/log/absl_check.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/compiler/cpp/helpers.h"
#include "google/protobuf/compiler/rust/accessors/accessor_case.h"
#include "google/protobuf/compiler/rust/accessors/default_value.h"
#include "google/protobuf/compiler/rust/accessors/generator.h"
#include "google/protobuf/compiler/rust/accessors/with_presence.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"
namespace google {
@ -38,6 +41,8 @@ void SingularCord::InMsgImpl(Context& ctx, const FieldDescriptor& field,
{"setter_thunk", ThunkName(ctx, field, "set")},
{"getter_thunk", ThunkName(ctx, field, "get")},
{"proxied_type", RsTypePath(ctx, field)},
{"default_value", DefaultValue(ctx, field)},
{"upb_mt_field_index", UpbMiniTableFieldIndex(field)},
{"borrowed_type",
[&] {
if (is_string_type) {
@ -52,13 +57,13 @@ void SingularCord::InMsgImpl(Context& ctx, const FieldDescriptor& field,
ctx.Emit(R"rs(
$pb$::ProtoStringCow::Borrowed(
// SAFETY: The runtime doesn't require ProtoStr to be UTF-8.
unsafe { $pb$::ProtoStr::from_utf8_unchecked(view) }
unsafe { $pb$::ProtoStr::from_utf8_unchecked(view.as_ref()) }
)
)rs");
} else {
ctx.Emit(R"rs(
$pb$::ProtoBytesCow::Borrowed(
view
unsafe { view.as_ref() }
)
)rs");
}
@ -95,7 +100,7 @@ void SingularCord::InMsgImpl(Context& ctx, const FieldDescriptor& field,
ctx.Emit(R"rs(
let cord_is_flat = unsafe { $is_flat_thunk$(self.raw_msg()) };
if cord_is_flat {
let view = unsafe { $borrowed_getter_thunk$(self.raw_msg()).as_ref() };
let view = unsafe { $borrowed_getter_thunk$(self.raw_msg()) };
return $transform_borrowed$;
}
@ -106,7 +111,13 @@ void SingularCord::InMsgImpl(Context& ctx, const FieldDescriptor& field,
)rs");
} else {
ctx.Emit(R"rs(
let view = unsafe { $getter_thunk$(self.raw_msg()).as_ref() };
let view = unsafe {
let f = $pbr$::upb_MiniTable_GetFieldByIndex(
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
$upb_mt_field_index$);
$pbr$::upb_Message_GetString(
self.raw_msg(), f, ($default_value$).into())
};
$transform_borrowed$
)rs");
}
@ -145,10 +156,13 @@ void SingularCord::InMsgImpl(Context& ctx, const FieldDescriptor& field,
parent_arena.fuse(&arena);
unsafe {
$setter_thunk$(
let f = $pbr$::upb_MiniTable_GetFieldByIndex(
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
$upb_mt_field_index$);
$pbr$::upb_Message_SetBaseFieldString(
self.as_mutator_message_ref($pbi$::Private).msg(),
view
);
f,
view);
}
)rs");
}
@ -170,6 +184,8 @@ void SingularCord::InMsgImpl(Context& ctx, const FieldDescriptor& field,
}
void SingularCord::InExternC(Context& ctx, const FieldDescriptor& field) const {
if (ctx.is_upb()) return;
if (field.has_presence()) {
WithPresenceAccessorsInExternC(ctx, field);
}
@ -213,6 +229,8 @@ void SingularCord::InExternC(Context& ctx, const FieldDescriptor& field) const {
}
void SingularCord::InThunkCc(Context& ctx, const FieldDescriptor& field) const {
ABSL_CHECK(ctx.is_cpp());
if (field.has_presence()) {
WithPresenceAccessorsInThunkCc(ctx, field);
}

Loading…
Cancel
Save