Implement and use field entries for `_mut`

This is the final CL (part 4 of 4) in the ProxiedWithPresence chain.
In the past, we had returned Mut directly for the `_mut` accessors.
This was a temporary engagement in order to get the other submsg machinery checked in.

As we prep for the finalization of v0.6, we can finally conform to the rest of the `_mut` getters.
$field$_mut now correctly returns $pb$::FieldEntry<'_, $msg_type$> as a part of this.
All test callsites have been updated to `.or_default` in order to test the mutational pathway as before.

PiperOrigin-RevId: 602739186
pull/15602/head
Hong Shin 1 year ago committed by Copybara-Service
parent 531d4372f4
commit f4511fda5a
  1. 2
      rust/test/shared/accessors_test.rs
  2. 10
      rust/test/shared/simple_nested_test.rs
  3. 24
      src/google/protobuf/compiler/rust/accessors/singular_message.cc
  4. 35
      src/google/protobuf/compiler/rust/oneof.cc

@ -675,7 +675,7 @@ fn test_singular_msg_field() {
// testing reading an int inside a view // testing reading an int inside a view
assert_that!(msg_view.bb(), eq(0)); assert_that!(msg_view.bb(), eq(0));
let msg_mut: NestedMessageMut = msg.optional_nested_message_mut(); let msg_mut: NestedMessageMut = msg.optional_nested_message_mut().or_default();
// test reading an int inside a mut // test reading an int inside a mut
assert_that!(msg_mut.bb(), eq(0)); assert_that!(msg_mut.bb(), eq(0));
} }

@ -99,7 +99,7 @@ fn test_nested_muts() {
} }
let mut outer_msg = Outer::new(); let mut outer_msg = Outer::new();
let mut inner_msg: InnerMut<'_> = outer_msg.inner_mut(); let mut inner_msg: InnerMut<'_> = outer_msg.inner_mut().or_default();
assert_that!( assert_that!(
inner_msg, inner_msg,
matches_pattern!(InnerMut{ matches_pattern!(InnerMut{
@ -164,10 +164,10 @@ fn test_recursive_view() {
#[test] #[test]
fn test_recursive_mut() { fn test_recursive_mut() {
let mut rec = nested_proto::Recursive::new(); let mut rec = nested_proto::Recursive::new();
let mut one = rec.rec_mut(); let mut one = rec.rec_mut().or_default();
let mut two = one.rec_mut(); let mut two = one.rec_mut().or_default();
let mut three = two.rec_mut(); let mut three = two.rec_mut().or_default();
let mut four = three.rec_mut(); let mut four = three.rec_mut().or_default();
four.num_mut().set(1); four.num_mut().set(1);
assert_that!(four.num(), eq(1)); assert_that!(four.num(), eq(1));

@ -66,35 +66,13 @@ void SingularMessage::InMsgImpl(Context& ctx, const FieldDescriptor& field,
} }
)rs"); )rs");
}}, }},
{"getter_mut_body",
[&] {
if (ctx.is_upb()) {
ctx.Emit({}, R"rs(
let submsg = unsafe {
$getter_mut_thunk$(self.raw_msg(), self.arena().raw())
};
$msg_type$Mut::from_parent($pbi$::Private, self.as_mutator_message_ref(), submsg)
)rs");
} else {
ctx.Emit({}, R"rs(
let submsg = unsafe { $getter_mut_thunk$(self.raw_msg()) };
$msg_type$Mut::from_parent($pbi$::Private, self.as_mutator_message_ref(), submsg)
)rs");
}
}},
{"getter_mut", {"getter_mut",
[&] { [&] {
if (accessor_case == AccessorCase::VIEW) { if (accessor_case == AccessorCase::VIEW) {
return; return;
} }
ctx.Emit({}, R"rs( ctx.Emit({}, R"rs(
pub fn $field$_mut(&mut self) -> $msg_type$Mut { pub fn $field$_mut(&mut self)
$getter_mut_body$
}
//~ TODO: b/319472103 - delete $field_mut$, then rename
//~ this to $field$_mut and update all unit tests
pub fn $field$_entry(&mut self)
-> $pb$::FieldEntry<'_, $msg_type$> { -> $pb$::FieldEntry<'_, $msg_type$> {
static VTABLE: $pbr$::MessageVTable = static VTABLE: $pbr$::MessageVTable =
$pbr$::MessageVTable::new($pbi$::Private, $pbr$::MessageVTable::new($pbi$::Private,

@ -284,30 +284,23 @@ void GenerateOneofAccessors(Context& ctx, const OneofDescriptor& oneof,
ctx.Emit( ctx.Emit(
{{"case", OneofCaseRsName(field)}, {{"case", OneofCaseRsName(field)},
{"rs_mut_getter", field.name() + "_mut"}, {"rs_mut_getter", field.name() + "_mut"},
{"type", rs_type}, {"type", rs_type}},
// Any extra behavior needed to map the mut getter into the
// Any extra behavior needed to map the mut getter into the // unwrapped Mut<>. Right now Message's _mut already returns
// unwrapped Mut<>. Right now Message's _mut already returns // the Mut directly, but for scalars the accessor will return
// the Mut directly, but for scalars the accessor will return // an Optional which we then grab the mut by doing
// an Optional which we then grab the mut by doing // .try_into_mut().unwrap().
// .try_into_mut().unwrap(). //
// // Note that this unwrap() is safe because the flow is:
// Note that this unwrap() is safe because the flow is: // 1) Find out which oneof field is already set (if any)
// 1) Find out which oneof field is already set (if any) // 2) If a field is set, call the corresponding field's _mut()
// 2) If a field is set, call the corresponding field's _mut() // and wrap the result in the SomeOneofMut enum.
// and wrap the result in the SomeOneofMut enum. // The unwrap() will only ever panic if the which oneof enum
// The unwrap() will only ever panic if the which oneof enum // disagrees with the corresponding field presence which.
// disagrees with the corresponding field presence which.
// TODO: If the message _mut accessor returns
// Optional<> then this conditional behavior should be removed.
{"into_mut_transform",
field.type() == FieldDescriptor::TYPE_MESSAGE
? ""
: ".try_into_mut().unwrap()"}},
R"rs( R"rs(
$Msg$_::$case_enum_name$::$case$ => $Msg$_::$case_enum_name$::$case$ =>
$Msg$_::$mut_enum_name$::$case$( $Msg$_::$mut_enum_name$::$case$(
self.$rs_mut_getter$()$into_mut_transform$), self.$rs_mut_getter$().try_into_mut().unwrap()),
)rs"); )rs");
} }
}}, }},

Loading…
Cancel
Save