Skip to content

Commit

Permalink
Fix message clear not updating hasbit when message/group has presence…
Browse files Browse the repository at this point in the history
…. Add more tests.

PiperOrigin-RevId: 457822583
  • Loading branch information
protobuf-github-bot authored and copybara-github committed Jun 28, 2022
1 parent da82d15 commit b6f862b
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 95 deletions.
142 changes: 62 additions & 80 deletions upb/test_generated_code.cc
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,68 @@ TEST(GeneratedCode, ScalarsProto2) {
upb_Arena_Free(arena);
}

TEST(GeneratedCode, RepeatedClear) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
size_t len = 0;
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(0, len);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 2,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 3,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 4,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(3, len);
protobuf_test_messages_proto2_TestAllTypesProto2_clear_repeated_int32(msg);
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(0, len);
upb_Arena_Free(arena);
}

TEST(GeneratedCode, Clear) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
// Test clear.
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_int32(msg, 1);
EXPECT_TRUE(
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int32(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_int32(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int32(msg));
EXPECT_FALSE(
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int32(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_int64(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int64(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_uint32(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint32(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_uint64(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint64(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_float(msg);
EXPECT_EQ(
0.0f,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_float(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_double(msg);
EXPECT_EQ(
0.0,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_double(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_bool(msg);
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_bool(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_string(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_string(msg)
.size);
upb_Arena_Free(arena);
}

TEST(GeneratedCode, Bytes) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
Expand Down Expand Up @@ -425,86 +487,6 @@ TEST(GeneratedCode, Bytes) {
upb_Arena_Free(arena);
}

TEST(GeneratedCode, Extension) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect_new(
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect* msg2;
upb_StringView serialized;

EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_has_message_set_extension(
msg));

protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2* ext =
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_new(
arena);
EXPECT_EQ(
0,
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_i(
ext));
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_set_i(
ext, 5);
EXPECT_EQ(
5,
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_i(
ext));
// Test setter/hazzer.
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_set_message_set_extension(
msg, ext, arena);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_has_message_set_extension(
msg));
// Test serialize.
serialized.data =
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect_serialize(
msg, arena, &serialized.size);
msg2 =
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect_parse(
serialized.data, serialized.size, arena);
const protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2*
ext2 =
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_message_set_extension(
msg);
EXPECT_EQ(
5,
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_i(
ext2));

// Test Clear.
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_clear_message_set_extension(
msg);
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension2_has_message_set_extension(
msg));
upb_Arena_Free(arena);
}

TEST(GeneratedCode, RepeatedClear) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
size_t len = 0;
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(0, len);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 2,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 3,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 4,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(3, len);
protobuf_test_messages_proto2_TestAllTypesProto2_clear_repeated_int32(msg);
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(0, len);
upb_Arena_Free(arena);
}

TEST(GeneratedCode, UTF8) {
const char invalid_utf8[] = "\xff";
const upb_StringView invalid_utf8_view =
Expand Down
54 changes: 39 additions & 15 deletions upbc/protoc-gen-upb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -923,13 +923,25 @@ void GenerateClear(const protobuf::FieldDescriptor* field,
field->number(), oneof_fullname, default_value);
} else {
if (field->message_type()) {
output(
R"cc(
UPB_INLINE void $0_clear_$1(const $0* msg) {
*UPB_PTR_AT(msg, $2, const upb_Message*) = NULL;
}
)cc",
msg_name, field->name(), layout.GetFieldOffset(field));
if (layout.HasHasbit(field)) {
output(
R"cc(
UPB_INLINE void $0_clear_$1(const $0* msg) {
*UPB_PTR_AT(msg, $2, const upb_Message*) = NULL;
_upb_clearhas(msg, $3);
}
)cc",
msg_name, field->name(), layout.GetFieldOffset(field),
layout.GetHasbitIndex(field));
} else {
output(
R"cc(
UPB_INLINE void $0_clear_$1(const $0* msg) {
*UPB_PTR_AT(msg, $2, const upb_Message*) = NULL;
}
)cc",
msg_name, field->name(), layout.GetFieldOffset(field));
}
} else if (layout.HasHasbit(field)) {
if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING) {
output(
Expand Down Expand Up @@ -979,13 +991,25 @@ void GenerateClear(const protobuf::FieldDescriptor* field,
void GenerateRepeatedClear(const protobuf::FieldDescriptor* field,
const FileLayout& layout, absl::string_view msg_name,
Output& output) {
output(
R"cc(
UPB_INLINE void $0_clear_$1(const $0* msg) {
_upb_array_detach(msg, $2);
}
)cc",
msg_name, field->name(), layout.GetFieldOffset(field));
if (layout.HasHasbit(field)) {
output(
R"cc(
UPB_INLINE void $0_clear_$1(const $0* msg) {
_upb_array_detach(msg, $2);
_upb_clearhas(msg, $4);
}
)cc",
msg_name, field->name(), layout.GetFieldOffset(field),
layout.GetHasbitIndex(field));
} else {
output(
R"cc(
UPB_INLINE void $0_clear_$1(const $0* msg) {
_upb_array_detach(msg, $2);
}
)cc",
msg_name, field->name(), layout.GetFieldOffset(field));
}
}

void GenerateMapGetters(const protobuf::FieldDescriptor* field,
Expand Down Expand Up @@ -1910,7 +1934,7 @@ int WriteExtensions(const FileLayout& layout, Output& output) {
return exts.size();
}

// Writes a .upb.c source file.
// Writes a .upb.cc source file.
void WriteSource(const FileLayout& layout, Output& output,
bool fasttable_enabled) {
const protobuf::FileDescriptor* file = layout.descriptor();
Expand Down

0 comments on commit b6f862b

Please sign in to comment.