Add upb_Message_ClearOneof (and retain upb_Message_WhichOneofFieldNumber)

upb users currently need to manually fetch a oneof field in order to clear it.
In this CL, we add a convenience method to do that in one fell swoop.

PiperOrigin-RevId: 631454136
pull/16711/head
Hong Shin 10 months ago committed by Copybara-Service
parent d45016a93f
commit 6ccda4d2b5
  1. 4
      upb/message/accessors.h
  2. 24
      upb/message/accessors_test.cc
  3. 15
      upb/message/internal/accessors.h

@ -54,6 +54,10 @@ UPB_API_INLINE void upb_Message_ClearBaseField(upb_Message* msg,
UPB_API_INLINE void upb_Message_ClearExtension(upb_Message* msg,
const upb_MiniTableExtension* e);
UPB_API_INLINE void upb_Message_ClearOneof(upb_Message* msg,
const upb_MiniTable* m,
const upb_MiniTableField* f);
UPB_API_INLINE bool upb_Message_HasBaseField(const upb_Message* msg,
const upb_MiniTableField* f);

@ -478,4 +478,28 @@ TEST(GeneratedCode, EnumClosedCheck) {
upb_Arena_Free(arena);
}
TEST(GeneratedCode, OneofClear) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
const upb_MiniTable* table =
&protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init;
// oneof_uint32
const upb_MiniTableField* oneofField =
upb_MiniTable_FindFieldByNumber(table, 111);
EXPECT_TRUE(upb_MiniTableField_IsInOneof(oneofField));
protobuf_test_messages_proto2_TestAllTypesProto2_set_oneof_uint32(msg, 522);
EXPECT_TRUE(
protobuf_test_messages_proto2_TestAllTypesProto2_has_oneof_uint32(msg));
upb_Message_ClearOneof((upb_Message*)msg, table, oneofField);
EXPECT_FALSE(
protobuf_test_messages_proto2_TestAllTypesProto2_has_oneof_uint32(msg));
upb_Arena_Free(arena);
}
} // namespace

@ -693,6 +693,21 @@ UPB_API_INLINE void upb_Message_ClearExtension(
}
}
UPB_API_INLINE void upb_Message_ClearOneof(struct upb_Message* msg,
const upb_MiniTable* m,
const upb_MiniTableField* f) {
UPB_ASSERT(!upb_Message_IsFrozen(msg));
uint32_t field_number = upb_Message_WhichOneofFieldNumber(msg, f);
if (field_number == 0) {
// No field in the oneof is set.
return;
}
const upb_MiniTableField* field =
upb_MiniTable_FindFieldByNumber(m, field_number);
upb_Message_ClearBaseField(msg, field);
}
UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized(
struct upb_Message* msg, const upb_MiniTableField* f, size_t size,
upb_Arena* arena) {

Loading…
Cancel
Save