diff --git a/upb/test_generated_code.cc b/upb/test_generated_code.cc index b74b148aba..013ed634a6 100644 --- a/upb/test_generated_code.cc +++ b/upb/test_generated_code.cc @@ -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 = @@ -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 = diff --git a/upbc/protoc-gen-upb.cc b/upbc/protoc-gen-upb.cc index 61d4980357..524ebccaae 100644 --- a/upbc/protoc-gen-upb.cc +++ b/upbc/protoc-gen-upb.cc @@ -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( @@ -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, @@ -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();