From 90e1b49f0f838a3bedb0d485a7f323e468730eb7 Mon Sep 17 00:00:00 2001 From: Sandy Zhang Date: Mon, 16 Oct 2023 13:08:07 -0700 Subject: [PATCH 01/95] Use Editions features in Java, Kotlin, and Java Lite code generators. This uses C++ feature resolution. Note that JVM runtimes are not fully Editions compatible yet. PiperOrigin-RevId: 573905581 --- src/google/protobuf/compiler/java/BUILD.bazel | 15 ++++++++++- .../protobuf/compiler/java/doc_comment.cc | 3 +++ src/google/protobuf/compiler/java/file.cc | 14 ++++++++++ .../protobuf/compiler/java/generator.cc | 7 ++++- src/google/protobuf/compiler/java/generator.h | 13 +++++++++ src/google/protobuf/compiler/java/helpers.h | 21 +++++++++++---- .../compiler/java/kotlin_generator.cc | 5 +++- .../protobuf/compiler/java/kotlin_generator.h | 11 ++++++++ .../protobuf/compiler/java/message_lite.cc | 8 ++++-- .../java/message_serialization_unittest.cc | 3 ++- .../java/message_serialization_unittest.proto | 8 +++--- src/google/protobuf/compiler/java/options.h | 5 +++- .../protobuf/compiler/java/plugin_unittest.cc | 21 +++++++++++---- .../compiler/java/shared_code_generator.cc | 5 ++++ src/google/protobuf/descriptor.cc | 12 +++++++++ src/google/protobuf/descriptor_unittest.cc | 27 ++++++++++++++++++- 16 files changed, 156 insertions(+), 22 deletions(-) diff --git a/src/google/protobuf/compiler/java/BUILD.bazel b/src/google/protobuf/compiler/java/BUILD.bazel index a6e78f0094..a9461d0901 100644 --- a/src/google/protobuf/compiler/java/BUILD.bazel +++ b/src/google/protobuf/compiler/java/BUILD.bazel @@ -26,6 +26,7 @@ cc_library( "names.cc", ], hdrs = [ + "generator.h", "helpers.h", "name_resolver.h", "names.h", @@ -35,6 +36,7 @@ cc_library( include_prefix = "google/protobuf/compiler/java", visibility = ["//pkg:__pkg__"], deps = [ + ":java_features_bootstrap", "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", @@ -42,6 +44,17 @@ cc_library( ], ) +cc_library( + name = "java_features_bootstrap", + srcs = ["java_features.pb.cc"], + hdrs = ["java_features.pb.h"], + include_prefix = "google/protobuf/compiler/java", + deps = [ + "//src/google/protobuf:arena", + "//src/google/protobuf:protobuf_nowkt", + ], +) + cc_library( name = "java", srcs = [ @@ -57,7 +70,6 @@ cc_library( "file.cc", "generator.cc", "generator_factory.cc", - "java_features.pb.cc", "kotlin_generator.cc", "map_field.cc", "map_field_lite.cc", @@ -113,6 +125,7 @@ cc_library( "//src/google/protobuf/compiler:__pkg__", ], deps = [ + ":java_features_bootstrap", ":names", ":names_internal", "//src/google/protobuf:arena", diff --git a/src/google/protobuf/compiler/java/doc_comment.cc b/src/google/protobuf/compiler/java/doc_comment.cc index dce76a92a3..992cc97100 100644 --- a/src/google/protobuf/compiler/java/doc_comment.cc +++ b/src/google/protobuf/compiler/java/doc_comment.cc @@ -191,6 +191,9 @@ static std::string FirstLineOf(const std::string& value) { static void WriteDebugString(io::Printer* printer, const FieldDescriptor* field, const Options options, const bool kdoc) { std::string field_comment = FirstLineOf(field->DebugString()); + if (options.strip_nonfunctional_codegen) { + field_comment = field->name(); + } if (kdoc) { printer->Print(" * `$def$`\n", "def", EscapeKdoc(field_comment)); } else { diff --git a/src/google/protobuf/compiler/java/file.cc b/src/google/protobuf/compiler/java/file.cc index f116c1781c..5401e8257b 100644 --- a/src/google/protobuf/compiler/java/file.cc +++ b/src/google/protobuf/compiler/java/file.cc @@ -442,6 +442,13 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( FieldDescriptorSet extensions; CollectExtensions(file_proto, *file_->pool(), &extensions, file_data); + if (options_.strip_nonfunctional_codegen) { + // Skip feature extensions, which are a visible (but non-functional) + // deviation between editions and legacy syntax. + absl::erase_if(extensions, [](const FieldDescriptor* field) { + return field->containing_type()->full_name() == "google.protobuf.FeatureSet"; + }); + } if (!extensions.empty()) { // Must construct an ExtensionRegistry containing all existing extensions // and use it to parse the descriptor data again to recognize extensions. @@ -744,6 +751,13 @@ void FileGenerator::GenerateKotlinSiblings( bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor, bool immutable_api) { + // Skip feature imports, which are a visible (but non-functional) deviation + // between editions and legacy syntax. + if (options_.strip_nonfunctional_codegen && + IsKnownFeatureProto(descriptor->name())) { + return false; + } + return true; } diff --git a/src/google/protobuf/compiler/java/generator.cc b/src/google/protobuf/compiler/java/generator.cc index 4ed0029b34..aceb1207f1 100644 --- a/src/google/protobuf/compiler/java/generator.cc +++ b/src/google/protobuf/compiler/java/generator.cc @@ -14,6 +14,8 @@ #include #include +#include "google/protobuf/compiler/code_generator.h" + #include @@ -36,7 +38,8 @@ JavaGenerator::JavaGenerator() {} JavaGenerator::~JavaGenerator() {} uint64_t JavaGenerator::GetSupportedFeatures() const { - return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL | + CodeGenerator::Feature::FEATURE_SUPPORTS_EDITIONS; } bool JavaGenerator::Generate(const FileDescriptor* file, @@ -69,6 +72,8 @@ bool JavaGenerator::Generate(const FileDescriptor* file, file_options.annotate_code = true; } else if (option.first == "annotation_list_file") { file_options.annotation_list_file = option.second; + } else if (option.first == "experimental_strip_nonfunctional_codegen") { + file_options.strip_nonfunctional_codegen = true; } else { *error = absl::StrCat("Unknown generator option: ", option.first); return false; diff --git a/src/google/protobuf/compiler/java/generator.h b/src/google/protobuf/compiler/java/generator.h index 41c00998bc..549d0e5ab6 100644 --- a/src/google/protobuf/compiler/java/generator.h +++ b/src/google/protobuf/compiler/java/generator.h @@ -14,9 +14,13 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ #define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ +#include #include +#include #include "google/protobuf/compiler/code_generator.h" +#include "google/protobuf/compiler/java/java_features.pb.h" +#include "google/protobuf/descriptor.pb.h" // Must be included last. #include "google/protobuf/port_def.inc" @@ -43,10 +47,19 @@ class PROTOC_EXPORT JavaGenerator : public CodeGenerator { uint64_t GetSupportedFeatures() const override; + Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; } + Edition GetMaximumEdition() const override { return Edition::EDITION_2023; } + + std::vector GetFeatureExtensions() const override { + return {GetExtensionReflection(pb::java)}; + } + void set_opensource_runtime(bool opensource) { opensource_runtime_ = opensource; } + using CodeGenerator::GetResolvedSourceFeatures; + private: bool opensource_runtime_ = PROTO2_IS_OSS; }; diff --git a/src/google/protobuf/compiler/java/helpers.h b/src/google/protobuf/compiler/java/helpers.h index 8390b510b3..8dc75a9ed3 100644 --- a/src/google/protobuf/compiler/java/helpers.h +++ b/src/google/protobuf/compiler/java/helpers.h @@ -16,6 +16,8 @@ #include #include "absl/strings/string_view.h" +#include "google/protobuf/compiler/java/generator.h" +#include "google/protobuf/compiler/java/java_features.pb.h" #include "google/protobuf/compiler/java/names.h" #include "google/protobuf/compiler/java/options.h" #include "google/protobuf/descriptor.h" @@ -349,10 +351,12 @@ inline bool ExposePublicParser(const FileDescriptor* descriptor) { // but in the message and can be queried using additional getters that return // ints. inline bool SupportUnknownEnumValue(const FieldDescriptor* field) { - // TODO: Check Java legacy_enum_field_treated_as_closed feature. - return field->type() != FieldDescriptor::TYPE_ENUM || - FileDescriptorLegacy(field->file()).syntax() == - FileDescriptorLegacy::SYNTAX_PROTO3; + if (JavaGenerator::GetResolvedSourceFeatures(*field) + .GetExtension(pb::java) + .legacy_closed_enum()) { + return false; + } + return field->enum_type() != nullptr && !field->enum_type()->is_closed(); } // Check whether a message has repeated fields. @@ -375,7 +379,14 @@ inline bool IsWrappersProtoFile(const FileDescriptor* descriptor) { } inline bool CheckUtf8(const FieldDescriptor* descriptor) { - return descriptor->requires_utf8_validation() || + if (JavaGenerator::GetResolvedSourceFeatures(*descriptor) + .GetExtension(pb::java) + .utf8_validation() == pb::JavaFeatures::VERIFY) { + return true; + } + return JavaGenerator::GetResolvedSourceFeatures(*descriptor) + .utf8_validation() == FeatureSet::VERIFY || + // For legacy syntax. This is not allowed under Editions. descriptor->file()->options().java_string_check_utf8(); } diff --git a/src/google/protobuf/compiler/java/kotlin_generator.cc b/src/google/protobuf/compiler/java/kotlin_generator.cc index 881ef018a5..c9848b390d 100644 --- a/src/google/protobuf/compiler/java/kotlin_generator.cc +++ b/src/google/protobuf/compiler/java/kotlin_generator.cc @@ -22,7 +22,8 @@ KotlinGenerator::KotlinGenerator() {} KotlinGenerator::~KotlinGenerator() {} uint64_t KotlinGenerator::GetSupportedFeatures() const { - return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL | + CodeGenerator::Feature::FEATURE_SUPPORTS_EDITIONS; } bool KotlinGenerator::Generate(const FileDescriptor* file, @@ -54,6 +55,8 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, file_options.annotate_code = true; } else if (option.first == "annotation_list_file") { file_options.annotation_list_file = option.second; + } else if (option.first == "experimental_strip_nonfunctional_codegen") { + file_options.strip_nonfunctional_codegen = true; } else { *error = absl::StrCat("Unknown generator option: ", option.first); return false; diff --git a/src/google/protobuf/compiler/java/kotlin_generator.h b/src/google/protobuf/compiler/java/kotlin_generator.h index 8323f21baa..afc4085646 100644 --- a/src/google/protobuf/compiler/java/kotlin_generator.h +++ b/src/google/protobuf/compiler/java/kotlin_generator.h @@ -13,6 +13,8 @@ #include #include "google/protobuf/compiler/code_generator.h" +#include "google/protobuf/compiler/java/java_features.pb.h" +#include "google/protobuf/descriptor.pb.h" // Must be included last. #include "google/protobuf/port_def.inc" @@ -38,6 +40,15 @@ class PROTOC_EXPORT KotlinGenerator : public CodeGenerator { GeneratorContext* context, std::string* error) const override; uint64_t GetSupportedFeatures() const override; + + Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; } + Edition GetMaximumEdition() const override { return Edition::EDITION_2023; } + + std::vector GetFeatureExtensions() const override { + return {GetExtensionReflection(pb::java)}; + } + + using CodeGenerator::GetResolvedSourceFeatures; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/message_lite.cc b/src/google/protobuf/compiler/java/message_lite.cc index d207aa8696..587f2ccf91 100644 --- a/src/google/protobuf/compiler/java/message_lite.cc +++ b/src/google/protobuf/compiler/java/message_lite.cc @@ -487,14 +487,18 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo( int flags = 0; if (FileDescriptorLegacy(descriptor_->file()).syntax() == FileDescriptorLegacy::Syntax::SYNTAX_PROTO2) { - flags |= 0x1; + if (!context_->options().strip_nonfunctional_codegen) { + flags |= 0x1; + } } if (descriptor_->options().message_set_wire_format()) { flags |= 0x2; } if (FileDescriptorLegacy(descriptor_->file()).syntax() == FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) { - flags |= 0x4; + if (!context_->options().strip_nonfunctional_codegen) { + flags |= 0x4; + } } WriteIntToUtf16CharSequence(flags, &chars); diff --git a/src/google/protobuf/compiler/java/message_serialization_unittest.cc b/src/google/protobuf/compiler/java/message_serialization_unittest.cc index 997a2d1fb2..51d66a2efc 100644 --- a/src/google/protobuf/compiler/java/message_serialization_unittest.cc +++ b/src/google/protobuf/compiler/java/message_serialization_unittest.cc @@ -47,10 +47,11 @@ int CompileJavaProto(std::string proto_file_name) { "protoc", proto_path.c_str(), java_out.c_str(), + "--experimental_editions", proto_file_name.c_str(), }; - return cli.Run(4, argv); + return cli.Run(5, argv); } TEST(MessageSerializationTest, CollapseAdjacentExtensionRanges) { diff --git a/src/google/protobuf/compiler/java/message_serialization_unittest.proto b/src/google/protobuf/compiler/java/message_serialization_unittest.proto index e426a1b68e..acd3848f1f 100644 --- a/src/google/protobuf/compiler/java/message_serialization_unittest.proto +++ b/src/google/protobuf/compiler/java/message_serialization_unittest.proto @@ -5,7 +5,7 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd -syntax = "proto2"; +edition = "2023"; package protobuf_unittest; @@ -18,15 +18,15 @@ message TestMessageWithManyExtensionRanges { // First extension range: ends at field number 3 (exclusive) extensions 1 to 2; - optional int32 foo = 3; - optional int32 bar = 5; + int32 foo = 3; + int32 bar = 5; // Second extension range: ends at field number 13 (exclusive) extensions 6; extensions 8; extensions 10 to 12; - optional int32 baz = 23; + int32 baz = 23; // Third extension range: ends at field number 43 (exclusive) extensions 42; diff --git a/src/google/protobuf/compiler/java/options.h b/src/google/protobuf/compiler/java/options.h index af43d4f024..f10b699c68 100644 --- a/src/google/protobuf/compiler/java/options.h +++ b/src/google/protobuf/compiler/java/options.h @@ -24,7 +24,8 @@ struct Options { generate_mutable_code(false), generate_shared_code(false), enforce_lite(false), - annotate_code(false) { + annotate_code(false), + strip_nonfunctional_codegen(false) { } bool generate_immutable_code; @@ -43,6 +44,8 @@ struct Options { // Name of a file where we will write a list of generated file names, one // per line. std::string output_list_file; + // If true, strip out nonfunctional codegen. + bool strip_nonfunctional_codegen; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/plugin_unittest.cc b/src/google/protobuf/compiler/java/plugin_unittest.cc index eabe1196f0..393f94d390 100644 --- a/src/google/protobuf/compiler/java/plugin_unittest.cc +++ b/src/google/protobuf/compiler/java/plugin_unittest.cc @@ -52,6 +52,13 @@ class TestGenerator : public CodeGenerator { io::Printer printer(output.get(), '$'); printer.Print("// inserted $name$\n", "name", insertion_point); } + + uint64_t GetSupportedFeatures() const override { + return CodeGenerator::Feature::FEATURE_SUPPORTS_EDITIONS; + } + + Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; } + Edition GetMaximumEdition() const override { return Edition::EDITION_2023; } }; // This test verifies that all the expected insertion points exist. It does @@ -60,14 +67,17 @@ class TestGenerator : public CodeGenerator { TEST(JavaPluginTest, PluginTest) { ABSL_CHECK_OK( File::SetContents(absl::StrCat(TestTempDir(), "/test.proto"), - "syntax = \"proto2\";\n" + "edition = \"2023\";\n" "package foo;\n" "option java_package = \"\";\n" "option java_outer_classname = \"Test\";\n" "message Bar {\n" " message Baz {}\n" "}\n" - "enum Qux { BLAH = 1; }\n", + "enum Qux {\n" + " option features.enum_type = CLOSED;\n" + " BLAH = 1;\n" + "}\n", true)); CommandLineInterface cli; @@ -82,10 +92,11 @@ TEST(JavaPluginTest, PluginTest) { std::string java_out = absl::StrCat("--java_out=", TestTempDir()); std::string test_out = absl::StrCat("--test_out=", TestTempDir()); - const char* argv[] = {"protoc", proto_path.c_str(), java_out.c_str(), - test_out.c_str(), "test.proto"}; + const char* argv[] = { + "protoc", proto_path.c_str(), java_out.c_str(), + test_out.c_str(), "--experimental_editions", "test.proto"}; - EXPECT_EQ(0, cli.Run(5, argv)); + EXPECT_EQ(0, cli.Run(6, argv)); // Loop over the lines of the generated code and verify that we find what we // expect diff --git a/src/google/protobuf/compiler/java/shared_code_generator.cc b/src/google/protobuf/compiler/java/shared_code_generator.cc index c8c584e9b7..3def00c69b 100644 --- a/src/google/protobuf/compiler/java/shared_code_generator.cc +++ b/src/google/protobuf/compiler/java/shared_code_generator.cc @@ -113,6 +113,11 @@ void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) { // code size limits (error "code to large"). String literals are apparently // embedded raw, which is what we want. FileDescriptorProto file_proto = StripSourceRetentionOptions(*file_); + // Skip serialized file descriptor proto, which contain non-functional + // deviation between editions and legacy syntax (e.g. syntax, features) + if (options_.strip_nonfunctional_codegen) { + file_proto.Clear(); + } std::string file_data; file_proto.SerializeToString(&file_data); diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 5be4ddf37a..751c4b8bec 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -7877,10 +7877,22 @@ static bool IsStringMapType(const FieldDescriptor& field) { void DescriptorBuilder::ValidateFileFeatures(const FileDescriptor* file, const FileDescriptorProto& proto) { + // Rely on our legacy validation for proto2/proto3 files. + if (FileDescriptorLegacy(file).syntax() != + FileDescriptorLegacy::SYNTAX_EDITIONS) { + return; + } + if (file->features().field_presence() == FeatureSet::LEGACY_REQUIRED) { AddError(file->name(), proto, DescriptorPool::ErrorCollector::EDITIONS, "Required presence can't be specified by default."); } + if (file->options().java_string_check_utf8()) { + AddError( + file->name(), proto, DescriptorPool::ErrorCollector::EDITIONS, + "File option java_string_check_utf8 is not allowed under editions. Use " + "the (pb.java).utf8_validation feature to control this behavior."); + } } void DescriptorBuilder::ValidateFieldFeatures( diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 8986cf095d..88bab99985 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -9258,7 +9258,7 @@ TEST_F(FeaturesTest, FeaturesOutsideEditions) { "editions.\n"); } -TEST_F(FeaturesTest, InvalidRequiredByDefault) { +TEST_F(FeaturesTest, InvalidFileRequiredPresence) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( R"pb( @@ -9270,6 +9270,31 @@ TEST_F(FeaturesTest, InvalidRequiredByDefault) { "foo.proto: foo.proto: EDITIONS: Required presence can't be specified " "by default.\n"); } + +TEST_F(FeaturesTest, InvalidFileJavaStringCheckUtf8) { + BuildDescriptorMessagesInTestPool(); + BuildFileWithErrors( + R"pb( + name: "foo.proto" + syntax: "editions" + edition: EDITION_2023 + options { java_string_check_utf8: true } + )pb", + "foo.proto: foo.proto: EDITIONS: File option java_string_check_utf8 is " + "not allowed under editions. Use the (pb.java).utf8_validation feature " + "to control this behavior.\n"); +} + +TEST_F(FeaturesTest, Proto2FileJavaStringCheckUtf8) { + BuildDescriptorMessagesInTestPool(); + const FileDescriptor* file = BuildFile( + R"pb( + name: "foo.proto" + syntax: "proto2" + options { java_string_check_utf8: true } + )pb"); + EXPECT_EQ(file->options().java_string_check_utf8(), true); +} TEST_F(FeaturesTest, InvalidFieldPacked) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( From 4354846c51341f67f9405364f9015529acf08fbf Mon Sep 17 00:00:00 2001 From: Martijn Vels Date: Mon, 16 Oct 2023 13:53:42 -0700 Subject: [PATCH 02/95] Remove `options` from some functions we want to use externally. `Options` is a fairly heavy class and not easy to initialize, and not required for the common functions we change here allowing a lower bar for re-use. PiperOrigin-RevId: 573920014 --- .../cpp/field_generators/string_field.cc | 2 +- src/google/protobuf/compiler/cpp/file.cc | 8 +++---- src/google/protobuf/compiler/cpp/helpers.cc | 23 ++++++++++++++++--- src/google/protobuf/compiler/cpp/helpers.h | 9 +++++--- src/google/protobuf/compiler/cpp/message.cc | 12 +++++----- 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc index 748a8d6882..9c2976130c 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc @@ -596,7 +596,7 @@ void SingularString::GenerateConstructorCode(io::Printer* p) const { $field_$.InitDefault(); )cc"); - if (IsString(field_, *opts_) && EmptyDefault()) { + if (IsString(field_) && EmptyDefault()) { p->Emit(R"cc( #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING $field_$.Set("", GetArena()); diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index ec53d9d0ec..3807b96418 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -909,7 +909,7 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) { GenerateSourceIncludes(p); GenerateSourcePrelude(p); - if (IsAnyMessage(file_, options_)) { + if (IsAnyMessage(file_)) { MuteWuninitialized(p); } @@ -943,7 +943,7 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) { message_generators_[idx]->GenerateSourceInProto2Namespace(p); } - if (IsAnyMessage(file_, options_)) { + if (IsAnyMessage(file_)) { UnmuteWuninitialized(p); } @@ -989,7 +989,7 @@ void FileGenerator::GenerateSource(io::Printer* p) { GetCrossFileReferencesForFile(file_, &refs); GenerateInternalForwardDeclarations(refs, p); - if (IsAnyMessage(file_, options_)) { + if (IsAnyMessage(file_)) { MuteWuninitialized(p); } @@ -1058,7 +1058,7 @@ void FileGenerator::GenerateSource(io::Printer* p) { // @@protoc_insertion_point(global_scope) )cc"); - if (IsAnyMessage(file_, options_)) { + if (IsAnyMessage(file_)) { UnmuteWuninitialized(p); } diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc index 2c8d275114..c14e064c57 100644 --- a/src/google/protobuf/compiler/cpp/helpers.cc +++ b/src/google/protobuf/compiler/cpp/helpers.cc @@ -921,6 +921,23 @@ bool IsStringInliningEnabled(const Options& options) { return options.force_inline_string || IsProfileDriven(options); } +bool CanStringBeInlined(const FieldDescriptor* field) { + // TODO: Handle inlining for any.proto. + if (IsAnyMessage(field->containing_type())) return false; + if (field->containing_type()->options().map_entry()) return false; + if (field->is_repeated()) return false; + + // We rely on has bits to distinguish field presence for release_$name$. When + // there is no hasbit, we cannot use the address of the string instance when + // the field has been inlined. + if (!internal::cpp::HasHasbit(field)) return false; + + if (!IsString(field)) return false; + if (!field->default_value_string().empty()) return false; + + return true; +} + bool IsStringInlined(const FieldDescriptor* field, const Options& options) { (void)field; (void)options; @@ -1148,13 +1165,13 @@ bool IsStringOrMessage(const FieldDescriptor* field) { return false; } -bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options) { +bool IsAnyMessage(const FileDescriptor* descriptor) { return descriptor->name() == kAnyProtoFile; } -bool IsAnyMessage(const Descriptor* descriptor, const Options& options) { +bool IsAnyMessage(const Descriptor* descriptor) { return descriptor->name() == kAnyMessageName && - IsAnyMessage(descriptor->file(), options); + IsAnyMessage(descriptor->file()); } bool IsWellKnownMessage(const FileDescriptor* file) { diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index 9b7483537d..6e5896dc80 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -331,7 +331,7 @@ inline bool IsCord(const FieldDescriptor* field) { internal::cpp::EffectiveStringCType(field) == FieldOptions::CORD; } -inline bool IsString(const FieldDescriptor* field, const Options& options) { +inline bool IsString(const FieldDescriptor* field) { return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && internal::cpp::EffectiveStringCType(field) == FieldOptions::STRING; } @@ -355,6 +355,9 @@ float GetPresenceProbability(const FieldDescriptor* field, bool IsStringInliningEnabled(const Options& options); +// Returns true if the provided field is a singular string and can be inlined. +bool CanStringBeInlined(const FieldDescriptor* field); + // Returns true if `field` should be inlined based on PDProto profile. bool IsStringInlined(const FieldDescriptor* field, const Options& options); @@ -529,8 +532,8 @@ inline std::string MakeVarintCachedSizeFieldName(const FieldDescriptor* field, // while the two functions below use FileDescriptor::name(). In a sane world the // two approaches should be equivalent. But if you are dealing with descriptors // from untrusted sources, you might need to match semantics across libraries. -bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options); -bool IsAnyMessage(const Descriptor* descriptor, const Options& options); +bool IsAnyMessage(const FileDescriptor* descriptor); +bool IsAnyMessage(const Descriptor* descriptor); bool IsWellKnownMessage(const FileDescriptor* descriptor); diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 08fd28f69b..69c8295eff 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -299,7 +299,7 @@ bool IsCrossFileMaybeMap(const FieldDescriptor* field) { bool HasNonSplitOptionalString(const Descriptor* desc, const Options& options) { for (const auto* field : FieldRange(desc)) { - if (IsString(field, options) && !field->is_repeated() && + if (IsString(field) && !field->is_repeated() && !field->real_containing_oneof() && !ShouldSplit(field, options)) { return true; } @@ -1384,7 +1384,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { "\n", index_in_file_messages_); - if (IsAnyMessage(descriptor_, options_)) { + if (IsAnyMessage(descriptor_)) { format( "// implements Any -----------------------------------------------\n" "\n"); @@ -1870,7 +1870,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { format("::$proto_ns$::internal::WeakFieldMap _weak_field_map_;\n"); } // Generate _any_metadata_ for the Any type. - if (IsAnyMessage(descriptor_, options_)) { + if (IsAnyMessage(descriptor_)) { format("::$proto_ns$::internal::AnyMetadata _any_metadata_;\n"); } @@ -1983,7 +1983,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { return; } - if (IsAnyMessage(descriptor_, options_)) { + if (IsAnyMessage(descriptor_)) { if (HasDescriptorMethods(descriptor_->file(), options_)) { format( "bool $classname$::GetAnyFieldDescriptors(\n" @@ -2622,7 +2622,7 @@ void MessageGenerator::GenerateImplMemberInit(io::Printer* p, }; auto init_any_metadata = [&] { - if (IsAnyMessage(descriptor_, options_)) { + if (IsAnyMessage(descriptor_)) { separator(); p->Emit("_any_metadata_{&type_url_, &value_}"); } @@ -3124,7 +3124,7 @@ void MessageGenerator::GenerateCopyConstructorBodyImpl(io::Printer* p) const { decltype($weak_field_map$){from.$weak_field_map$}, )cc"); } - if (IsAnyMessage(descriptor_, options_)) { + if (IsAnyMessage(descriptor_)) { p->Emit(R"cc( /*decltype($any_metadata$)*/ { &_impl_.type_url_, From 62a435c1ab81ea65850f1b1fb58f7b3c6f498cef Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 16 Oct 2023 14:12:52 -0700 Subject: [PATCH 03/95] Fix handling of Unicode escapes in string data in textproto files. PiperOrigin-RevId: 573926175 --- .../text_format_failure_list_python.txt | 25 ------------------- .../text_format_failure_list_python_cpp.txt | 24 ------------------ .../protobuf/internal/text_format_test.py | 11 +++++--- python/google/protobuf/text_encoding.py | 11 +++++--- 4 files changed, 14 insertions(+), 57 deletions(-) diff --git a/conformance/text_format_failure_list_python.txt b/conformance/text_format_failure_list_python.txt index 6bf7c1aa63..2f7f22471c 100644 --- a/conformance/text_format_failure_list_python.txt +++ b/conformance/text_format_failure_list_python.txt @@ -3,31 +3,6 @@ # TODO: These should be fixed. Required.Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput Required.Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput - -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString -Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes -Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString -Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes -Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput diff --git a/conformance/text_format_failure_list_python_cpp.txt b/conformance/text_format_failure_list_python_cpp.txt index 91fc2ea3cd..b9da32dab8 100644 --- a/conformance/text_format_failure_list_python_cpp.txt +++ b/conformance/text_format_failure_list_python_cpp.txt @@ -1,27 +1,3 @@ -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString -Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes -Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString -Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes -Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py index 8f9d5f8862..75f3b5b35a 100644 --- a/python/google/protobuf/internal/text_format_test.py +++ b/python/google/protobuf/internal/text_format_test.py @@ -854,10 +854,11 @@ class TextFormatParserTests(TextFormatBase): # itself for string fields. It also demonstrates escaped binary data. # The ur"" string prefix is unfortunately missing from Python 3 # so we resort to double escaping our \s so that they come through. - _UNICODE_SAMPLE = u""" + _UNICODE_SAMPLE = """ optional_bytes: 'Á short desçription' optional_string: 'Á short desçription' repeated_bytes: '\\303\\201 short des\\303\\247ription' + repeated_bytes: '\\u00c1 short des\\u00e7ription' repeated_bytes: '\\x12\\x34\\x56\\x78\\x90\\xab\\xcd\\xef' repeated_string: '\\xd0\\x9f\\xd1\\x80\\xd0\\xb8\\xd0\\xb2\\xd0\\xb5\\xd1\\x82' """ @@ -873,8 +874,9 @@ class TextFormatParserTests(TextFormatBase): self.assertEqual(m.optional_bytes, self._GOLDEN_BYTES) self.assertEqual(m.optional_string, self._GOLDEN_UNICODE) self.assertEqual(m.repeated_bytes[0], self._GOLDEN_BYTES) - # repeated_bytes[1] contained simple \ escaped non-UTF-8 raw binary data. - self.assertEqual(m.repeated_bytes[1], self._GOLDEN_BYTES_1) + self.assertEqual(m.repeated_bytes[1], self._GOLDEN_BYTES) + # repeated_bytes[2] contained simple \ escaped non-UTF-8 raw binary data. + self.assertEqual(m.repeated_bytes[2], self._GOLDEN_BYTES_1) # repeated_string[0] contained \ escaped data representing the UTF-8 # representation of _GOLDEN_STR_0 - it needs to decode as such. self.assertEqual(m.repeated_string[0], self._GOLDEN_STR_0) @@ -885,8 +887,9 @@ class TextFormatParserTests(TextFormatBase): self.assertEqual(m.optional_bytes, self._GOLDEN_BYTES) self.assertEqual(m.optional_string, self._GOLDEN_UNICODE) self.assertEqual(m.repeated_bytes[0], self._GOLDEN_BYTES) + self.assertEqual(m.repeated_bytes[1], self._GOLDEN_BYTES) # repeated_bytes[1] contained simple \ escaped non-UTF-8 raw binary data. - self.assertEqual(m.repeated_bytes[1], self._GOLDEN_BYTES_1) + self.assertEqual(m.repeated_bytes[2], self._GOLDEN_BYTES_1) # repeated_string[0] contained \ escaped data representing the UTF-8 # representation of _GOLDEN_STR_0 - it needs to decode as such. self.assertEqual(m.repeated_string[0], self._GOLDEN_STR_0) diff --git a/python/google/protobuf/text_encoding.py b/python/google/protobuf/text_encoding.py index d454987496..112e4ab105 100644 --- a/python/google/protobuf/text_encoding.py +++ b/python/google/protobuf/text_encoding.py @@ -79,7 +79,10 @@ def CUnescape(text: str) -> bytes: # allow single-digit hex escapes (like '\xf'). result = _CUNESCAPE_HEX.sub(ReplaceHex, text) - return (result.encode('utf-8') # Make it bytes to allow decode. - .decode('unicode_escape') - # Make it bytes again to return the proper type. - .encode('raw_unicode_escape')) + # Replaces Unicode escape sequences with their character equivalents. + result = result.encode('raw_unicode_escape').decode('raw_unicode_escape') + # Encode Unicode characters as UTF-8, then decode to Latin-1 escaping + # unprintable characters. + result = result.encode('utf-8').decode('unicode_escape') + # Convert Latin-1 text back to a byte string (latin-1 codec also works here). + return result.encode('latin-1') From 7ed49c7af3f4ae68c4d3193e8f5a12cb99a4cb82 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Mon, 16 Oct 2023 14:28:01 -0700 Subject: [PATCH 04/95] Updating version.json to: 26-dev (#14425) Closes #14425 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/14425 from protocolbuffers:main-202310162054 7e95b7fe8ead2098d66716c2d553266899439226 PiperOrigin-RevId: 573930599 --- version.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/version.json b/version.json index 6f7526ea3d..5c98fc209d 100644 --- a/version.json +++ b/version.json @@ -1,17 +1,17 @@ { "main": { - "protoc_version": "25-dev", + "protoc_version": "26-dev", "lts": false, - "date": "2023-07-11", + "date": "2023-10-16", "languages": { - "cpp": "4.25-dev", - "csharp": "3.25-dev", - "java": "3.25-dev", - "javascript": "3.25-dev", - "objectivec": "3.25-dev", - "php": "3.25-dev", - "python": "4.25-dev", - "ruby": "3.25-dev" + "cpp": "4.26-dev", + "csharp": "3.26-dev", + "java": "3.26-dev", + "javascript": "3.26-dev", + "objectivec": "3.26-dev", + "php": "3.26-dev", + "python": "4.26-dev", + "ruby": "3.26-dev" } } } \ No newline at end of file From 961b340f54deb99968396df87542e6f31a88d4e4 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 16 Oct 2023 15:07:08 -0700 Subject: [PATCH 05/95] Remove redundant reinterpret_cast<>. PiperOrigin-RevId: 573941337 --- .../cpp/field_generators/message_field.cc | 6 +- src/google/protobuf/compiler/plugin.pb.h | 4 +- src/google/protobuf/descriptor.pb.h | 80 +++++++++---------- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc index a7c7935c9a..72fe14db0f 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc @@ -55,9 +55,9 @@ std::vector Vars(const FieldDescriptor* field, const Options& opts, ? default_ptr : absl::Substitute("reinterpret_cast($1)", base, default_ptr)}, - {"base_cast", - absl::Substitute("reinterpret_cast<$0*>", - !is_foreign && !weak ? qualified_type : base)}, + {"base_cast", !is_foreign && !weak + ? "" + : absl::Substitute("reinterpret_cast<$0*>", base)}, Sub{"weak_cast", !weak ? "" : absl::Substitute("reinterpret_cast<$0*>", base)} .ConditionalFunctionCall(), diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 3936fe2abe..90fb5f0ae3 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -1606,11 +1606,11 @@ inline void CodeGeneratorRequest::set_allocated_compiler_version(::google::proto ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::compiler::Version*>(_impl_.compiler_version_); + delete (_impl_.compiler_version_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::compiler::Version*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index dea31b5075..511109e828 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -11541,11 +11541,11 @@ inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileO ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FileOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FileOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -11637,11 +11637,11 @@ inline void FileDescriptorProto::set_allocated_source_code_info(::google::protob ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::SourceCodeInfo*>(_impl_.source_code_info_); + delete (_impl_.source_code_info_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::SourceCodeInfo*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -11893,11 +11893,11 @@ inline void DescriptorProto_ExtensionRange::set_allocated_options(::google::prot ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::ExtensionRangeOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::ExtensionRangeOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -12418,11 +12418,11 @@ inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOp ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::MessageOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::MessageOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -12996,11 +12996,11 @@ inline void ExtensionRangeOptions::set_allocated_features(::google::protobuf::Fe ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -13594,11 +13594,11 @@ inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::Fiel ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FieldOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FieldOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -13793,11 +13793,11 @@ inline void OneofDescriptorProto::set_allocated_options(::google::protobuf::Oneo ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::OneofOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::OneofOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -14073,11 +14073,11 @@ inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumO ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::EnumOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::EnumOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -14422,11 +14422,11 @@ inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf:: ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::EnumValueOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::EnumValueOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -14642,11 +14642,11 @@ inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::Se ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::ServiceOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::ServiceOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -14955,11 +14955,11 @@ inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::Met ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::MethodOptions*>(_impl_.options_); + delete (_impl_.options_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::MethodOptions*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -16102,11 +16102,11 @@ inline void FileOptions::set_allocated_features(::google::protobuf::FeatureSet* ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -16391,11 +16391,11 @@ inline void MessageOptions::set_allocated_features(::google::protobuf::FeatureSe ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -16994,11 +16994,11 @@ inline void FieldOptions::set_allocated_features(::google::protobuf::FeatureSet* ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -17143,11 +17143,11 @@ inline void OneofOptions::set_allocated_features(::google::protobuf::FeatureSet* ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -17376,11 +17376,11 @@ inline void EnumOptions::set_allocated_features(::google::protobuf::FeatureSet* ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -17553,11 +17553,11 @@ inline void EnumValueOptions::set_allocated_features(::google::protobuf::Feature ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -17730,11 +17730,11 @@ inline void ServiceOptions::set_allocated_features(::google::protobuf::FeatureSe ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -17964,11 +17964,11 @@ inline void MethodOptions::set_allocated_features(::google::protobuf::FeatureSet ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } @@ -18773,11 +18773,11 @@ inline void FeatureSetDefaults_FeatureSetEditionDefault::set_allocated_features( ::google::protobuf::Arena* message_arena = GetArena(); PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (message_arena == nullptr) { - delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.features_); + delete (_impl_.features_); } if (value != nullptr) { - ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::FeatureSet*>(value)->GetArena(); + ::google::protobuf::Arena* submessage_arena = (value)->GetArena(); if (message_arena != submessage_arena) { value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); } From d79270313bf53288ded2fa036bdbc38ecc603e9b Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Mon, 16 Oct 2023 17:44:40 -0700 Subject: [PATCH 06/95] Set `PROTOBUF_EXPORT` on `InternalOutOfLineDeleteMessageLite()` This function needs to be visible to generated code, so this CL ensures that it's exported on libprotobuf.so. PiperOrigin-RevId: 573980166 --- src/google/protobuf/repeated_ptr_field.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index d9d8d8fb4c..d38232462e 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -863,7 +863,7 @@ void RepeatedPtrFieldBase::MergeFrom( const RepeatedPtrFieldBase& from); -void InternalOutOfLineDeleteMessageLite(MessageLite* message); +PROTOBUF_EXPORT void InternalOutOfLineDeleteMessageLite(MessageLite* message); template class GenericTypeHandler { From 59d5006d6073602675c9d9f418353a566a085658 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 17 Oct 2023 05:27:33 -0700 Subject: [PATCH 07/95] feat: better debug info for PHP messages and repeated fields (#12718) addresses https://github.com/protocolbuffers/protobuf/issues/12714 by dumping more concise debug info for protobuf messages and repeated fields via the `serializeToJsonString` function. Additionally, message types which serialize into something other than an array (e.g. `Google\Protobuf\Value`, `Google\Protobuf\Timestamp`, etc) are handled in a special way to make their output consistent with other messages. ```php $m = new Google\Protobuf\DoubleValue(); $m->setValue(1.5); var_dump($m); ``` will output ``` object(Google\Protobuf\DoubleValue)#12 (1) { ["value"]=> float(1.5) } ``` Closes #12718 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/12718 from bshaffer:php-add-debuginfo c40a6f91de08a39d9f66c7c5a5463893edcbedf8 PiperOrigin-RevId: 574115431 --- php/src/Google/Protobuf/Internal/Message.php | 52 ++ .../Protobuf/Internal/RepeatedField.php | 13 + php/tests/DebugInfoTest.php | 597 ++++++++++++++++++ 3 files changed, 662 insertions(+) create mode 100644 php/tests/DebugInfoTest.php diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 578e606ec7..a427e4889f 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -2014,4 +2014,56 @@ class Message } return $size; } + + public function __debugInfo() + { + if (is_a($this, 'Google\Protobuf\FieldMask')) { + return ['paths' => $this->getPaths()->__debugInfo()]; + } + + if (is_a($this, 'Google\Protobuf\Value')) { + switch ($this->getKind()) { + case 'null_value': + return ['nullValue' => $this->getNullValue()]; + case 'number_value': + return ['numberValue' => $this->getNumberValue()]; + case 'string_value': + return ['stringValue' => $this->getStringValue()]; + case 'bool_value': + return ['boolValue' => $this->getBoolValue()]; + case 'struct_value': + return ['structValue' => $this->getStructValue()->__debugInfo()]; + case 'list_value': + return ['listValue' => $this->getListValue()->__debugInfo()]; + } + return []; + } + + if (is_a($this, 'Google\Protobuf\BoolValue') + || is_a($this, 'Google\Protobuf\BytesValue') + || is_a($this, 'Google\Protobuf\DoubleValue') + || is_a($this, 'Google\Protobuf\FloatValue') + || is_a($this, 'Google\Protobuf\StringValue') + || is_a($this, 'Google\Protobuf\Int32Value') + || is_a($this, 'Google\Protobuf\Int64Value') + || is_a($this, 'Google\Protobuf\UInt32Value') + || is_a($this, 'Google\Protobuf\UInt64Value') + ) { + return [ + 'value' => json_decode($this->serializeToJsonString(), true), + ]; + } + + if ( + is_a($this, 'Google\Protobuf\Duration') + || is_a($this, 'Google\Protobuf\Timestamp') + ) { + return [ + 'seconds' => $this->getSeconds(), + 'nanos' => $this->getNanos(), + ]; + } + + return json_decode($this->serializeToJsonString(), true); + } } diff --git a/php/src/Google/Protobuf/Internal/RepeatedField.php b/php/src/Google/Protobuf/Internal/RepeatedField.php index 8f56863fe9..3d9e66d488 100644 --- a/php/src/Google/Protobuf/Internal/RepeatedField.php +++ b/php/src/Google/Protobuf/Internal/RepeatedField.php @@ -238,4 +238,17 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable { return count($this->container); } + + public function __debugInfo() + { + return array_map( + function ($item) { + if ($item instanceof Message || $item instanceof RepeatedField) { + return $item->__debugInfo(); + } + return $item; + }, + iterator_to_array($this) + ); + } } diff --git a/php/tests/DebugInfoTest.php b/php/tests/DebugInfoTest.php new file mode 100644 index 0000000000..296f0ef1e5 --- /dev/null +++ b/php/tests/DebugInfoTest.php @@ -0,0 +1,597 @@ +markTestSkipped('__debugInfo is not supported for the protobuf extension'); + } + } + + public function testVarDumpOutput() + { + $m = new DoubleValue(); + $m->setValue(1.5); + var_dump($m); + $regex = << + float(1.5) +} +EOL; + $this->expectOutputRegex('/' . sprintf(preg_quote($regex), '\d+') . '/'); + } + + public function testTopLevelDoubleValue() + { + $m = new DoubleValue(); + $m->setValue(1.5); + $this->assertSame(['value' => 1.5], $m->__debugInfo()); + } + + public function testTopLevelFloatValue() + { + $m = new FloatValue(); + $m->setValue(1.5); + $this->assertSame(['value' => 1.5], $m->__debugInfo()); + } + + public function testTopLevelInt32Value() + { + $m = new Int32Value(); + $m->setValue(1); + $this->assertSame(['value' => 1], $m->__debugInfo()); + } + + public function testTopLevelUInt32Value() + { + $m = new UInt32Value(); + $m->setValue(1); + $this->assertSame(['value' => 1], $m->__debugInfo()); + } + + public function testTopLevelInt64Value() + { + $m = new Int64Value(); + $m->setValue(1); + $this->assertSame(['value' => '1'], $m->__debugInfo()); + } + + public function testTopLevelUInt64Value() + { + $m = new UInt64Value(); + $m->setValue(1); + $this->assertSame(['value' => '1'], $m->__debugInfo()); + } + + public function testTopLevelStringValue() + { + $m = new StringValue(); + $m->setValue("a"); + $this->assertSame(['value' => 'a'], $m->__debugInfo()); + } + + public function testTopLevelBoolValue() + { + $m = new BoolValue(); + $m->setValue(true); + $this->assertSame(['value' => true], $m->__debugInfo()); + } + + public function testTopLevelBytesValue() + { + $m = new BytesValue(); + $m->setValue("a"); + $this->assertSame(['value' => 'YQ=='], $m->__debugInfo()); + } + + public function testTopLevelLongBytesValue() + { + $m = new BytesValue(); + $data = $this->generateRandomString(12007); + $m->setValue($data); + $expected = base64_encode($data); + $this->assertSame(['value' => $expected], $m->__debugInfo()); + } + + public function testJsonEncodeNullSubMessage() + { + $from = new TestMessage(); + $from->setOptionalMessage(null); + $data = $from->__debugInfo(); + $this->assertEquals([], $data); + } + + public function testDuration() + { + $m = new Google\Protobuf\Duration(); + $m->setSeconds(1234); + $m->setNanos(999999999); + $this->assertEquals([ + 'seconds' => 1234, + 'nanos' => 999999999, + ], $m->__debugInfo()); + } + + public function testTimestamp() + { + $m = new Google\Protobuf\Timestamp(); + $m->setSeconds(946684800); + $m->setNanos(123456789); + $this->assertEquals([ + 'seconds' => 946684800, + 'nanos' => 123456789, + ], $m->__debugInfo()); + } + + public function testTopLevelValue() + { + $m = new Value(); + $m->setStringValue("a"); + $this->assertSame(['stringValue' => 'a'], $m->__debugInfo()); + + $m = new Value(); + $m->setNumberValue(1.5); + $this->assertSame(['numberValue' => 1.5], $m->__debugInfo()); + + $m = new Value(); + $m->setBoolValue(true); + $this->assertSame(['boolValue' => true], $m->__debugInfo()); + + $m = new Value(); + $m->setNullValue(\Google\Protobuf\NullValue::NULL_VALUE); + $this->assertSame(['nullValue' => 0], $m->__debugInfo()); + + $m = new Value(); + $struct = new Struct(); + $map = $struct->getFields(); + $sub = new Value(); + $sub->setNumberValue(1.5); + $map["a"] = $sub; + $m->setStructValue($struct); + $this->assertSame(['structValue' => ['a' => 1.5]], $m->__debugInfo()); + + $m = new Value(); + $list = new ListValue(); + $arr = $list->getValues(); + $sub = new Value(); + $sub->setNumberValue(1.5); + $arr[] = $sub; + $m->setListValue($list); + $this->assertSame(['listValue' => [1.5]], $m->__debugInfo()); + } + + public function testTopLevelListValue() + { + $m = new ListValue(); + $arr = $m->getValues(); + $sub = new Value(); + $sub->setNumberValue(1.5); + $arr[] = $sub; + $this->assertSame([1.5], $m->__debugInfo()); + } + + public function testEmptyListValue() + { + $m = new Struct(); + $m->setFields(['test' => (new Value())->setListValue(new ListValue())]); + $this->assertSame(['test' => []], $m->__debugInfo()); + } + + public function testTopLevelStruct() + { + $m = new Struct(); + $map = $m->getFields(); + $sub = new Value(); + $sub->setNumberValue(1.5); + $map["a"] = $sub; + $this->assertSame(['a' => 1.5], $m->__debugInfo()); + } + + public function testEmptyStruct() + { + $m = new Struct(); + $m->setFields(['test' => (new Value())->setStructValue(new Struct())]); + $this->assertSame(['test' => []], $m->__debugInfo()); + } + + public function testEmptyValue() + { + $m = new Value(); + $this->assertSame([], $m->__debugInfo()); + } + + public function testTopLevelAny() + { + // Test a normal message. + $packed = new TestMessage(); + $packed->setOptionalInt32(123); + $packed->setOptionalString("abc"); + + $m = new Any(); + $m->pack($packed); + $expected = [ + '@type' => 'type.googleapis.com/foo.TestMessage', + 'optionalInt32' => 123, + 'optionalString' => 'abc', + ]; + $result = $m->__debugInfo(); + $this->assertSame($expected, $result); + + // Test a well known message. + $packed = new Int32Value(); + $packed->setValue(123); + + $m = new Any(); + $m->pack($packed); + $this->assertSame([ + '@type' => 'type.googleapis.com/google.protobuf.Int32Value', + 'value' => 123 + ], $m->__debugInfo()); + + // Test an Any message. + $outer = new Any(); + $outer->pack($m); + $this->assertSame([ + '@type' => 'type.googleapis.com/google.protobuf.Any', + 'value' => [ + '@type' => 'type.googleapis.com/google.protobuf.Int32Value', + 'value' => 123 + ], + ], $outer->__debugInfo()); + + // Test a Timestamp message. + $packed = new Google\Protobuf\Timestamp(); + $packed->setSeconds(946684800); + $packed->setNanos(123456789); + $m = new Any(); + $m->pack($packed); + $this->assertSame([ + '@type' => 'type.googleapis.com/google.protobuf.Timestamp', + 'value' => '2000-01-01T00:00:00.123456789Z', + ], $m->__debugInfo()); + } + + public function testAnyWithDefaultWrapperMessagePacked() + { + $any = new Any(); + $any->pack(new TestInt32Value([ + 'field' => new Int32Value(['value' => 0]), + ])); + $this->assertSame( + ['@type' => 'type.googleapis.com/foo.TestInt32Value', 'field' => 0], + $any->__debugInfo() + ); + } + + public function testTopLevelFieldMask() + { + $m = new FieldMask(); + $m->setPaths(["foo.bar_baz", "qux"]); + $this->assertSame(['paths' => ['foo.bar_baz', 'qux']], $m->__debugInfo()); + } + + public function testEmptyAnySerialization() + { + $m = new EmptyAnySerialization(); + + $any = new Any(); + $any->pack($m); + + $data = $any->__debugInfo(); + $this->assertEquals(['@type' => 'type.googleapis.com/foo.EmptyAnySerialization'], $data); + } + + public function testRepeatedStringValue() + { + $m = new TestStringValue(); + $r = [new StringValue(['value' => 'a'])]; + $m->setRepeatedField($r); + $this->assertSame(['repeatedField' => ['a']], $m->__debugInfo()); + } + + public function testMapStringValue() + { + $m = new TestStringValue(); + $m->mergeFromJsonString("{\"map_field\":{\"1\": \"a\"}}"); + $this->assertSame(['mapField' => [1 => 'a']], $m->__debugInfo()); + } + + public function testNestedAny() + { + // Make sure packed message has been created at least once. + $m = new TestAny(); + $m->mergeFromJsonString( + "{\"any\":{\"optionalInt32\": 1, " . + "\"@type\":\"type.googleapis.com/foo.TestMessage\", " . + "\"optionalInt64\": 2}}"); + $this->assertSame([ + 'any' => [ + '@type' => 'type.googleapis.com/foo.TestMessage', + 'optionalInt32' => 1, + 'optionalInt64' => '2', + ] + ], $m->__debugInfo()); + } + + public function testEnum() + { + $m = new TestMessage(); + $m->setOneofEnum(TestEnum::ZERO); + $this->assertSame(['oneofEnum' => 'ZERO'], $m->__debugInfo()); + } + + public function testTopLevelRepeatedField() + { + $r1 = new RepeatedField(GPBType::class); + $r1[] = 'a'; + $this->assertSame(['a'], $r1->__debugInfo()); + + $r2 = new RepeatedField(TestMessage::class); + $r2[] = new TestMessage(['optional_int32' => -42]); + $r2[] = new TestMessage(['optional_int64' => 43]); + $this->assertSame([ + ['optionalInt32' => -42], + ['optionalInt64' => '43'], + ], $r2->__debugInfo()); + + $r3 = new RepeatedField(RepeatedField::class); + $r3[] = $r1; + $r3[] = $r2; + + $this->assertSame([ + ['a'], + [ + ['optionalInt32' => -42], + ['optionalInt64' => '43'], + ], + ], $r3->__debugInfo()); + } + + public function testEverything() + { + $m = new TestMessage([ + 'optional_int32' => -42, + 'optional_int64' => -43, + 'optional_uint32' => 42, + 'optional_uint64' => 43, + 'optional_sint32' => -44, + 'optional_sint64' => -45, + 'optional_fixed32' => 46, + 'optional_fixed64' => 47, + 'optional_sfixed32' => -46, + 'optional_sfixed64' => -47, + 'optional_float' => 1.5, + 'optional_double' => 1.6, + 'optional_bool' => true, + 'optional_string' => 'a', + 'optional_bytes' => 'bbbb', + 'optional_enum' => TestEnum::ONE, + 'optional_message' => new Sub([ + 'a' => 33 + ]), + 'repeated_int32' => [-42, -52], + 'repeated_int64' => [-43, -53], + 'repeated_uint32' => [42, 52], + 'repeated_uint64' => [43, 53], + 'repeated_sint32' => [-44, -54], + 'repeated_sint64' => [-45, -55], + 'repeated_fixed32' => [46, 56], + 'repeated_fixed64' => [47, 57], + 'repeated_sfixed32' => [-46, -56], + 'repeated_sfixed64' => [-47, -57], + 'repeated_float' => [1.5, 2.5], + 'repeated_double' => [1.6, 2.6], + 'repeated_bool' => [true, false], + 'repeated_string' => ['a', 'c'], + 'repeated_bytes' => ['bbbb', 'dddd'], + 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE], + 'repeated_message' => [new Sub(['a' => 34]), + new Sub(['a' => 35])], + 'map_int32_int32' => [-62 => -62], + 'map_int64_int64' => [-63 => -63], + 'map_uint32_uint32' => [62 => 62], + 'map_uint64_uint64' => [63 => 63], + 'map_sint32_sint32' => [-64 => -64], + 'map_sint64_sint64' => [-65 => -65], + 'map_fixed32_fixed32' => [66 => 66], + 'map_fixed64_fixed64' => [67 => 67], + 'map_sfixed32_sfixed32' => [-68 => -68], + 'map_sfixed64_sfixed64' => [-69 => -69], + 'map_int32_float' => [1 => 3.5], + 'map_int32_double' => [1 => 3.6], + 'map_bool_bool' => [true => true], + 'map_string_string' => ['e' => 'e'], + 'map_int32_bytes' => [1 => 'ffff'], + 'map_int32_enum' => [1 => TestEnum::ONE], + 'map_int32_message' => [1 => new Sub(['a' => 36])], + ]); + + $this->assertSame([ + 'optionalInt32' => -42, + 'optionalInt64' => '-43', + 'optionalUint32' => 42, + 'optionalUint64' => '43', + 'optionalSint32' => -44, + 'optionalSint64' => '-45', + 'optionalFixed32' => 46, + 'optionalFixed64' => '47', + 'optionalSfixed32' => -46, + 'optionalSfixed64' => '-47', + 'optionalFloat' => 1.5, + 'optionalDouble' => 1.6, + 'optionalBool' => true, + 'optionalString' => 'a', + 'optionalBytes' => 'YmJiYg==', + 'optionalEnum' => 'ONE', + 'optionalMessage' => [ + 'a' => 33, + ], + 'repeatedInt32' => [ + -42, + -52, + ], + 'repeatedInt64' => [ + '-43', + '-53', + ], + 'repeatedUint32' => [ + 42, + 52, + ], + 'repeatedUint64' => [ + '43', + '53', + ], + 'repeatedSint32' => [ + -44, + -54, + ], + 'repeatedSint64' => [ + '-45', + '-55', + ], + 'repeatedFixed32' => [ + 46, + 56, + ], + 'repeatedFixed64' => [ + '47', + '57', + ], + 'repeatedSfixed32' => [ + -46, + -56, + ], + 'repeatedSfixed64' => [ + '-47', + '-57', + ], + 'repeatedFloat' => [ + 1.5, + 2.5, + ], + 'repeatedDouble' => [ + 1.6, + 2.6, + ], + 'repeatedBool' => [ + true, + false, + ], + 'repeatedString' => [ + 'a', + 'c', + ], + 'repeatedBytes' => [ + 'YmJiYg==', + 'ZGRkZA==', + ], + 'repeatedEnum' => [ + 'ZERO', + 'ONE', + ], + 'repeatedMessage' => [ + [ + 'a' => 34, + ], + [ + 'a' => 35, + ], + ], + 'mapInt32Int32' => [ + -62 => -62, + ], + 'mapInt64Int64' => [ + -63 => '-63', + ], + 'mapUint32Uint32' => [ + 62 => 62, + ], + 'mapUint64Uint64' => [ + 63 => '63', + ], + 'mapSint32Sint32' => [ + -64 => -64, + ], + 'mapSint64Sint64' => [ + -65 => '-65', + ], + 'mapFixed32Fixed32' => [ + 66 => 66, + ], + 'mapFixed64Fixed64' => [ + 67 => '67', + ], + 'mapSfixed32Sfixed32' => [ + -68 => -68, + ], + 'mapSfixed64Sfixed64' => [ + -69 => '-69', + ], + 'mapInt32Float' => [ + 1 => 3.5, + ], + 'mapInt32Double' => [ + 1 => 3.6, + ], + 'mapBoolBool' => [ + 'true' => true, + ], + 'mapStringString' => [ + 'e' => 'e', + ], + 'mapInt32Bytes' => [ + 1 => 'ZmZmZg==', + ], + 'mapInt32Enum' => [ + 1 => 'ONE', + ], + 'mapInt32Message' => [ + 1 => ['a' => 36], + ], + ], $m->__debugInfo()); + } + + private function generateRandomString($length = 10) + { + $randomString = str_repeat("+", $length); + for ($i = 0; $i < $length; $i++) { + $randomString[$i] = chr(rand(0, 255)); + } + return $randomString; + } +} From 3688d8cb4acb46625793cdbf9f534ef57d6a129e Mon Sep 17 00:00:00 2001 From: Martijn Vels Date: Tue, 17 Oct 2023 08:40:41 -0700 Subject: [PATCH 08/95] Remove PROTOBUF_EXPLICIT_CONSTRUCTORS define The switch from aggregate initialization to explicit constructors in `Impl_` has been enabled since 09/06, and no issues have been reported or found. This change removes the back-out option and code from the various sources for aggregate initialization. PiperOrigin-RevId: 574161896 --- .../cpp/field_generators/cord_field.cc | 14 - .../cpp/field_generators/enum_field.cc | 6 - .../cpp/field_generators/map_field.cc | 5 - .../cpp/field_generators/message_field.cc | 27 +- .../cpp/field_generators/primitive_field.cc | 6 - .../cpp/field_generators/string_field.cc | 13 - src/google/protobuf/compiler/cpp/file.cc | 2 - src/google/protobuf/compiler/cpp/message.cc | 363 +----------------- src/google/protobuf/compiler/cpp/message.h | 2 - src/google/protobuf/message_lite.h | 2 - src/google/protobuf/port_def.inc | 8 - 11 files changed, 3 insertions(+), 445 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc b/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc index 88e2afacaf..62cbbae303 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc @@ -65,9 +65,6 @@ class CordFieldGenerator : public FieldGeneratorBase { void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override; -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - void GenerateDestructorCode(io::Printer* printer) const override; -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS void GenerateArenaDestructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; @@ -244,17 +241,6 @@ void CordFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { } } -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS -void CordFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { - Formatter format(printer, variables_); - if (should_split()) { - // A cord field in the `Split` struct is automatically destroyed when the - // split pointer is deleted and should not be explicitly destroyed here. - return; - } - format("$field$.~Cord();\n"); -} -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS void CordFieldGenerator::GenerateArenaDestructorCode( io::Printer* printer) const { diff --git a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc index d9613e7edb..51a20ce5d0 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc @@ -281,12 +281,6 @@ class RepeatedEnum : public FieldGeneratorBase { p->Emit(R"cc( $field_$.DeleteIfNotDefault(); )cc"); - } else { -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - p->Emit(R"cc( - _internal_mutable_$name$()->~RepeatedField(); - )cc"); -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS } } diff --git a/src/google/protobuf/compiler/cpp/field_generators/map_field.cc b/src/google/protobuf/compiler/cpp/field_generators/map_field.cc index 69a07727e1..13bcd63fe0 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/map_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/map_field.cc @@ -159,11 +159,6 @@ class Map : public FieldGeneratorBase { )cc"); return; } -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - p->Emit(R"cc( - $field_$.~$MapField$(); - )cc"); -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS } void GeneratePrivateMembers(io::Printer* p) const override; diff --git a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc index 72fe14db0f..34c7733eac 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc @@ -14,6 +14,7 @@ #include #include +#include "absl/log/absl_check.h" #include "absl/memory/memory.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" @@ -444,26 +445,6 @@ void SingularMessage::GenerateDestructorCode(io::Printer* p) const { using internal::cpp::HasHasbit; -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - -void SingularMessage::GenerateCopyConstructorCode(io::Printer* p) const { - if (has_hasbit_) { - p->Emit(R"cc( - if ((from.$has_hasbit$) != 0) { - _this->$field_$ = new $Submsg$(*from.$field_$); - } - )cc"); - } else { - p->Emit(R"cc( - if (from._internal_has_$name$()) { - _this->$field_$ = new $Submsg$(*from.$field_$); - } - )cc"); - } -} - -#else // !PROTOBUF_EXPLICIT_CONSTRUCTORS - void SingularMessage::GenerateCopyConstructorCode(io::Printer* p) const { if (has_hasbit_) { p->Emit(R"cc( @@ -480,8 +461,6 @@ void SingularMessage::GenerateCopyConstructorCode(io::Printer* p) const { } } -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS - void SingularMessage::GenerateSerializeWithCachedSizesToArray( io::Printer* p) const { if (!is_group()) { @@ -941,10 +920,6 @@ void RepeatedMessage::GenerateDestructorCode(io::Printer* p) const { p->Emit(R"cc( $field_$.DeleteIfNotDefault(); )cc"); - } else { -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - p->Emit("$field_$.~$Weak$RepeatedPtrField();\n"); -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS } } diff --git a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc index f96d35511d..f58b9b3eeb 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc @@ -329,12 +329,6 @@ class RepeatedPrimitive final : public FieldGeneratorBase { p->Emit(R"cc( $field_$.DeleteIfNotDefault(); )cc"); - } else { -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - p->Emit(R"cc( - $field_$.~RepeatedField(); - )cc"); -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS } } diff --git a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc index 9c2976130c..426833da15 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc @@ -643,14 +643,7 @@ void SingularString::GenerateCopyConstructorCode(io::Printer* p) const { void SingularString::GenerateDestructorCode(io::Printer* p) const { if (is_inlined()) { -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - // Explicitly calls ~InlinedStringField as its automatic call is disabled. - // Destructor has been implicitly skipped as a union. ABSL_DCHECK(!should_split()); - p->Emit(R"cc( - $field_$.~InlinedStringField(); - )cc"); -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS return; } @@ -774,12 +767,6 @@ class RepeatedString : public FieldGeneratorBase { p->Emit(R"cc( $field_$.DeleteIfNotDefault(); )cc"); - } else { -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - p->Emit(R"cc( - _internal_mutable_$name$()->~RepeatedPtrField(); - )cc"); -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS } } diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index 3807b96418..a47b7cb37f 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -1406,7 +1406,6 @@ class FileGenerator::ForwardDeclarations { template <> $dllexport_decl $$class$* Arena::CreateMaybeMessage<$class$>(Arena*); )cc"); -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS if (!IsMapEntryMessage(c.second)) { p->Emit({{"class", QualifiedClassName(c.second, options)}}, R"cc( template <> @@ -1414,7 +1413,6 @@ class FileGenerator::ForwardDeclarations { Arena*, const $class$&); )cc"); } -#endif // PROTOBUF_EXPLICIT_CONSTRUCTORS } } } diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 69c8295eff..829361e72c 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -1280,12 +1281,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { "explicit PROTOBUF_CONSTEXPR " "$classname$(::$proto_ns$::internal::ConstantInitialized);\n" "\n" -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS "inline $classname$(const $classname$& from)\n" " : $classname$(nullptr, from) {}\n" -#else // PROTOBUF_EXPLICIT_CONSTRUCTORS - "$classname$(const $classname$& from);\n" -#endif // PROTOBUF_EXPLICIT_CONSTRUCTORS "$classname$($classname$&& from) noexcept\n" " : $classname$() {\n" " *this = ::std::move(from);\n" @@ -1578,15 +1575,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { // we rely on. "protected:\n" "explicit $classname$(::$proto_ns$::Arena* arena);\n" -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS "$classname$(::$proto_ns$::Arena* arena, const $classname$& from);\n" -#else // PROTOBUF_EXPLICIT_CONSTRUCTORS - "inline $classname$(::$proto_ns$::Arena* arena," - " const $classname$& from)\n" - " : $classname$(arena) {\n" - " MergeFrom(from);\n" - "}\n" -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS ); switch (NeedsArenaDestructor()) { @@ -1750,14 +1739,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { // alignment. // (3) members assumed to align to 4 bytes. -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS format("struct $dllexport_decl $Impl_ {\n"); -#else - format("struct Impl_ {\n"); -#endif format.Indent(); -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS // TODO: check if/when there is a need for an outline dtor. format(R"cc( inline explicit constexpr Impl_( @@ -1767,7 +1751,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { inline explicit Impl_($pbi$::InternalVisibility visibility, ::$proto_ns$::Arena* arena, const Impl_& from); )cc"); -#endif // PROTOBUF_EXPLICIT_CONSTRUCTORS // Members assumed to align to 8 bytes: @@ -2272,169 +2255,6 @@ std::pair MessageGenerator::GenerateOffsets(io::Printer* p) { return std::make_pair(entries, offsets); } -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - -void MessageGenerator::GenerateSharedConstructorCode(io::Printer* p) { - if (HasSimpleBaseClass(descriptor_, options_)) return; - - p->Emit( - { - {"impl_init", - [&] { - // Note: any fields without move/copy constructors can't be - // explicitly aggregate initialized pre-C++17. - if (descriptor_->extension_range_count() > 0) { - p->Emit(R"cc( - /*decltype($extensions$)*/ {::_pbi::ArenaInitialized(), arena}, - )cc"); - } - if (!inlined_string_indices_.empty()) { - p->Emit(R"cc( - decltype($inlined_string_donated_array$){}, - )cc"); - } - bool need_to_emit_cached_size = - !HasSimpleBaseClass(descriptor_, options_); - if (!has_bit_indices_.empty()) { - p->Emit(R"cc( - decltype($has_bits$){}, - )cc"); - if (need_to_emit_cached_size) { - p->Emit(R"cc( - /*decltype($cached_size$)*/ {}, - )cc"); - need_to_emit_cached_size = false; - } - } - - // Initialize member variables with arena constructor. - for (const auto* field : optimized_order_) { - if (ShouldSplit(field, options_)) { - continue; - } - field_generators_.get(field).GenerateAggregateInitializer(p); - } - if (ShouldSplit(descriptor_, options_)) { - // We can't assign the default split to this->split without the - // const_cast because the former is a const. The const_cast is - // safe because we don't intend to modify the default split - // through this pointer, and we also expect the default split to - // be in the rodata section which is protected from mutation. - p->Emit( - {{"instance", DefaultInstanceName(descriptor_, options_, - /*split=*/true)}}, - R"cc( - decltype($split$){const_cast( - reinterpret_cast(&$instance$))}, - )cc"); - } - for (const auto* oneof : OneOfRange(descriptor_)) { - p->Emit({{"name", oneof->name()}}, - R"cc( - decltype(_impl_.$name$_){}, - )cc"); - } - - if (need_to_emit_cached_size) { - p->Emit(R"cc( - /*decltype($cached_size$)*/ {}, - )cc"); - } - - if (descriptor_->real_oneof_decl_count() != 0) { - p->Emit(R"cc( - /*decltype($oneof_case$)*/ {}, - )cc"); - } - if (num_weak_fields_ > 0) { - p->Emit(R"cc( - decltype($weak_field_map$){arena}, - )cc"); - } - if (IsAnyMessage(descriptor_, options_)) { - // AnyMetadata has no move constructor. - p->Emit(R"cc( - /*decltype($any_metadata$)*/ {&_impl_.type_url_, - &_impl_.value_}, - )cc"); - } - }}, - {"inlined_strings_init", - [&] { - if (inlined_string_indices_.empty()) return; - // Donate inline string fields. - // The last bit is the tracking bit for registering ArenaDtor. The - // bit is 1 means ArenaDtor is not registered on construction, and - // on demand register is needed. - p->Emit( - { - {"mask", - NeedsArenaDestructor() == ArenaDtorNeeds::kOnDemand - ? "~0u" - : "0xFFFFFFFEu"}, - {"init_body", - [&] { - for (size_t i = 1; i < InlinedStringDonatedSize(); - ++i) { - p->Emit({{"i", i}}, - R"cc( - $inlined_string_donated_array$[$i$] = ~0u; - )cc"); - } - }}, - }, - R"cc( - if (arena != nullptr) { - $inlined_string_donated_array$[0] = $mask$; - $init_body$; - } - )cc"); - }}, - {"field_ctor_code", - [&] { - for (const FieldDescriptor* field : optimized_order_) { - if (ShouldSplit(field, options_)) { - continue; - } - field_generators_.get(field).GenerateConstructorCode(p); - } - }}, - {"force_allocation", - [&] { - if (!ShouldForceAllocationOnConstruction(descriptor_, options_)) - return; - p->Emit(R"cc( - //~ force alignment -#ifdef PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION - $mutable_unknown_fields$; -#endif // PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION - )cc"); - }}, - {"clear_oneofs", - [&] { - for (auto oneof : OneOfRange(descriptor_)) { - p->Emit({{"name", oneof->name()}}, - R"cc( - clear_has_$name$(); - )cc"); - } - }}, - }, - R"cc( - inline void $classname$::SharedCtor(::_pb::Arena* arena) { - (void)arena; - new (&_impl_) Impl_{ - $impl_init$, - }; - $inlined_strings_init$; - $field_ctor_code$; - $force_allocation$; - $clear_oneofs$; - } - )cc"); -} - -#else // !PROTOBUF_EXPLICIT_CONSTRUCTORS void MessageGenerator::GenerateZeroInitFields(io::Printer* p) const { using Iterator = decltype(optimized_order_.begin()); @@ -2661,8 +2481,6 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* p) { )cc"); } -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS - void MessageGenerator::GenerateInitDefaultSplitInstance(io::Printer* p) { if (!ShouldSplit(descriptor_, options_)) return; @@ -2688,15 +2506,6 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* p) { }; p->Emit( { - {"extensions_dtor", - [&] { -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - if (descriptor_->extension_range_count() == 0) return; - p->Emit(R"cc( - $extensions$.~ExtensionSet(); - )cc"); -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS - }}, {"field_dtors", [&] { emit_field_dtors(/* split_fields= */ false); }}, {"split_field_dtors", [&] { @@ -2733,31 +2542,15 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* p) { $weak_field_map$.ClearAll(); )cc"); }}, - {"any_metadata_dtor", - [&] { -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - if (!IsAnyMessage(descriptor_, options_)) return; - p->Emit(R"cc( - $any_metadata$.~AnyMetadata(); - )cc"); -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS - }}, - {"impl_dtor", - [&] { -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS - p->Emit("_impl_.~Impl_();\n"); -#endif // PROTOBUF_EXPLICIT_CONSTRUCTORS - }}, + {"impl_dtor", [&] { p->Emit("_impl_.~Impl_();\n"); }}, }, R"cc( inline void $classname$::SharedDtor() { $DCHK$(GetArena() == nullptr); - $extensions_dtor$; $field_dtors$; $split_field_dtors$; $oneof_field_dtors$; $weak_fields_dtor$; - $any_metadata_dtor$; $impl_dtor$; } )cc"); @@ -2855,91 +2648,6 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) { return; } -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - - bool need_to_emit_cached_size = !HasSimpleBaseClass(descriptor_, options_); - p->Emit( - { - {"init_body", - [&] { - p->Emit("\n"); - auto indent = p->WithIndent(); - - if (descriptor_->extension_range_count() > 0) { - p->Emit(R"cc( - /*decltype($extensions$)*/ {}, - )cc"); - } - if (!inlined_string_indices_.empty()) { - p->Emit(R"cc( - /*decltype($inlined_string_donated_array$)*/ {}, - )cc"); - } - if (!has_bit_indices_.empty()) { - p->Emit(R"cc( - /*decltype($has_bits$)*/ {}, - )cc"); - if (need_to_emit_cached_size) { - p->Emit(R"cc( - /*decltype($cached_size$)*/ {}, - )cc"); - need_to_emit_cached_size = false; - } - } - for (auto* field : optimized_order_) { - if (ShouldSplit(field, options_)) { - continue; - } - field_generators_.get(field) - .GenerateConstexprAggregateInitializer(p); - } - if (ShouldSplit(descriptor_, options_)) { - p->Emit({{"name", DefaultInstanceName(descriptor_, options_, - /*split=*/true)}}, - R"cc( - /*decltype($split$)*/ const_cast( - &$name$._instance), - )cc"); - } - for (auto* oneof : OneOfRange(descriptor_)) { - p->Emit({{"name", oneof->name()}}, - R"cc( - /*decltype(_impl_.$name$_)*/ {}, - )cc"); - } - if (need_to_emit_cached_size) { - p->Emit(R"cc( - /*decltype($cached_size$)*/ {}, - )cc"); - } - if (descriptor_->real_oneof_decl_count() != 0) { - p->Emit(R"cc( - /*decltype($oneof_case$)*/ {}, - )cc"); - } - if (num_weak_fields_) { - p->Emit(R"cc( - /*decltype($weak_field_map$)*/ {}, - )cc"); - } - if (IsAnyMessage(descriptor_, options_)) { - p->Emit(R"cc( - /*decltype($any_metadata$)*/ {&_impl_.type_url_, - &_impl_.value_}, - )cc"); - } - }}, - }, - R"cc( - //~ Templatize constexpr constructor as a workaround for a bug in gcc 12 - //~ (warning in gcc 13). - template - $constexpr$ $classname$::$classname$(::_pbi::ConstantInitialized) - : _impl_{$init_body$} {} - )cc"); - -#else // !PROTOBUF_EXPLICIT_CONSTRUCTORS - // Generate Impl_::Imp_(::_pbi::ConstantInitialized); // We use separate p->Emit() calls for LF and #ifdefs as they result in // awkward layout and more awkward indenting of the function statement. @@ -2959,8 +2667,6 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) { $constexpr$ $classname$::$classname$(::_pbi::ConstantInitialized) : _impl_(::_pbi::ConstantInitialized()) {} )cc"); - -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS } void MessageGenerator::GenerateCopyConstructorBody(io::Printer* p) const { @@ -3177,8 +2883,6 @@ void MessageGenerator::GenerateCopyConstructorBodyOneofs(io::Printer* p) const { } } -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS - void MessageGenerator::GenerateCopyInitFields(io::Printer* p) const { auto begin = optimized_order_.begin(); auto end = optimized_order_.end(); @@ -3412,8 +3116,6 @@ void MessageGenerator::GenerateArenaEnabledCopyConstructor(io::Printer* p) { )cc"); } -#endif // PROTOBUF_EXPLICIT_CONSTRUCTORS - void MessageGenerator::GenerateStructors(io::Printer* p) { p->Emit( { @@ -3440,57 +3142,6 @@ void MessageGenerator::GenerateStructors(io::Printer* p) { )cc"); // Generate the copy constructor. -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS - if (UsingImplicitWeakFields(descriptor_->file(), options_)) { - // If we are in lite mode and using implicit weak fields, we generate a - // one-liner copy constructor that delegates to MergeFrom. This saves some - // code size and also cuts down on the complexity of implicit weak fields. - // We might eventually want to do this for all lite protos. - p->Emit(R"cc( - $classname$::$classname$(const $classname$& from) : $classname$() { - MergeFrom(from); - } - )cc"); - } else if (ImplHasCopyCtor()) { - p->Emit(R"cc( - $classname$::$classname$(const $classname$& from) - : $superclass$(), _impl_(from._impl_) { - _internal_metadata_.MergeFrom<$unknown_fields_type$>( - from._internal_metadata_); - // @@protoc_insertion_point(copy_constructor:$full_name$) - } - )cc"); - } else { - p->Emit( - { - {"copy_impl", [&] { GenerateCopyConstructorBodyImpl(p); }}, - {"copy_extensions", - [&] { - if (descriptor_->extension_range_count() == 0) return; - p->Emit(R"cc( - $extensions$.MergeFrom(internal_default_instance(), - from.$extensions$); - )cc"); - }}, - {"copy_body", [&] { GenerateCopyConstructorBody(p); }}, - {"copy_oneofs", [&] { GenerateCopyConstructorBodyOneofs(p); }}, - }, - R"cc( - $classname$::$classname$(const $classname$& from) : $superclass$() { - $classname$* const _this = this; - (void)_this; - $copy_impl$; - _internal_metadata_.MergeFrom<$unknown_fields_type$>( - from._internal_metadata_); - $copy_extensions$; - $copy_body$; - $copy_oneofs$; - - // @@protoc_insertion_point(copy_constructor:$full_name$) - } - )cc"); - } -#else // !PROTOBUF_EXPLICIT_CONSTRUCTORS if (UsingImplicitWeakFields(descriptor_->file(), options_)) { // If we are in lite mode and using implicit weak fields, we generate a // one-liner copy constructor that delegates to MergeFrom. This saves some @@ -3516,7 +3167,6 @@ void MessageGenerator::GenerateStructors(io::Printer* p) { } else { GenerateArenaEnabledCopyConstructor(p); } -#endif // !PROTOBUF_EXPLICIT_CONSTRUCTORS // Generate the shared constructor code. GenerateSharedConstructorCode(p); @@ -3554,7 +3204,6 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* p) { Formatter format(p); if (ShouldGenerateExternSpecializations(options_) && ShouldGenerateClass(descriptor_, options_)) { -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS format(R"cc( template <> PROTOBUF_NOINLINE $classtype$* Arena::CreateMaybeMessage<$classtype$>( @@ -3577,14 +3226,6 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* p) { } )cc"); } -#else // PROTOBUF_EXPLICIT_CONSTRUCTORS - format( - "template<> " - "PROTOBUF_NOINLINE $classtype$*\n" - "Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" - " return Arena::CreateMessageInternal< $classtype$ >(arena);\n" - "}\n"); -#endif // PROTOBUF_EXPLICIT_CONSTRUCTORS } } diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index 820a954c12..894650f829 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -89,14 +89,12 @@ class MessageGenerator { // Generate constructors and destructor. void GenerateStructors(io::Printer* p); -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS void GenerateZeroInitFields(io::Printer* p) const; void GenerateCopyInitFields(io::Printer* p) const; void GenerateImplMemberInit(io::Printer* p, InitType init_type); void GenerateArenaEnabledCopyConstructor(io::Printer* p); -#endif // PROTOBUF_EXPLICIT_CONSTRUCTORS // The compiler typically generates multiple copies of each constructor and // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index de8bd19aa0..60bc923e02 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -505,12 +505,10 @@ class PROTOBUF_EXPORT MessageLite { return Arena::CreateMaybeMessage(arena); } -#ifdef PROTOBUF_EXPLICIT_CONSTRUCTORS template static T* CreateMaybeMessage(Arena* arena, const T& from) { return Arena::CreateMaybeMessage(arena, from); } -#endif // PROTOBUF_EXPLICIT_CONSTRUCTORS inline explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {} diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index f131670a30..063f60be15 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -572,14 +572,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #error PROTOBUF_FORCE_COPY_DEFAULT_STRING was previously defined #endif -// Set (and leave set) PROTOBUF_EXPLICIT_CONSTRUCTORS -// This flag changes the internal implementation class and its uses from using -// aggregate initialization to using explicit constructor based initialization. -// TODO: remove this flag and make the code permanent. -#ifndef PROTOBUF_EXPLICIT_CONSTRUCTORS -#define PROTOBUF_EXPLICIT_CONSTRUCTORS -#endif - #ifdef PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION #error PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION was previously defined #endif From 3fa2b2041952289c93636202fff7888249798c8e Mon Sep 17 00:00:00 2001 From: Matt Kulukundis Date: Tue, 17 Oct 2023 09:07:52 -0700 Subject: [PATCH 09/95] Bump minimum PHP to 8.0 Fixes #14436 PiperOrigin-RevId: 574168872 --- php/ext/google/protobuf/template_package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/ext/google/protobuf/template_package.xml b/php/ext/google/protobuf/template_package.xml index f8d6e66f6f..766a0b0d3e 100644 --- a/php/ext/google/protobuf/template_package.xml +++ b/php/ext/google/protobuf/template_package.xml @@ -30,7 +30,7 @@ - 7.0.0 + 8.0.0 1.4.0 From 48ebb9b0bb55c0effab41c1914436819cf4590c0 Mon Sep 17 00:00:00 2001 From: xiaolou86 Date: Tue, 17 Oct 2023 10:21:10 -0700 Subject: [PATCH 10/95] Fix typos (#14409) Closes #14409 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/14409 from xiaolou86:main 52126750f0530d810bae7759044cccf0ec775fae PiperOrigin-RevId: 574190850 --- bazel/BUILD | 2 +- protos_generator/tests/test_generated.cc | 2 +- rust/utf8.rs | 2 +- src/google/protobuf/compiler/cpp/file.cc | 2 +- src/google/protobuf/unknown_field_set_unittest.cc | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bazel/BUILD b/bazel/BUILD index b08bf4ecd2..a891d615a2 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -21,7 +21,7 @@ py_binary( ) # py_proto_library() is private rule, only intended for internal use by upb. -# Hopefully py_proto_library() will eventually be availble in rules_proto or +# Hopefully py_proto_library() will eventually be available in rules_proto or # another upstream package. bzl_library( name = "py_proto_library_bzl", diff --git a/protos_generator/tests/test_generated.cc b/protos_generator/tests/test_generated.cc index 1206b6a998..121251b6a7 100644 --- a/protos_generator/tests/test_generated.cc +++ b/protos_generator/tests/test_generated.cc @@ -114,7 +114,7 @@ TEST(CppGeneratedCode, ScalarInt32) { // Test int32 defaults. EXPECT_EQ(testModel.value(), 0); EXPECT_FALSE(testModel.has_value()); - // Floating point defautls. + // Floating point defaults. EXPECT_EQ(std::numeric_limits::infinity(), testModel.float_value_with_default()); EXPECT_EQ(-std::numeric_limits::infinity(), diff --git a/rust/utf8.rs b/rust/utf8.rs index 05f4c499e3..56a1c20b93 100644 --- a/rust/utf8.rs +++ b/rust/utf8.rs @@ -241,7 +241,7 @@ impl<'a> Iterator for Utf8Chunks<'a> { /// # Safety /// `index` must be in-bounds for `x` unsafe fn split_at_unchecked(x: &[u8], index: usize) -> (&[u8], &[u8]) { - // SAFTEY: in-bounds as promised by the caller + // SAFETY: in-bounds as promised by the caller unsafe { (x.get_unchecked(..index), x.get_unchecked(index..)) } } diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index a47b7cb37f..416afb0fab 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -100,7 +100,7 @@ void UnmuteWuninitialized(io::Printer* p) { // in cases where we may declare proto B as a member of proto A using an object, // instead of a pointer. // -// The proto dependencey graph can have cycles. So instead of directly working +// The proto dependency graph can have cycles. So instead of directly working // with protos, we compute strong connected components (SCCs) composed of protos // with mutual dependence. The dependency graph on SCCs is a directed acyclic // graph (DAG) and therefore a topological order can be computed for it i.e. an diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc index ff1ed9ee07..dcd20e5ad6 100644 --- a/src/google/protobuf/unknown_field_set_unittest.cc +++ b/src/google/protobuf/unknown_field_set_unittest.cc @@ -614,15 +614,15 @@ TEST_F(UnknownFieldSetTest, DeleteSubrange) { void CheckDeleteByNumber(const std::vector& field_numbers, int deleted_number, - const std::vector& expected_field_nubmers) { + const std::vector& expected_field_numbers) { UnknownFieldSet unknown_fields; for (int i = 0; i < field_numbers.size(); ++i) { unknown_fields.AddFixed32(field_numbers[i], i); } unknown_fields.DeleteByNumber(deleted_number); - ASSERT_EQ(expected_field_nubmers.size(), unknown_fields.field_count()); - for (int i = 0; i < expected_field_nubmers.size(); ++i) { - EXPECT_EQ(expected_field_nubmers[i], unknown_fields.field(i).number()); + ASSERT_EQ(expected_field_numbers.size(), unknown_fields.field_count()); + for (int i = 0; i < expected_field_numbers.size(); ++i) { + EXPECT_EQ(expected_field_numbers[i], unknown_fields.field(i).number()); } } From c458944280145b814b75603eb0b2baa417736ac9 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 17 Oct 2023 11:01:20 -0700 Subject: [PATCH 11/95] Adds "Minimum Required Edition" to the GitHub code repository. PiperOrigin-RevId: 574204805 --- docs/design/editions/README.md | 1 + .../editions/minimum-required-edition.md | 139 ++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 docs/design/editions/minimum-required-edition.md diff --git a/docs/design/editions/README.md b/docs/design/editions/README.md index 9443fb033b..3172a99627 100644 --- a/docs/design/editions/README.md +++ b/docs/design/editions/README.md @@ -24,6 +24,7 @@ The following topics are in this repository: * [Protobuf Editions Design: Features](protobuf-editions-design-features.md) * [Editions: Life of a Featureset](editions-life-of-a-featureset.md) * [Edition Zero Features](edition-zero-features.md) +* [Minimum Required Edition](minimum-required-edition.md) * [Protobuf Editions for Schema Producers](protobuf-editions-for-schema-producers.md) * [Stricter Schemas with Editions](stricter-schemas-with-editions.md) * [Edition Zero: JSON Handling](edition-zero-json-handling.md) diff --git a/docs/design/editions/minimum-required-edition.md b/docs/design/editions/minimum-required-edition.md new file mode 100644 index 0000000000..fd61ea1966 --- /dev/null +++ b/docs/design/editions/minimum-required-edition.md @@ -0,0 +1,139 @@ +# Minimum Required Edition + +**Author:** [@mcy](https://github.com/mcy) + +**Approved:** 2022-11-15 + +A versioning mechanism for descriptors that ensures old runtimes do not load +descriptors that are "too new." + +## Background + +Suppose we decide to add a novel definition like + +``` +const int32 MY_CONSTANT = 42; +``` + +to the Protobuf language. This would entail a descriptor change to track the +values of constants, but they would not be loaded properly by older runtimes. +This document describes an addition to `descriptor.proto` that prevents this +version mismatch issue. + +[Protobuf Editions](what-are-protobuf-editions.md) intends to add the concept of +an edition to Protobuf, which will be an approximately-annually incrementing +value. Because of their annual nature, and because runtimes need to be updated +to handle new features they implement regardless, we can use them as a poison +pill for old runtimes that try to load descriptors that are "too new." + +## Overview + +We propose adding a new field to `FileDescriptorProto`: + +``` +optional string minimum_required_edition = ...; +``` + +This field would exist alongside the `edition` field, and would have the +following semantics: + +Every Protobuf runtime implementation must specify the newest edition whose +constructs it can handle (at a particular rev of that implementation). If that +edition is less than `minimum_required_edition`, loading the descriptor must +fail. + +"Less than" is defined per the edition total order given in +[Life of an Edition](life-of-an-edition.md). To restate it, it is the following +algorithm: + +``` +def edition_less_than(a, b): + parts_a = a.split(".") + parts_b = b.split(".") + for i in range(0, min(len(parts_a), len(parts_b))): + if int(parts_a[i]) < int(parts_b[i]): return True + return len(a) < len(b) +``` + +`protoc` should keep track of which constructions require which minimum edition. +For example, if constants are introduced in edition 2025, but they are not +present in a file, `protoc` should not require that runtimes understand +constants by picking a lower edition, like 2023 (assuming no other construct +requires a higher edition). + +In particular, the following changes should keep the minimum edition constant, +with all other things unchanged: + +* An upgrade of the proto compiler. +* Upgrading the specified edition of a file via Prototiller. + +### Bootstrapping Concerns + +"Epochs for `descriptor.proto`" (not available externally) describes a potential +issue with bootstrapping. It is not the case here: minimum edition is only +incremented once a particular file uses a new feature. Since `descriptor.proto` +and other schemas used by `protoc` and the backends would not use new features +immediately, introducing a new feature does not immediately stop the compiler +from being able to compile itself. + +### Concerns for Schema Producers + +Schema producers should consider changes to their schemas that increase the +minimum required edition to be breaking changes, since it will stop compiled +descriptors from being loaded at runtime. + +## Recommendation + +We recommend adding the aforementioned minimum required edition field, along +with the semantics it entails. This logic should be implemented entirely in the +protoc frontend. + +## Alternatives + +### Use a Non-Editions Version Number + +Rather than using the editions value, use some other version number. This number +would be incremented rarely (3-5 year horizon). This is the approach proposed +in "Epochs for `descriptor.proto`." + +#### Pros + +* Does not re-use the editions value for a semantically-different meaning; the + edition remains being "just" a key into a table of features defaults. + +#### Cons + +* Introduces another version number to Protobuf that increments at its own + cadence. +* Could potentially be confused with the edition value, even though they serve + distinct purposes. + +### Minimum Required Edition Should Not Be Minimal + +The proto compiler should not guarantee that the minimum required edition is as +small as it could possibly be. + +#### Pros + +* Reduces implementation burden. + +#### Cons + +* This introduces situations where an upgrade of the proto compiler, or an + innocuous change to a schema, can lead the the minimum required edition + being incremented. This is a problem for schema producers. + +### Do Nothing + +#### Pros + +* Reduces churn in runtimes, since they do not need to implement new handling + for new *editions* (as contrasted to just *features)* regularly. +* Avoids a situation where old software cannot load new descriptors at + runtime. + +#### Cons + +* Commits us to never changing the descriptor wire format in + backwards-incompatible ways, which has far-reaching effects on evolution. + These consequences are discussed in "Epochs for `descriptor.proto`." From cbef12f8cf99d13bf4684273b16554d517d809f0 Mon Sep 17 00:00:00 2001 From: Matt Kulukundis Date: Tue, 17 Oct 2023 11:17:41 -0700 Subject: [PATCH 12/95] Update test matrix to 8.0 PiperOrigin-RevId: 574210079 --- .github/workflows/test_php_ext.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_php_ext.yml b/.github/workflows/test_php_ext.yml index ec65715119..e80afa0865 100644 --- a/.github/workflows/test_php_ext.yml +++ b/.github/workflows/test_php_ext.yml @@ -41,7 +41,7 @@ jobs: strategy: fail-fast: false # Don't cancel all jobs if one fails. matrix: - version: ["7.4", "8.1", "8.2"] + version: ["8.0", "8.1", "8.2"] name: Build ${{ matrix.version }} runs-on: ubuntu-latest steps: From 8489d8d461d2792f721cdeb99eecdae23ba9ab20 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 17 Oct 2023 13:29:25 -0700 Subject: [PATCH 13/95] Adds "Legacy Syntax Editions" to the GitHub code repository. PiperOrigin-RevId: 574248480 --- docs/design/editions/README.md | 1 + .../design/editions/legacy-syntax-editions.md | 144 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 docs/design/editions/legacy-syntax-editions.md diff --git a/docs/design/editions/README.md b/docs/design/editions/README.md index 3172a99627..483ce860c0 100644 --- a/docs/design/editions/README.md +++ b/docs/design/editions/README.md @@ -35,3 +35,4 @@ The following topics are in this repository: * [Edition Evolution](edition-evolution.md) * [Edition Naming](edition-naming.md) * [Editions Feature Visibility](editions-feature-visibility.md) +* [Legacy Syntax Editions](legacy-syntax-editions.md) diff --git a/docs/design/editions/legacy-syntax-editions.md b/docs/design/editions/legacy-syntax-editions.md new file mode 100644 index 0000000000..4afcb4569e --- /dev/null +++ b/docs/design/editions/legacy-syntax-editions.md @@ -0,0 +1,144 @@ +# Legacy Syntax Editions + +**Author:** [@mkruskal-google](https://github.com/mkruskal-google) + +**Approved:** 2023-09-08 + +Should proto2/proto3 be treated as editions? + +## Background + +[Edition Zero Features](edition-zero-features.md) lays out our plan for edition +2023, which will unify proto2 and proto3. Since early in the design process, +we've discussed the possibility of making proto2 and proto3 "special" editions, +but never laid out what exactly it would look like or determined if it was +necessary. + +We recently redesigned editions to be represented as enums +([Edition Naming](edition-naming.md)), and also how edition defaults are +propagated to generators and runtimes +([Editions: Life of a FeatureSet](editions-life-of-a-featureset.md)). With these +changes, there could be an opportunity to special-case proto2 and proto3 in a +beneficial way. + +## Problem Description + +While the original plan was to keep editions and syntax orthogonal, that naively +means we'd be supporting two very different codebases. This has some serious +maintenance costs though, especially when it comes to test coverage. We could +expect to have sub-optimal test coverage of editions initially, which would +gradually become poor coverage of syntax later. Since we need to support both +syntax and editions long-term, this isn't ideal. + +In the implementation of editions in C++, we decided to unify a lot of the +infrastructure to avoid this issue. We define global feature sets for proto2 and +proto3, and try to use those internally instead of checking syntax directly. By +pushing the syntax/editions branch earlier in the stack, it gives us a lot of +indirect test coverage for editions much earlier. + +A separate issue is how Prototiller will support the conversion of syntax to +edition 2023. For features it knows about, we can hardcode defaults into the +transforms. However, third party feature owners will have no way of signaling +what the old proto2/proto3 behavior was, so Prototiller won't be able to provide +any transformations by default. They'd need to provide custom Prototiller +transforms hardcoding all of their features. + +## Recommended Solution + +We recommend adding two new special editions to our current set: + +``` +enum Edition { + EDITION_UNKNOWN = 0; + EDITION_PROTO2 = 998; + EDITION_PROTO3 = 999; + EDITION_2023 = 1000; +} +``` + +These will be treated the same as any other edition, except in our parser which +will reject `edition = "proto2"` and `edition = "proto3"` in proto files. The +real benefit here is that this allows features to specify what their +proto2/proto3 defaults are, making it easier for Prototiller to handle +migration. It also allows generators and runtimes to unify their internals more +completely, treating proto2/proto3 files exactly the same as editions. + +### Serialized Descriptors + +As we now know, there are a lot of serialized `descriptor.proto` descriptor sets +out there that need to continue working for O(months). In order to avoid +blocking edition zero for that long, we may need fallbacks in protoc for the +case where feature resolution *fails*. If the file is proto2/proto3, failure +should result in a fallback to the existing hardcoded defaults. We can remove +these later once we're willing to break stale `descriptor.proto` snapshots that +predate the changes in this doc. + +### Bootstrapping + +In order to get feature resolution running in proto2 and proto3, we need to be +able to support bootstrapped protos. For these builds, we can't use any +reflection without deadlocking, which means feature defaults can't be compiled +during runtime. We would have had to solve this problem anyway when it came time +to migrate these protos to editions, but this proposal forces our hand early. +Luckily, "Editions: Life of a FeatureSet" already set us up for this scenario, +and we have Blaze rules for embedding these defaults into code. For C++ +specifically, this will need to be checked in alongside the other bootstrapped +protos. Other languages will be able to do this more dynamically via genrules. + +### Feature Inference + +While we can calculate defaults using the same logic as in editions, actually +inferring "features" from proto2/proto3 needs some custom code. For example: + +* The `required` keyword sets `LEGACY_REQUIRED` feature +* The `optional` keyword in proto3 sets `EXPLICIT` presence +* The `group` keyword implies `DELIMITED` encoding +* The `enforce_utf8` options flips between `PACKED` and `EXPANDED` encoding + +This logic needs to be written in code, and will need to be duplicated in every +language we support. Any language-specific feature transformations will also +need to be included in that language. To make this as portable as possible, we +will define functions like: + +Each type of descriptor will have its own set of transformations that should be +applied to its features for legacy editions. + +#### Pros + +* Makes it clearer that proto2/proto3 are "like" editions + +* Gives Prototiller a little more information in the transformation from + proto2/proto3 to editions (not necessarily 2023) + +* Allows proto2/proto3 defaults to be specified in a single location + +* Makes unification of syntax/edition code easier to implement in runtimes + +* Allows cross-language proto2/proto3 testing with the conformance framework + mentioned in "Editions: Life of a FeatureSet" + +#### Cons + +* Adds special-case legacy editions, which may be somewhat confusing + +* We will need to port feature inference logic across all languages. This is + arguably cheaper than maintaining branched proto2/proto3 code in all + languages though + +## Considered Alternatives + +### Do Nothing + +If we do nothing, there will be no built-in unification of syntax and editions. +Runtimes could choose any point to split the logic. + +#### Pros + +* Requires no changes to editions code + +#### Cons + +* Likely results in lower test coverage +* May hide issues until we start rolling out edition 2023 +* Prototiller would have to hard-code proto2/proto3 defaults of features it + knows, and couldn't even try to migrate runtimes it doesn't From e1bb7d65a842b3e9521bc2ad79d34a70cde2352f Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 17 Oct 2023 14:15:37 -0700 Subject: [PATCH 14/95] Implement rust repeated scalars for cpp and upb PiperOrigin-RevId: 574261929 --- Cargo.bazel.lock | 65 ++++++- Cargo.lock | 8 +- WORKSPACE | 3 + rust/BUILD | 9 +- rust/cpp.rs | 137 +++++++++++++- rust/cpp_kernel/BUILD | 3 +- rust/cpp_kernel/cpp_api.cc | 35 ++++ rust/internal.rs | 14 ++ rust/repeated.rs | 119 ++++++++++++ rust/shared.rs | 2 + rust/test/cpp/interop/test_utils.cc | 2 +- rust/test/shared/BUILD | 6 + rust/test/shared/accessors_test.rs | 49 +++++ rust/upb.rs | 176 +++++++++++++++++- rust/upb_kernel/BUILD | 1 + rust/upb_kernel/upb_api.c | 3 +- src/google/protobuf/compiler/rust/BUILD.bazel | 1 + .../rust/accessors/accessor_generator.h | 8 + .../compiler/rust/accessors/accessors.cc | 13 +- .../rust/accessors/repeated_scalar.cc | 156 ++++++++++++++++ src/google/protobuf/compiler/rust/naming.cc | 39 +++- 21 files changed, 831 insertions(+), 18 deletions(-) create mode 100644 rust/cpp_kernel/cpp_api.cc create mode 100644 rust/repeated.rs create mode 100644 src/google/protobuf/compiler/rust/accessors/repeated_scalar.cc diff --git a/Cargo.bazel.lock b/Cargo.bazel.lock index 80674909ca..3839525cf1 100644 --- a/Cargo.bazel.lock +++ b/Cargo.bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "8bc2d235f612e77f4dca1b6886cc8bd14df348168fea27a687805ed9518a8f1a", + "checksum": "641f887b045ff0fc19f64df79b53d96d77d1c03c96069036d84bd1104ddc0000", "crates": { "aho-corasick 1.1.2": { "name": "aho-corasick", @@ -108,6 +108,15 @@ "selects": {} }, "edition": "2018", + "proc_macro_deps": { + "common": [ + { + "id": "paste 1.0.14", + "target": "paste" + } + ], + "selects": {} + }, "version": "0.0.1" }, "license": null @@ -318,6 +327,59 @@ }, "license": "MIT OR Apache-2.0" }, + "paste 1.0.14": { + "name": "paste", + "version": "1.0.14", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/paste/1.0.14/download", + "sha256": "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "paste", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "paste", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "paste 1.0.14", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.0.14" + }, + "build_script_attrs": { + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0" + }, "proc-macro2 1.0.69": { "name": "proc-macro2", "version": "1.0.69", @@ -769,4 +831,3 @@ }, "conditions": {} } - diff --git a/Cargo.lock b/Cargo.lock index e075e9722c..ea70571b3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,6 +22,7 @@ name = "direct-cargo-bazel-deps" version = "0.0.1" dependencies = [ "googletest", + "paste", ] [[package]] @@ -61,6 +62,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "proc-macro2" version = "1.0.69" @@ -130,4 +137,3 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - diff --git a/WORKSPACE b/WORKSPACE index 2c665be1a8..d0d66ec54f 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -193,6 +193,9 @@ crates_repository( "googletest": crate.spec( version = ">0.0.0", ), + "paste": crate.spec( + version = ">=1", + ), }, ) diff --git a/rust/BUILD b/rust/BUILD index dd23b44abe..3e0ca71ed6 100644 --- a/rust/BUILD +++ b/rust/BUILD @@ -52,6 +52,7 @@ PROTOBUF_SHARED = [ "optional.rs", "primitive.rs", "proxied.rs", + "repeated.rs", "shared.rs", "string.rs", "vtable.rs", @@ -92,8 +93,14 @@ rust_library( name = "protobuf_cpp", srcs = PROTOBUF_SHARED + ["cpp.rs"], crate_root = "shared.rs", + proc_macro_deps = [ + "@crate_index//:paste", + ], rustc_flags = ["--cfg=cpp_kernel"], - deps = [":utf8"], + deps = [ + ":utf8", + "//rust/cpp_kernel:cpp_api", + ], ) rust_test( diff --git a/rust/cpp.rs b/rust/cpp.rs index c2af02d7c0..6ef124070e 100644 --- a/rust/cpp.rs +++ b/rust/cpp.rs @@ -7,7 +7,8 @@ // Rust Protobuf runtime using the C++ kernel. -use crate::__internal::{Private, RawArena, RawMessage}; +use crate::__internal::{Private, RawArena, RawMessage, RawRepeatedField}; +use paste::paste; use std::alloc::Layout; use std::cell::UnsafeCell; use std::fmt; @@ -35,6 +36,7 @@ pub struct Arena { impl Arena { /// Allocates a fresh arena. #[inline] + #[allow(clippy::new_without_default)] pub fn new() -> Self { Self { ptr: NonNull::dangling(), _not_sync: PhantomData } } @@ -182,6 +184,116 @@ pub fn copy_bytes_in_arena_if_needed_by_runtime<'a>( val } +/// RepeatedField impls delegate out to `extern "C"` functions exposed by +/// `cpp_api.h` and store either a RepeatedField* or a RepeatedPtrField* +/// depending on the type. +/// +/// Note: even though this type is `Copy`, it should only be copied by +/// protobuf internals that can maintain mutation invariants: +/// +/// - No concurrent mutation for any two fields in a message: this means +/// mutators cannot be `Send` but are `Sync`. +/// - If there are multiple accessible `Mut` to a single message at a time, they +/// must be different fields, and not be in the same oneof. As such, a `Mut` +/// cannot be `Clone` but *can* reborrow itself with `.as_mut()`, which +/// converts `&'b mut Mut<'a, T>` to `Mut<'b, T>`. +#[derive(Clone, Copy)] +pub struct RepeatedField<'msg, T: ?Sized> { + inner: RepeatedFieldInner<'msg>, + _phantom: PhantomData<&'msg mut T>, +} + +/// CPP runtime-specific arguments for initializing a RepeatedField. +/// See RepeatedField comment about mutation invariants for when this type can +/// be copied. +#[derive(Clone, Copy)] +pub struct RepeatedFieldInner<'msg> { + pub raw: RawRepeatedField, + pub _phantom: PhantomData<&'msg ()>, +} + +impl<'msg, T: ?Sized> RepeatedField<'msg, T> { + pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self { + RepeatedField { inner, _phantom: PhantomData } + } +} +impl<'msg> RepeatedField<'msg, i32> {} + +pub trait RepeatedScalarOps { + fn new_repeated_field() -> RawRepeatedField; + fn push(f: RawRepeatedField, v: Self); + fn len(f: RawRepeatedField) -> usize; + fn get(f: RawRepeatedField, i: usize) -> Self; + fn set(f: RawRepeatedField, i: usize, v: Self); +} + +macro_rules! impl_repeated_scalar_ops { + ($($t: ty),*) => { + paste! { $( + extern "C" { + fn [< __pb_rust_RepeatedField_ $t _new >]() -> RawRepeatedField; + fn [< __pb_rust_RepeatedField_ $t _add >](f: RawRepeatedField, v: $t); + fn [< __pb_rust_RepeatedField_ $t _size >](f: RawRepeatedField) -> usize; + fn [< __pb_rust_RepeatedField_ $t _get >](f: RawRepeatedField, i: usize) -> $t; + fn [< __pb_rust_RepeatedField_ $t _set >](f: RawRepeatedField, i: usize, v: $t); + } + impl RepeatedScalarOps for $t { + fn new_repeated_field() -> RawRepeatedField { + unsafe { [< __pb_rust_RepeatedField_ $t _new >]() } + } + fn push(f: RawRepeatedField, v: Self) { + unsafe { [< __pb_rust_RepeatedField_ $t _add >](f, v) } + } + fn len(f: RawRepeatedField) -> usize { + unsafe { [< __pb_rust_RepeatedField_ $t _size >](f) } + } + fn get(f: RawRepeatedField, i: usize) -> Self { + unsafe { [< __pb_rust_RepeatedField_ $t _get >](f, i) } + } + fn set(f: RawRepeatedField, i: usize, v: Self) { + unsafe { [< __pb_rust_RepeatedField_ $t _set >](f, i, v) } + } + } + )* } + }; +} + +impl_repeated_scalar_ops!(i32, u32, i64, u64, f32, f64, bool); + +impl<'msg, T: RepeatedScalarOps> RepeatedField<'msg, T> { + #[allow(clippy::new_without_default, dead_code)] + /// new() is not currently used in our normal pathways, it is only used + /// for testing. Existing `RepeatedField<>`s are owned by, and retrieved + /// from, the containing `Message`. + pub fn new() -> Self { + Self::from_inner( + Private, + RepeatedFieldInner::<'msg> { raw: T::new_repeated_field(), _phantom: PhantomData }, + ) + } + pub fn push(&mut self, val: T) { + T::push(self.inner.raw, val) + } + pub fn len(&self) -> usize { + T::len(self.inner.raw) + } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn get(&self, index: usize) -> Option { + if index >= self.len() { + return None; + } + Some(T::get(self.inner.raw, index)) + } + pub fn set(&mut self, index: usize, val: T) { + if index >= self.len() { + return; + } + T::set(self.inner.raw, index, val) + } +} + #[cfg(test)] mod tests { use super::*; @@ -201,4 +313,27 @@ mod tests { let serialized_data = SerializedData { data: NonNull::new(ptr).unwrap(), len: len }; assert_eq!(&*serialized_data, b"Hello world"); } + + #[test] + fn repeated_field() { + let mut r = RepeatedField::::new(); + assert_eq!(r.len(), 0); + r.push(32); + assert_eq!(r.get(0), Some(32)); + + let mut r = RepeatedField::::new(); + assert_eq!(r.len(), 0); + r.push(32); + assert_eq!(r.get(0), Some(32)); + + let mut r = RepeatedField::::new(); + assert_eq!(r.len(), 0); + r.push(0.1234f64); + assert_eq!(r.get(0), Some(0.1234)); + + let mut r = RepeatedField::::new(); + assert_eq!(r.len(), 0); + r.push(true); + assert_eq!(r.get(0), Some(true)); + } } diff --git a/rust/cpp_kernel/BUILD b/rust/cpp_kernel/BUILD index 245772c834..d10f9e7db8 100644 --- a/rust/cpp_kernel/BUILD +++ b/rust/cpp_kernel/BUILD @@ -4,13 +4,14 @@ load("@rules_rust//rust:defs.bzl", "rust_library") cc_library( name = "cpp_api", + srcs = ["cpp_api.cc"], hdrs = ["cpp_api.h"], visibility = [ "//src/google/protobuf:__subpackages__", "//rust:__subpackages__", ], deps = [ - ":rust_alloc_for_cpp_api", + ":rust_alloc_for_cpp_api", # buildcleaner: keep "//:protobuf_nowkt", ], ) diff --git a/rust/cpp_kernel/cpp_api.cc b/rust/cpp_kernel/cpp_api.cc new file mode 100644 index 0000000000..8ff79d8fa9 --- /dev/null +++ b/rust/cpp_kernel/cpp_api.cc @@ -0,0 +1,35 @@ +#include "google/protobuf/repeated_field.h" + +extern "C" { + +#define expose_repeated_field_methods(ty, rust_ty) \ + google::protobuf::RepeatedField* __pb_rust_RepeatedField_##rust_ty##_new() { \ + return new google::protobuf::RepeatedField(); \ + } \ + void __pb_rust_RepeatedField_##rust_ty##_add(google::protobuf::RepeatedField* r, \ + ty val) { \ + r->Add(val); \ + } \ + size_t __pb_rust_RepeatedField_##rust_ty##_size( \ + google::protobuf::RepeatedField* r) { \ + return r->size(); \ + } \ + ty __pb_rust_RepeatedField_##rust_ty##_get(google::protobuf::RepeatedField* r, \ + size_t index) { \ + return r->Get(index); \ + } \ + void __pb_rust_RepeatedField_##rust_ty##_set(google::protobuf::RepeatedField* r, \ + size_t index, ty val) { \ + return r->Set(index, val); \ + } + +expose_repeated_field_methods(int32_t, i32); +expose_repeated_field_methods(uint32_t, u32); +expose_repeated_field_methods(float, f32); +expose_repeated_field_methods(double, f64); +expose_repeated_field_methods(bool, bool); +expose_repeated_field_methods(uint64_t, u64); +expose_repeated_field_methods(int64_t, i64); + +#undef expose_repeated_field_methods +} diff --git a/rust/internal.rs b/rust/internal.rs index 1e0f536b19..e56c9dc555 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -51,6 +51,17 @@ mod _opaque_pointees { _data: [u8; 0], _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, } + + /// Opaque pointee for [`RawRepeatedField`] + /// + /// This type is not meant to be dereferenced in Rust code. + /// It is only meant to provide type safety for raw pointers + /// which are manipulated behind FFI. + #[repr(C)] + pub struct RawRepeatedFieldData { + _data: [u8; 0], + _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, + } } /// A raw pointer to the underlying message for this runtime. @@ -59,6 +70,9 @@ pub type RawMessage = NonNull<_opaque_pointees::RawMessageData>; /// A raw pointer to the underlying arena for this runtime. pub type RawArena = NonNull<_opaque_pointees::RawArenaData>; +/// A raw pointer to the underlying repeated field container for this runtime. +pub type RawRepeatedField = NonNull<_opaque_pointees::RawRepeatedFieldData>; + /// Represents an ABI-stable version of `NonNull<[u8]>`/`string_view` (a /// borrowed slice of bytes) for FFI use only. /// diff --git a/rust/repeated.rs b/rust/repeated.rs new file mode 100644 index 0000000000..b824de8399 --- /dev/null +++ b/rust/repeated.rs @@ -0,0 +1,119 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +/// Repeated scalar fields are implemented around the runtime-specific +/// `RepeatedField` struct. `RepeatedField` stores an opaque pointer to the +/// runtime-specific representation of a repeated scalar (`upb_Array*` on upb, +/// and `RepeatedField*` on cpp). +use std::marker::PhantomData; + +use crate::{ + __internal::{Private, RawRepeatedField}, + __runtime::{RepeatedField, RepeatedFieldInner}, +}; + +#[derive(Clone, Copy)] +pub struct RepeatedFieldRef<'a> { + pub repeated_field: RawRepeatedField, + pub _phantom: PhantomData<&'a mut ()>, +} + +unsafe impl<'a> Send for RepeatedFieldRef<'a> {} +unsafe impl<'a> Sync for RepeatedFieldRef<'a> {} + +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct RepeatedView<'a, T: ?Sized> { + inner: RepeatedField<'a, T>, +} + +impl<'msg, T: ?Sized> RepeatedView<'msg, T> { + pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self { + Self { inner: RepeatedField::<'msg>::from_inner(_private, inner) } + } +} + +pub struct RepeatedFieldIter<'a, T> { + inner: RepeatedField<'a, T>, + current_index: usize, +} + +impl<'a, T> std::fmt::Debug for RepeatedView<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("RepeatedView").finish() + } +} + +#[repr(transparent)] +pub struct RepeatedMut<'a, T: ?Sized> { + inner: RepeatedField<'a, T>, +} + +impl<'msg, T: ?Sized> RepeatedMut<'msg, T> { + pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self { + Self { inner: RepeatedField::from_inner(_private, inner) } + } +} + +impl<'a, T> std::ops::Deref for RepeatedMut<'a, T> { + type Target = RepeatedView<'a, T>; + fn deref(&self) -> &Self::Target { + // SAFETY: + // - `Repeated{View,Mut}<'a, T>` are both `#[repr(transparent)]` over + // `RepeatedField<'a, T>`. + // - `RepeatedField` is a type alias for `NonNull`. + unsafe { &*(self as *const Self as *const RepeatedView<'a, T>) } + } +} + +macro_rules! impl_repeated_primitives { + ($($t:ty),*) => { + $( + impl<'a> RepeatedView<'a, $t> { + pub fn len(&self) -> usize { + self.inner.len() + } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn get(&self, index: usize) -> Option<$t> { + self.inner.get(index) + } + } + + impl<'a> RepeatedMut<'a, $t> { + pub fn push(&mut self, val: $t) { + self.inner.push(val) + } + pub fn set(&mut self, index: usize, val: $t) { + self.inner.set(index, val) + } + } + + impl<'a> std::iter::Iterator for RepeatedFieldIter<'a, $t> { + type Item = $t; + fn next(&mut self) -> Option { + let val = self.inner.get(self.current_index); + if val.is_some() { + self.current_index += 1; + } + val + } + } + + impl<'a> std::iter::IntoIterator for RepeatedView<'a, $t> { + type Item = $t; + type IntoIter = RepeatedFieldIter<'a, $t>; + fn into_iter(self) -> Self::IntoIter { + RepeatedFieldIter { inner: self.inner, current_index: 0 } + } + } + )* + } +} + +impl_repeated_primitives!(i32, u32, bool, f32, f64, i64, u64); diff --git a/rust/shared.rs b/rust/shared.rs index 3c4408d943..f8a9d117d9 100644 --- a/rust/shared.rs +++ b/rust/shared.rs @@ -22,6 +22,7 @@ pub mod __public { pub use crate::proxied::{ Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy, }; + pub use crate::repeated::{RepeatedFieldRef, RepeatedMut, RepeatedView}; pub use crate::string::{BytesMut, ProtoStr, ProtoStrMut}; } pub use __public::*; @@ -46,6 +47,7 @@ mod macros; mod optional; mod primitive; mod proxied; +mod repeated; mod string; mod vtable; diff --git a/rust/test/cpp/interop/test_utils.cc b/rust/test/cpp/interop/test_utils.cc index d5c3784df1..5c27a95c9b 100644 --- a/rust/test/cpp/interop/test_utils.cc +++ b/rust/test/cpp/interop/test_utils.cc @@ -8,7 +8,7 @@ #include #include "absl/strings/string_view.h" -#include "google/protobuf/rust/cpp_kernel/cpp_api.h" +#include "rust/cpp_kernel/cpp_api.h" #include "google/protobuf/unittest.pb.h" extern "C" void MutateTestAllTypes(protobuf_unittest::TestAllTypes* msg) { diff --git a/rust/test/shared/BUILD b/rust/test/shared/BUILD index e5be7b7511..79d43ddd4e 100644 --- a/rust/test/shared/BUILD +++ b/rust/test/shared/BUILD @@ -151,6 +151,9 @@ rust_test( "//rust:protobuf_cpp": "protobuf", "//rust/test/shared:matchers_cpp": "matchers", }, + proc_macro_deps = [ + "@crate_index//:paste", + ], tags = [ # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. "not_build:arm", @@ -170,6 +173,9 @@ rust_test( "//rust:protobuf_upb": "protobuf", "//rust/test/shared:matchers_upb": "matchers", }, + proc_macro_deps = [ + "@crate_index//:paste", + ], tags = [ # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. "not_build:arm", diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs index 40098b18ef..910f9f133e 100644 --- a/rust/test/shared/accessors_test.rs +++ b/rust/test/shared/accessors_test.rs @@ -9,6 +9,7 @@ use googletest::prelude::*; use matchers::{is_set, is_unset}; +use paste::paste; use protobuf::Optional; use unittest_proto::proto2_unittest::{TestAllTypes, TestAllTypes_}; @@ -398,3 +399,51 @@ fn test_oneof_accessors() { // This should show it set to the OneofBytes but its not supported yet. assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); } + +macro_rules! generate_repeated_numeric_test { + ($(($t: ty, $field: ident)),*) => { + paste! { $( + #[test] + fn [< test_repeated_ $field _accessors >]() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.[< repeated_ $field >]().len(), eq(0)); + assert_that!(msg.[]().get(0), none()); + + let mut mutator = msg.[](); + mutator.push(1 as $t); + assert_that!(mutator.len(), eq(1)); + assert_that!(mutator.get(0), some(eq(1 as $t))); + mutator.set(0, 2 as $t); + assert_that!(mutator.get(0), some(eq(2 as $t))); + mutator.push(1 as $t); + + assert_that!(mutator.into_iter().collect::>(), eq(vec![2 as $t, 1 as $t])); + } + )* } + }; +} + +generate_repeated_numeric_test!( + (i32, int32), + (u32, uint32), + (i64, int64), + (u64, uint64), + (f32, float), + (f64, double) +); + +#[test] +fn test_repeated_bool_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.repeated_bool().len(), eq(0)); + assert_that!(msg.repeated_bool().get(0), none()); + + let mut mutator = msg.repeated_bool_mut(); + mutator.push(true); + assert_that!(mutator.len(), eq(1)); + assert_that!(mutator.get(0), some(eq(true))); + mutator.set(0, false); + assert_that!(mutator.get(0), some(eq(false))); + mutator.push(true); + assert_that!(mutator.into_iter().collect::>(), eq(vec![false, true])); +} diff --git a/rust/upb.rs b/rust/upb.rs index cd5cc77e74..57f9c5512b 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -7,7 +7,7 @@ //! UPB FFI wrapper code for use by Rust Protobuf. -use crate::__internal::{Private, RawArena, RawMessage}; +use crate::__internal::{Private, PtrAndLen, RawArena, RawMessage, RawRepeatedField}; use std::alloc; use std::alloc::Layout; use std::cell::UnsafeCell; @@ -284,6 +284,149 @@ pub fn copy_bytes_in_arena_if_needed_by_runtime<'a>( } } +/// RepeatedFieldInner contains a `upb_Array*` as well as a reference to an +/// `Arena`, most likely that of the containing `Message`. upb requires an Arena +/// to perform mutations on a repeated field. +#[derive(Clone, Copy, Debug)] +pub struct RepeatedFieldInner<'msg> { + pub raw: RawRepeatedField, + pub arena: &'msg Arena, +} + +#[derive(Clone, Copy, Debug)] +pub struct RepeatedField<'msg, T: ?Sized> { + inner: RepeatedFieldInner<'msg>, + _phantom: PhantomData<&'msg mut T>, +} + +impl<'msg, T: ?Sized> RepeatedField<'msg, T> { + pub fn len(&self) -> usize { + unsafe { upb_Array_Size(self.inner.raw) } + } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self { + Self { inner, _phantom: PhantomData } + } +} + +// Transcribed from google3/third_party/upb/upb/message/value.h +#[repr(C)] +#[derive(Clone, Copy)] +union upb_MessageValue { + bool_val: bool, + float_val: std::ffi::c_float, + double_val: std::ffi::c_double, + uint32_val: u32, + int32_val: i32, + uint64_val: u64, + int64_val: i64, + array_val: *const std::ffi::c_void, + map_val: *const std::ffi::c_void, + msg_val: *const std::ffi::c_void, + str_val: PtrAndLen, +} + +// Transcribed from google3/third_party/upb/upb/base/descriptor_constants.h +#[repr(C)] +#[allow(dead_code)] +enum UpbCType { + Bool = 1, + Float = 2, + Int32 = 3, + UInt32 = 4, + Enum = 5, + Message = 6, + Double = 7, + Int64 = 8, + UInt64 = 9, + String = 10, + Bytes = 11, +} + +extern "C" { + #[allow(dead_code)] + fn upb_Array_New(a: RawArena, r#type: std::ffi::c_int) -> RawRepeatedField; + fn upb_Array_Size(arr: RawRepeatedField) -> usize; + fn upb_Array_Set(arr: RawRepeatedField, i: usize, val: upb_MessageValue); + fn upb_Array_Get(arr: RawRepeatedField, i: usize) -> upb_MessageValue; + fn upb_Array_Append(arr: RawRepeatedField, val: upb_MessageValue, arena: RawArena); +} + +macro_rules! impl_repeated_primitives { + ($(($rs_type:ty, $union_field:ident, $upb_tag:expr)),*) => { + $( + impl<'msg> RepeatedField<'msg, $rs_type> { + #[allow(dead_code)] + fn new(arena: &'msg Arena) -> Self { + Self { + inner: RepeatedFieldInner { + raw: unsafe { upb_Array_New(arena.raw, $upb_tag as std::ffi::c_int) }, + arena, + }, + _phantom: PhantomData, + } + } + pub fn push(&mut self, val: $rs_type) { + unsafe { upb_Array_Append( + self.inner.raw, + upb_MessageValue { $union_field: val }, + self.inner.arena.raw(), + ) } + } + pub fn get(&self, i: usize) -> Option<$rs_type> { + if i >= self.len() { + None + } else { + unsafe { Some(upb_Array_Get(self.inner.raw, i).$union_field) } + } + } + pub fn set(&self, i: usize, val: $rs_type) { + if i >= self.len() { + return; + } + unsafe { upb_Array_Set( + self.inner.raw, + i, + upb_MessageValue { $union_field: val }, + ) } + } + } + )* + } +} + +impl_repeated_primitives!( + (bool, bool_val, UpbCType::Bool), + (f32, float_val, UpbCType::Float), + (f64, double_val, UpbCType::Double), + (i32, int32_val, UpbCType::Int32), + (u32, uint32_val, UpbCType::UInt32), + (i64, int64_val, UpbCType::Int64), + (u64, uint64_val, UpbCType::UInt64) +); + +/// Returns a static thread-local empty RepeatedFieldInner for use in a +/// RepeatedView. +/// +/// # Safety +/// TODO: Split RepeatedFieldInner into mut and const variants to +/// enforce safety. The returned array must never be mutated. +pub unsafe fn empty_array() -> RepeatedFieldInner<'static> { + // TODO: Consider creating empty array in C. + fn new_repeated_field_inner() -> RepeatedFieldInner<'static> { + let arena = Box::leak::<'static>(Box::new(Arena::new())); + // Provide `i32` as a placeholder type. + RepeatedField::<'static, i32>::new(arena).inner + } + thread_local! { + static REPEATED_FIELD: RepeatedFieldInner<'static> = new_repeated_field_inner(); + } + + REPEATED_FIELD.with(|inner| *inner) +} + #[cfg(test)] mod tests { use super::*; @@ -309,4 +452,35 @@ mod tests { }; assert_eq!(&*serialized_data, b"Hello world"); } + + #[test] + fn i32_array() { + let mut arena = Arena::new(); + let mut arr = RepeatedField::::new(&arena); + assert_eq!(arr.len(), 0); + arr.push(1); + assert_eq!(arr.get(0), Some(1)); + assert_eq!(arr.len(), 1); + arr.set(0, 3); + assert_eq!(arr.get(0), Some(3)); + for i in 0..2048 { + arr.push(i); + assert_eq!(arr.get(arr.len() - 1), Some(i)); + } + } + #[test] + fn u32_array() { + let mut arena = Arena::new(); + let mut arr = RepeatedField::::new(&mut arena); + assert_eq!(arr.len(), 0); + arr.push(1); + assert_eq!(arr.get(0), Some(1)); + assert_eq!(arr.len(), 1); + arr.set(0, 3); + assert_eq!(arr.get(0), Some(3)); + for i in 0..2048 { + arr.push(i); + assert_eq!(arr.get(arr.len() - 1), Some(i)); + } + } } diff --git a/rust/upb_kernel/BUILD b/rust/upb_kernel/BUILD index dc65231433..b06f182117 100644 --- a/rust/upb_kernel/BUILD +++ b/rust/upb_kernel/BUILD @@ -8,6 +8,7 @@ cc_library( "//rust:__subpackages__", ], deps = [ + "//upb:collections", "//upb:mem", ], ) diff --git a/rust/upb_kernel/upb_api.c b/rust/upb_kernel/upb_api.c index 985749da23..a30b4dd9bb 100644 --- a/rust/upb_kernel/upb_api.c +++ b/rust/upb_kernel/upb_api.c @@ -8,4 +8,5 @@ #define UPB_BUILD_API -#include "upb/mem/arena.h" // IWYU pragma: keep +#include "upb/collections/array.h" // IWYU pragma: keep +#include "upb/mem/arena.h" // IWYU pragma: keep diff --git a/src/google/protobuf/compiler/rust/BUILD.bazel b/src/google/protobuf/compiler/rust/BUILD.bazel index f404beae97..1429b9bff1 100644 --- a/src/google/protobuf/compiler/rust/BUILD.bazel +++ b/src/google/protobuf/compiler/rust/BUILD.bazel @@ -51,6 +51,7 @@ cc_library( name = "accessors", srcs = [ "accessors/accessors.cc", + "accessors/repeated_scalar.cc", "accessors/singular_message.cc", "accessors/singular_scalar.cc", "accessors/singular_string.cc", diff --git a/src/google/protobuf/compiler/rust/accessors/accessor_generator.h b/src/google/protobuf/compiler/rust/accessors/accessor_generator.h index e3a453493c..3bf1dca06d 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessor_generator.h +++ b/src/google/protobuf/compiler/rust/accessors/accessor_generator.h @@ -86,6 +86,14 @@ class SingularMessage final : public AccessorGenerator { void InThunkCc(Context field) const override; }; +class RepeatedScalar final : public AccessorGenerator { + public: + ~RepeatedScalar() override = default; + void InMsgImpl(Context field) const override; + void InExternC(Context field) const override; + void InThunkCc(Context field) const override; +}; + class UnsupportedField final : public AccessorGenerator { public: ~UnsupportedField() override = default; diff --git a/src/google/protobuf/compiler/rust/accessors/accessors.cc b/src/google/protobuf/compiler/rust/accessors/accessors.cc index 82b38cc642..fa5c876bf9 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessors.cc +++ b/src/google/protobuf/compiler/rust/accessors/accessors.cc @@ -29,10 +29,6 @@ std::unique_ptr AccessorGeneratorFor( return std::make_unique(); } - if (desc.is_repeated()) { - return std::make_unique(); - } - switch (desc.type()) { case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_INT64: @@ -47,11 +43,20 @@ std::unique_ptr AccessorGeneratorFor( case FieldDescriptor::TYPE_FLOAT: case FieldDescriptor::TYPE_DOUBLE: case FieldDescriptor::TYPE_BOOL: + if (desc.is_repeated()) { + return std::make_unique(); + } return std::make_unique(); case FieldDescriptor::TYPE_BYTES: case FieldDescriptor::TYPE_STRING: + if (desc.is_repeated()) { + return std::make_unique(); + } return std::make_unique(); case FieldDescriptor::TYPE_MESSAGE: + if (desc.is_repeated()) { + return std::make_unique(); + } return std::make_unique(); default: diff --git a/src/google/protobuf/compiler/rust/accessors/repeated_scalar.cc b/src/google/protobuf/compiler/rust/accessors/repeated_scalar.cc new file mode 100644 index 0000000000..8f0a7625b3 --- /dev/null +++ b/src/google/protobuf/compiler/rust/accessors/repeated_scalar.cc @@ -0,0 +1,156 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/compiler/rust/accessors/accessor_generator.h" +#include "google/protobuf/compiler/rust/context.h" +#include "google/protobuf/compiler/rust/naming.h" +#include "google/protobuf/descriptor.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace rust { + +void RepeatedScalar::InMsgImpl(Context field) const { + field.Emit({{"field", field.desc().name()}, + {"Scalar", PrimitiveRsTypeName(field.desc())}, + {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"getter", + [&] { + if (field.is_upb()) { + field.Emit({}, R"rs( + pub fn r#$field$(&self) -> $pb$::RepeatedView<'_, $Scalar$> { + let inner = unsafe { + $getter_thunk$( + self.inner.msg, + /* optional size pointer */ std::ptr::null(), + ) } + .map_or_else(|| unsafe {$pbr$::empty_array()}, |raw| { + $pbr$::RepeatedFieldInner{ raw, arena: &self.inner.arena } + }); + $pb$::RepeatedView::from_inner($pbi$::Private, inner) + } + )rs"); + } else { + field.Emit({}, R"rs( + pub fn r#$field$(&self) -> $pb$::RepeatedView<'_, $Scalar$> { + $pb$::RepeatedView::from_inner( + $pbi$::Private, + $pbr$::RepeatedFieldInner{ + raw: unsafe { $getter_thunk$(self.inner.msg) }, + _phantom: std::marker::PhantomData, + }, + ) + } + )rs"); + } + }}, + {"clearer_thunk", Thunk(field, "clear")}, + {"field_mutator_getter", + [&] { + if (field.is_upb()) { + field.Emit({}, R"rs( + pub fn r#$field$_mut(&mut self) -> $pb$::RepeatedMut<'_, $Scalar$> { + $pb$::RepeatedMut::from_inner( + $pbi$::Private, + $pbr$::RepeatedFieldInner{ + raw: unsafe { $getter_mut_thunk$( + self.inner.msg, + /* optional size pointer */ std::ptr::null(), + self.inner.arena.raw(), + ) }, + arena: &self.inner.arena, + }, + ) + } + )rs"); + } else { + field.Emit({}, R"rs( + pub fn r#$field$_mut(&mut self) -> $pb$::RepeatedMut<'_, $Scalar$> { + $pb$::RepeatedMut::from_inner( + $pbi$::Private, + $pbr$::RepeatedFieldInner{ + raw: unsafe { $getter_mut_thunk$(self.inner.msg)}, + _phantom: std::marker::PhantomData, + }, + ) + } + )rs"); + } + }}}, + R"rs( + $getter$ + $field_mutator_getter$ + )rs"); +} + +void RepeatedScalar::InExternC(Context field) const { + field.Emit({{"Scalar", PrimitiveRsTypeName(field.desc())}, + {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"getter", + [&] { + if (field.is_upb()) { + field.Emit(R"rs( + fn $getter_mut_thunk$( + raw_msg: $pbi$::RawMessage, + size: *const usize, + arena: $pbi$::RawArena, + ) -> $pbi$::RawRepeatedField; + // Returns `None` when returned array pointer is NULL. + fn $getter_thunk$( + raw_msg: $pbi$::RawMessage, + size: *const usize, + ) -> Option<$pbi$::RawRepeatedField>; + )rs"); + } else { + field.Emit(R"rs( + fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage) -> $pbi$::RawRepeatedField; + fn $getter_thunk$(raw_msg: $pbi$::RawMessage) -> $pbi$::RawRepeatedField; + )rs"); + } + }}, + {"clearer_thunk", Thunk(field, "clear")}}, + R"rs( + fn $clearer_thunk$(raw_msg: $pbi$::RawMessage); + $getter$ + )rs"); +} + +void RepeatedScalar::InThunkCc(Context field) const { + field.Emit({{"field", cpp::FieldName(&field.desc())}, + {"Scalar", cpp::PrimitiveTypeName(field.desc().cpp_type())}, + {"QualifiedMsg", + cpp::QualifiedClassName(field.desc().containing_type())}, + {"clearer_thunk", Thunk(field, "clear")}, + {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"impls", + [&] { + field.Emit( + R"cc( + void $clearer_thunk$($QualifiedMsg$* msg) { + msg->clear_$field$(); + } + google::protobuf::RepeatedField<$Scalar$>* $getter_mut_thunk$($QualifiedMsg$* msg) { + return msg->mutable_$field$(); + } + const google::protobuf::RepeatedField<$Scalar$>& $getter_thunk$($QualifiedMsg$& msg) { + return msg.$field$(); + } + )cc"); + }}}, + "$impls$"); +} + +} // namespace rust +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/rust/naming.cc b/src/google/protobuf/compiler/rust/naming.cc index eb0b30b905..bb1c35a3e2 100644 --- a/src/google/protobuf/compiler/rust/naming.cc +++ b/src/google/protobuf/compiler/rust/naming.cc @@ -64,22 +64,28 @@ std::string GetHeaderFile(Context file) { namespace { template -std::string Thunk(Context field, absl::string_view op) { +std::string FieldPrefix(Context field) { // NOTE: When field.is_upb(), this functions outputs must match the symbols // that the upbc plugin generates exactly. Failure to do so correctly results // in a link-time failure. absl::string_view prefix = field.is_cpp() ? "__rust_proto_thunk__" : ""; - std::string thunk = + std::string thunk_prefix = absl::StrCat(prefix, GetUnderscoreDelimitedFullName( field.WithDesc(field.desc().containing_type()))); + return thunk_prefix; +} + +template +std::string Thunk(Context field, absl::string_view op) { + std::string thunk = FieldPrefix(field); absl::string_view format; if (field.is_upb() && op == "get") { // upb getter is simply the field name (no "get" in the name). format = "_$1"; - } else if (field.is_upb() && op == "case") { - // upb oneof case function is x_case compared to has/set/clear which are in - // the other order e.g. clear_x. + } else if (field.is_upb() && (op == "case")) { + // some upb functions are in the order x_op compared to has/set/clear which + // are in the other order e.g. op_x. format = "_$1_$0"; } else { format = "_$0_$1"; @@ -89,9 +95,32 @@ std::string Thunk(Context field, absl::string_view op) { return thunk; } +std::string ThunkRepeated(Context field, + absl::string_view op) { + if (!field.is_upb()) { + return Thunk(field, op); + } + + std::string thunk = absl::StrCat("_", FieldPrefix(field)); + absl::string_view format; + if (op == "get") { + format = "_$1_upb_array"; + } else if (op == "get_mut") { + format = "_$1_mutable_upb_array"; + } else { + return Thunk(field, op); + } + + absl::SubstituteAndAppend(&thunk, format, op, field.desc().name()); + return thunk; +} + } // namespace std::string Thunk(Context field, absl::string_view op) { + if (field.desc().is_repeated()) { + return ThunkRepeated(field, op); + } return Thunk(field, op); } From 9831212313e287b873ee1327356ec3404d2dd229 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 17 Oct 2023 21:36:07 +0000 Subject: [PATCH 15/95] Auto-generate files after cl/574261929 --- src/file_lists.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/src/file_lists.cmake b/src/file_lists.cmake index d320be43a6..70df9b057e 100644 --- a/src/file_lists.cmake +++ b/src/file_lists.cmake @@ -384,6 +384,7 @@ set(libprotoc_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/accessors.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/repeated_scalar.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/singular_message.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/singular_string.cc From 8908ea9aff5dfab6d1da12ea4e20ecb073cc75f2 Mon Sep 17 00:00:00 2001 From: Martijn Vels Date: Tue, 17 Oct 2023 14:56:58 -0700 Subject: [PATCH 16/95] Enable Arena Enabled Copy Constructor for RepeatedPtrField MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Benchmarking has this as a saving of up to 20%: name old cpu/op new cpu/op delta BM_MergeFromMessage/1 830ns ±15% 712ns ±16% -14.22% (p=0.000 n=20+20) BM_MergeFromMessage/10 9.03µs ±13% 7.42µs ±13% -17.91% (p=0.000 n=20+18) BM_MergeFromMessage/100 93.3µs ±16% 76.5µs ± 6% -18.01% (p=0.000 n=20+17) BM_MergeFromMessageWithArena/1 614ns ±16% 478ns ± 3% -22.07% (p=0.000 n=20+16) BM_MergeFromMessageWithArena/10 6.05µs ±14% 4.93µs ±19% -18.53% (p=0.000 n=20+20) BM_MergeFromMessageWithArena/100 59.7µs ±15% 49.3µs ±20% -17.51% (p=0.000 n=20+20) PiperOrigin-RevId: 574274002 --- src/google/protobuf/repeated_ptr_field.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index d38232462e..7a0c0989fe 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -311,9 +311,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // Message creating functor: used in MergeFrom() template static MessageLite* CopyMessage(Arena* arena, const MessageLite& src) { - T* msg = Arena::CreateMaybeMessage(arena); - msg->MergeFrom(static_cast(src)); - return msg; + return Arena::CreateMaybeMessage(arena, static_cast(src)); } // Appends all message values from `from` to this instance. From 8c80a3265ddb82e4e4009e059552fd895b3c6d54 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Tue, 17 Oct 2023 16:37:25 -0700 Subject: [PATCH 17/95] Restructure syntax branches in binary conformance tests. This doesn't change the tests at all, but refactors them to be more reusable in different contexts. Specifically, this will make it easier to add corresponding editions-based tests. This also splits the concept of "uses a proto3 message" and "runs proto3 tests", in preparation for that change. PiperOrigin-RevId: 574299923 --- conformance/BUILD.bazel | 1 + conformance/binary_json_conformance_suite.cc | 1619 +++++++++--------- conformance/binary_json_conformance_suite.h | 93 +- 3 files changed, 864 insertions(+), 849 deletions(-) diff --git a/conformance/BUILD.bazel b/conformance/BUILD.bazel index c4955042cb..42c1b3da34 100644 --- a/conformance/BUILD.bazel +++ b/conformance/BUILD.bazel @@ -157,6 +157,7 @@ cc_library( ":conformance_test", ":test_messages_proto2_proto_cc", ":test_messages_proto3_proto_cc", + "@com_google_absl//absl/log:die_if_null", "@com_google_absl//absl/status", "@jsoncpp", ], diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index cc43c86589..81ee1a4970 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -7,8 +7,10 @@ #include "binary_json_conformance_suite.h" +#include #include #include +#include #include #include @@ -16,6 +18,7 @@ #include "google/protobuf/util/type_resolver_util.h" #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" +#include "absl/log/die_if_null.h" #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "json/json.h" @@ -23,22 +26,22 @@ #include "conformance_test.h" #include "google/protobuf/endian.h" #include "google/protobuf/test_messages_proto2.pb.h" +#include "google/protobuf/test_messages_proto2.pb.h" +#include "google/protobuf/test_messages_proto3.pb.h" #include "google/protobuf/test_messages_proto3.pb.h" #include "google/protobuf/text_format.h" +#include "google/protobuf/util/type_resolver_util.h" #include "google/protobuf/wire_format_lite.h" -namespace proto2_messages = protobuf_test_messages::proto2; - using conformance::ConformanceRequest; using conformance::ConformanceResponse; using conformance::WireFormat; using google::protobuf::Descriptor; using google::protobuf::FieldDescriptor; -using google::protobuf::Message; using google::protobuf::internal::WireFormatLite; using google::protobuf::internal::little_endian::FromHost; using google::protobuf::util::NewTypeResolverForDescriptorPool; -using proto2_messages::TestAllTypesProto2; +using protobuf_test_messages::proto2::TestAllTypesProto2; using protobuf_test_messages::proto3::TestAllTypesProto3; using std::string; @@ -197,87 +200,6 @@ string GetNonDefaultValue(FieldDescriptor::Type type) { #define UNKNOWN_FIELD 666 -enum class Packed { - kUnspecified = 0, - kTrue = 1, - kFalse = 2, -}; - -const FieldDescriptor* GetFieldForType(FieldDescriptor::Type type, - bool repeated, bool is_proto3, - Packed packed = Packed::kUnspecified) { - const Descriptor* d = is_proto3 ? TestAllTypesProto3().GetDescriptor() - : TestAllTypesProto2().GetDescriptor(); - for (int i = 0; i < d->field_count(); i++) { - const FieldDescriptor* f = d->field(i); - if (f->type() == type && f->is_repeated() == repeated) { - if ((packed == Packed::kTrue && !f->is_packed()) || - (packed == Packed::kFalse && f->is_packed())) { - continue; - } - return f; - } - } - - absl::string_view packed_string = ""; - const absl::string_view repeated_string = - repeated ? "Repeated " : "Singular "; - const absl::string_view proto_string = is_proto3 ? "Proto3" : "Proto2"; - if (packed == Packed::kTrue) { - packed_string = "Packed "; - } - if (packed == Packed::kFalse) { - packed_string = "Unpacked "; - } - ABSL_LOG(FATAL) << "Couldn't find field with type: " << repeated_string - << packed_string << FieldDescriptor::TypeName(type) << " for " - << proto_string; - return nullptr; -} - -const FieldDescriptor* GetFieldForMapType(FieldDescriptor::Type key_type, - FieldDescriptor::Type value_type, - bool is_proto3) { - const Descriptor* d = is_proto3 ? TestAllTypesProto3().GetDescriptor() - : TestAllTypesProto2().GetDescriptor(); - for (int i = 0; i < d->field_count(); i++) { - const FieldDescriptor* f = d->field(i); - if (f->is_map()) { - const Descriptor* map_entry = f->message_type(); - const FieldDescriptor* key = map_entry->field(0); - const FieldDescriptor* value = map_entry->field(1); - if (key->type() == key_type && value->type() == value_type) { - return f; - } - } - } - - const absl::string_view proto_string = is_proto3 ? "Proto3" : "Proto2"; - ABSL_LOG(FATAL) << "Couldn't find map field with type: " - << FieldDescriptor::TypeName(key_type) << " and " - << FieldDescriptor::TypeName(key_type) << " for " - << proto_string; - return nullptr; -} - -const FieldDescriptor* GetFieldForOneofType(FieldDescriptor::Type type, - bool is_proto3, - bool exclusive = false) { - const Descriptor* d = is_proto3 ? TestAllTypesProto3().GetDescriptor() - : TestAllTypesProto2().GetDescriptor(); - for (int i = 0; i < d->field_count(); i++) { - const FieldDescriptor* f = d->field(i); - if (f->containing_oneof() && ((f->type() == type) ^ exclusive)) { - return f; - } - } - - const absl::string_view proto_string = is_proto3 ? "Proto3" : "Proto2"; - ABSL_LOG(FATAL) << "Couldn't find oneof field with type: " - << FieldDescriptor::TypeName(type) << " for " << proto_string; - return nullptr; -} - string UpperCase(string str) { for (size_t i = 0; i < str.size(); i++) { str[i] = toupper(str[i]); @@ -285,16 +207,6 @@ string UpperCase(string str) { return str; } -std::unique_ptr NewTestMessage(bool is_proto3) { - std::unique_ptr prototype; - if (is_proto3) { - prototype = std::make_unique(); - } else { - prototype = std::make_unique(); - } - return prototype; -} - bool IsProto3Default(FieldDescriptor::Type type, const string& binary_data) { switch (type) { case FieldDescriptor::TYPE_DOUBLE: @@ -402,38 +314,51 @@ bool BinaryAndJsonConformanceSuite::ParseResponse( return true; } -void BinaryAndJsonConformanceSuite::ExpectParseFailureForProtoWithProtoVersion( - const string& proto, const string& test_name, ConformanceLevel level, - bool is_proto3) { - std::unique_ptr prototype = NewTestMessage(is_proto3); +void BinaryAndJsonConformanceSuite::RunSuiteImpl() { + type_resolver_.reset(NewTypeResolverForDescriptorPool( + kTypeUrlPrefix, DescriptorPool::generated_pool())); + type_url_ = GetTypeUrl(TestAllTypesProto3::descriptor()); + + BinaryAndJsonConformanceSuiteImpl( + this, /*run_proto3_tests=*/true); + BinaryAndJsonConformanceSuiteImpl( + this, /*run_proto3_tests=*/false); +} + +template +void BinaryAndJsonConformanceSuiteImpl:: + ExpectParseFailureForProtoWithProtoVersion(const string& proto, + const string& test_name, + ConformanceLevel level) { + MessageType prototype; // We don't expect output, but if the program erroneously accepts the protobuf // we let it send its response as this. We must not leave it unspecified. ConformanceRequestSetting setting( level, conformance::PROTOBUF, conformance::PROTOBUF, - conformance::BINARY_TEST, *prototype, test_name, proto); + conformance::BINARY_TEST, prototype, test_name, proto); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - string effective_test_name = absl::StrCat( - setting.ConformanceLevelToString(level), - (is_proto3 ? ".Proto3" : ".Proto2"), ".ProtobufInput.", test_name); + string effective_test_name = + absl::StrCat(setting.ConformanceLevelToString(level), ".", + SyntaxIdentifier(), ".ProtobufInput.", test_name); - RunTest(effective_test_name, request, &response); + suite_.RunTest(effective_test_name, request, &response); if (response.result_case() == ConformanceResponse::kParseError) { - ReportSuccess(effective_test_name); + suite_.ReportSuccess(effective_test_name); } else if (response.result_case() == ConformanceResponse::kSkipped) { - ReportSkip(effective_test_name, request, response); + suite_.ReportSkip(effective_test_name, request, response); } else { - ReportFailure(effective_test_name, level, request, response, - "Should have failed to parse, but didn't."); + suite_.ReportFailure(effective_test_name, level, request, response, + "Should have failed to parse, but didn't."); } } // Expect that this precise protobuf will cause a parse error. -void BinaryAndJsonConformanceSuite::ExpectParseFailureForProto( +template +void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForProto( const string& proto, const string& test_name, ConformanceLevel level) { - ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, true); - ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, false); + ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level); } // Expect that this protobuf will cause a parse error, even if it is followed @@ -441,103 +366,106 @@ void BinaryAndJsonConformanceSuite::ExpectParseFailureForProto( // data verbatim and once with this data followed by some valid data. // // TODO: implement the second of these. -void BinaryAndJsonConformanceSuite::ExpectHardParseFailureForProto( - const string& proto, const string& test_name, ConformanceLevel level) { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::ExpectHardParseFailureForProto(const string& proto, + const string& test_name, + ConformanceLevel level) { return ExpectParseFailureForProto(proto, test_name, level); } -void BinaryAndJsonConformanceSuite::RunValidJsonTest( +template +void BinaryAndJsonConformanceSuiteImpl::RunValidJsonTest( const string& test_name, ConformanceLevel level, const string& input_json, const string& equivalent_text_format) { - TestAllTypesProto3 prototype; + MessageType prototype; RunValidJsonTestWithMessage(test_name, level, input_json, equivalent_text_format, prototype); } -void BinaryAndJsonConformanceSuite::RunValidJsonTest( - const string& test_name, ConformanceLevel level, const string& input_json, - const string& equivalent_text_format, bool is_proto3) { - if (is_proto3) { - RunValidJsonTest(test_name, level, input_json, equivalent_text_format); - } else { - TestAllTypesProto2 prototype; - RunValidJsonTestWithMessage(test_name, level, input_json, - equivalent_text_format, prototype); - } -} - -void BinaryAndJsonConformanceSuite::RunValidJsonTestWithMessage( - const string& test_name, ConformanceLevel level, const string& input_json, - const string& equivalent_text_format, const Message& prototype) { +template +void BinaryAndJsonConformanceSuiteImpl:: + RunValidJsonTestWithMessage(const string& test_name, ConformanceLevel level, + const string& input_json, + const string& equivalent_text_format, + const Message& prototype) { ConformanceRequestSetting setting1( level, conformance::JSON, conformance::PROTOBUF, conformance::JSON_TEST, prototype, test_name, input_json); - RunValidInputTest(setting1, equivalent_text_format); + suite_.RunValidInputTest(setting1, equivalent_text_format); ConformanceRequestSetting setting2(level, conformance::JSON, conformance::JSON, conformance::JSON_TEST, prototype, test_name, input_json); - RunValidInputTest(setting2, equivalent_text_format); + suite_.RunValidInputTest(setting2, equivalent_text_format); } -void BinaryAndJsonConformanceSuite::RunValidJsonTestWithProtobufInput( - const string& test_name, ConformanceLevel level, - const TestAllTypesProto3& input, const string& equivalent_text_format) { +template +void BinaryAndJsonConformanceSuiteImpl:: + RunValidJsonTestWithProtobufInput(const string& test_name, + ConformanceLevel level, + const TestAllTypesProto3& input, + const string& equivalent_text_format) { ConformanceRequestSetting setting( level, conformance::PROTOBUF, conformance::JSON, conformance::JSON_TEST, input, test_name, input.SerializeAsString()); - RunValidInputTest(setting, equivalent_text_format); + suite_.RunValidInputTest(setting, equivalent_text_format); } -void BinaryAndJsonConformanceSuite::RunValidJsonIgnoreUnknownTest( - const string& test_name, ConformanceLevel level, const string& input_json, - const string& equivalent_text_format) { +template +void BinaryAndJsonConformanceSuiteImpl:: + RunValidJsonIgnoreUnknownTest(const string& test_name, + ConformanceLevel level, + const string& input_json, + const string& equivalent_text_format) { TestAllTypesProto3 prototype; ConformanceRequestSetting setting( level, conformance::JSON, conformance::PROTOBUF, conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST, prototype, test_name, input_json); - RunValidInputTest(setting, equivalent_text_format); + suite_.RunValidInputTest(setting, equivalent_text_format); } -void BinaryAndJsonConformanceSuite::RunValidProtobufTest( +template +void BinaryAndJsonConformanceSuiteImpl::RunValidProtobufTest( const string& test_name, ConformanceLevel level, - const string& input_protobuf, const string& equivalent_text_format, - bool is_proto3) { - std::unique_ptr prototype = NewTestMessage(is_proto3); + const string& input_protobuf, const string& equivalent_text_format) { + MessageType prototype; ConformanceRequestSetting setting1( level, conformance::PROTOBUF, conformance::PROTOBUF, - conformance::BINARY_TEST, *prototype, test_name, input_protobuf); - RunValidInputTest(setting1, equivalent_text_format); + conformance::BINARY_TEST, prototype, test_name, input_protobuf); + suite_.RunValidInputTest(setting1, equivalent_text_format); - if (is_proto3) { + if (run_proto3_tests_) { ConformanceRequestSetting setting2( level, conformance::PROTOBUF, conformance::JSON, - conformance::BINARY_TEST, *prototype, test_name, input_protobuf); - RunValidInputTest(setting2, equivalent_text_format); + conformance::BINARY_TEST, prototype, test_name, input_protobuf); + suite_.RunValidInputTest(setting2, equivalent_text_format); } } -void BinaryAndJsonConformanceSuite::RunValidBinaryProtobufTest( +template +void BinaryAndJsonConformanceSuiteImpl::RunValidBinaryProtobufTest( const string& test_name, ConformanceLevel level, - const string& input_protobuf, bool is_proto3) { - RunValidBinaryProtobufTest(test_name, level, input_protobuf, input_protobuf, - is_proto3); + const string& input_protobuf) { + RunValidBinaryProtobufTest(test_name, level, input_protobuf, input_protobuf); } -void BinaryAndJsonConformanceSuite::RunValidBinaryProtobufTest( +template +void BinaryAndJsonConformanceSuiteImpl::RunValidBinaryProtobufTest( const string& test_name, ConformanceLevel level, - const string& input_protobuf, const string& expected_protobuf, - bool is_proto3) { - std::unique_ptr prototype = NewTestMessage(is_proto3); + const string& input_protobuf, const string& expected_protobuf) { + MessageType prototype; ConformanceRequestSetting setting( level, conformance::PROTOBUF, conformance::PROTOBUF, - conformance::BINARY_TEST, *prototype, test_name, input_protobuf); - RunValidBinaryInputTest(setting, expected_protobuf, true); + conformance::BINARY_TEST, prototype, test_name, input_protobuf); + suite_.RunValidBinaryInputTest(setting, expected_protobuf, true); } -void BinaryAndJsonConformanceSuite::RunBinaryPerformanceMergeMessageWithField( - const string& test_name, const string& field_proto, bool is_proto3) { +template +void BinaryAndJsonConformanceSuiteImpl:: + RunBinaryPerformanceMergeMessageWithField(const string& test_name, + const string& field_proto) { string message_tag = tag(27, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); string message_proto = absl::StrCat(message_tag, delim(field_proto)); @@ -553,66 +481,72 @@ void BinaryAndJsonConformanceSuite::RunBinaryPerformanceMergeMessageWithField( string expected_proto = absl::StrCat(message_tag, delim(multiple_repeated_field_proto)); - RunValidBinaryProtobufTest(test_name, RECOMMENDED, proto, expected_proto, - is_proto3); + RunValidBinaryProtobufTest(test_name, RECOMMENDED, proto, expected_proto); } -void BinaryAndJsonConformanceSuite::RunValidProtobufTestWithMessage( - const string& test_name, ConformanceLevel level, const Message* input, - const string& equivalent_text_format, bool is_proto3) { +template +void BinaryAndJsonConformanceSuiteImpl:: + RunValidProtobufTestWithMessage(const string& test_name, + ConformanceLevel level, + const Message* input, + const string& equivalent_text_format) { RunValidProtobufTest(test_name, level, input->SerializeAsString(), - equivalent_text_format, is_proto3); + equivalent_text_format); } // According to proto JSON specification, JSON serializers follow more strict // rules than parsers (e.g., a serializer must serialize int32 values as JSON // numbers while the parser is allowed to accept them as JSON strings). This // method allows strict checking on a proto JSON serializer by inspecting -// the JSON output directly. -void BinaryAndJsonConformanceSuite::RunValidJsonTestWithValidator( - const string& test_name, ConformanceLevel level, const string& input_json, - const Validator& validator, bool is_proto3) { - std::unique_ptr prototype = NewTestMessage(is_proto3); + +template // the JSON output directly. +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunValidJsonTestWithValidator(const string& test_name, + ConformanceLevel level, + const string& input_json, + const Validator& validator) { + MessageType prototype; ConformanceRequestSetting setting(level, conformance::JSON, conformance::JSON, - conformance::JSON_TEST, *prototype, + conformance::JSON_TEST, prototype, test_name, input_json); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; string effective_test_name = - absl::StrCat(setting.ConformanceLevelToString(level), - is_proto3 ? ".Proto3.JsonInput." : ".Proto2.JsonInput.", - test_name, ".Validator"); + absl::StrCat(setting.ConformanceLevelToString(level), ".", + SyntaxIdentifier(), ".JsonInput.", test_name, ".Validator"); - RunTest(effective_test_name, request, &response); + suite_.RunTest(effective_test_name, request, &response); if (response.result_case() == ConformanceResponse::kSkipped) { - ReportSkip(effective_test_name, request, response); + suite_.ReportSkip(effective_test_name, request, response); return; } if (response.result_case() != ConformanceResponse::kJsonPayload) { - ReportFailure(effective_test_name, level, request, response, - absl::StrCat("Expected JSON payload but got type ", - response.result_case())); + suite_.ReportFailure(effective_test_name, level, request, response, + absl::StrCat("Expected JSON payload but got type ", + response.result_case())); return; } Json::Reader reader; Json::Value value; if (!reader.parse(response.json_payload(), value)) { - ReportFailure(effective_test_name, level, request, response, - absl::StrCat("JSON payload cannot be parsed as valid JSON: ", - reader.getFormattedErrorMessages())); + suite_.ReportFailure( + effective_test_name, level, request, response, + absl::StrCat("JSON payload cannot be parsed as valid JSON: ", + reader.getFormattedErrorMessages())); return; } if (!validator(value)) { - ReportFailure(effective_test_name, level, request, response, - "JSON payload validation failed."); + suite_.ReportFailure(effective_test_name, level, request, response, + "JSON payload validation failed."); return; } - ReportSuccess(effective_test_name); + suite_.ReportSuccess(effective_test_name); } -void BinaryAndJsonConformanceSuite::ExpectParseFailureForJson( +template +void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForJson( const string& test_name, ConformanceLevel level, const string& input_json) { TestAllTypesProto3 prototype; // We don't expect output, but if the program erroneously accepts the protobuf @@ -625,20 +559,22 @@ void BinaryAndJsonConformanceSuite::ExpectParseFailureForJson( string effective_test_name = absl::StrCat( setting.ConformanceLevelToString(level), ".Proto3.JsonInput.", test_name); - RunTest(effective_test_name, request, &response); + suite_.RunTest(effective_test_name, request, &response); if (response.result_case() == ConformanceResponse::kParseError) { - ReportSuccess(effective_test_name); + suite_.ReportSuccess(effective_test_name); } else if (response.result_case() == ConformanceResponse::kSkipped) { - ReportSkip(effective_test_name, request, response); + suite_.ReportSkip(effective_test_name, request, response); } else { - ReportFailure(effective_test_name, level, request, response, - "Should have failed to parse, but didn't."); + suite_.ReportFailure(effective_test_name, level, request, response, + "Should have failed to parse, but didn't."); } } -void BinaryAndJsonConformanceSuite::ExpectSerializeFailureForJson( - const string& test_name, ConformanceLevel level, - const string& text_format) { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::ExpectSerializeFailureForJson(const string& test_name, + ConformanceLevel level, + const string& text_format) { TestAllTypesProto3 payload_message; ABSL_CHECK(TextFormat::ParseFromString(text_format, &payload_message)) << "Failed to parse: " << text_format; @@ -652,18 +588,19 @@ void BinaryAndJsonConformanceSuite::ExpectSerializeFailureForJson( string effective_test_name = absl::StrCat( setting.ConformanceLevelToString(level), ".", test_name, ".JsonOutput"); - RunTest(effective_test_name, request, &response); + suite_.RunTest(effective_test_name, request, &response); if (response.result_case() == ConformanceResponse::kSerializeError) { - ReportSuccess(effective_test_name); + suite_.ReportSuccess(effective_test_name); } else if (response.result_case() == ConformanceResponse::kSkipped) { - ReportSkip(effective_test_name, request, response); + suite_.ReportSkip(effective_test_name, request, response); } else { - ReportFailure(effective_test_name, level, request, response, - "Should have failed to serialize, but didn't."); + suite_.ReportFailure(effective_test_name, level, request, response, + "Should have failed to serialize, but didn't."); } } -void BinaryAndJsonConformanceSuite::TestPrematureEOFForType( +template +void BinaryAndJsonConformanceSuiteImpl::TestPrematureEOFForType( FieldDescriptor::Type type) { // Incomplete values for each wire type. static constexpr absl::string_view incompletes[6] = { @@ -675,8 +612,8 @@ void BinaryAndJsonConformanceSuite::TestPrematureEOFForType( "abc" // 32BIT }; - const FieldDescriptor* field = GetFieldForType(type, false, true); - const FieldDescriptor* rep_field = GetFieldForType(type, true, true); + const FieldDescriptor* field = GetFieldForType(type, false); + const FieldDescriptor* rep_field = GetFieldForType(type, true); WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( static_cast(type)); absl::string_view incomplete = incompletes[wire_type]; @@ -760,175 +697,174 @@ void BinaryAndJsonConformanceSuite::TestPrematureEOFForType( } } -void BinaryAndJsonConformanceSuite::TestValidDataForType( +template +void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( FieldDescriptor::Type type, std::vector> values) { - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( - static_cast(type)); - const FieldDescriptor* field = GetFieldForType(type, false, is_proto3); - const FieldDescriptor* rep_field = GetFieldForType(type, true, is_proto3); - - // Test singular data for singular fields. - for (size_t i = 0; i < values.size(); i++) { - string proto = - absl::StrCat(tag(field->number(), wire_type), values[i].first); - // In proto3, default primitive fields should not be encoded. - string expected_proto = - is_proto3 && IsProto3Default(field->type(), values[i].second) - ? "" - : absl::StrCat(tag(field->number(), wire_type), values[i].second); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(expected_proto); - string text; - TextFormat::PrintToString(*test_message, &text); - - RunValidProtobufTest( - absl::StrCat("ValidDataScalar", type_name, "[", i, "]"), REQUIRED, - proto, text, is_proto3); - RunValidBinaryProtobufTest( - absl::StrCat("ValidDataScalarBinary", type_name, "[", i, "]"), - RECOMMENDED, proto, expected_proto, is_proto3); - } + const string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( + static_cast(type)); + const FieldDescriptor* field = GetFieldForType(type, false); + const FieldDescriptor* rep_field = GetFieldForType(type, true); + + // Test singular data for singular fields. + for (size_t i = 0; i < values.size(); i++) { + string proto = + absl::StrCat(tag(field->number(), wire_type), values[i].first); + // In proto3, default primitive fields should not be encoded. + string expected_proto = + run_proto3_tests_ && IsProto3Default(field->type(), values[i].second) + ? "" + : absl::StrCat(tag(field->number(), wire_type), values[i].second); + MessageType test_message; + test_message.MergeFromString(expected_proto); + string text; + TextFormat::PrintToString(test_message, &text); - // Test repeated data for singular fields. - // For scalar message fields, repeated values are merged, which is tested - // separately. - if (type != FieldDescriptor::TYPE_MESSAGE) { - string proto; - for (size_t i = 0; i < values.size(); i++) { - proto += absl::StrCat(tag(field->number(), wire_type), values[i].first); - } - string expected_proto = - absl::StrCat(tag(field->number(), wire_type), values.back().second); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(expected_proto); - string text; - TextFormat::PrintToString(*test_message, &text); + RunValidProtobufTest( + absl::StrCat("ValidDataScalar", type_name, "[", i, "]"), REQUIRED, + proto, text); + RunValidBinaryProtobufTest( + absl::StrCat("ValidDataScalarBinary", type_name, "[", i, "]"), + RECOMMENDED, proto, expected_proto); + } - RunValidProtobufTest(absl::StrCat("RepeatedScalarSelectsLast", type_name), - REQUIRED, proto, text, is_proto3); + // Test repeated data for singular fields. + // For scalar message fields, repeated values are merged, which is tested + // separately. + if (type != FieldDescriptor::TYPE_MESSAGE) { + string proto; + for (size_t i = 0; i < values.size(); i++) { + proto += absl::StrCat(tag(field->number(), wire_type), values[i].first); } + string expected_proto = + absl::StrCat(tag(field->number(), wire_type), values.back().second); + MessageType test_message; + test_message.MergeFromString(expected_proto); + string text; + TextFormat::PrintToString(test_message, &text); - // Test repeated fields. - if (FieldDescriptor::IsTypePackable(type)) { - const FieldDescriptor* packed_field = - GetFieldForType(type, true, is_proto3, Packed::kTrue); - const FieldDescriptor* unpacked_field = - GetFieldForType(type, true, is_proto3, Packed::kFalse); - - string default_proto_packed; - string default_proto_unpacked; - string default_proto_packed_expected; - string default_proto_unpacked_expected; - string packed_proto_packed; - string packed_proto_unpacked; - string packed_proto_expected; - string unpacked_proto_packed; - string unpacked_proto_unpacked; - string unpacked_proto_expected; - - for (size_t i = 0; i < values.size(); i++) { - default_proto_unpacked += - absl::StrCat(tag(rep_field->number(), wire_type), values[i].first); - default_proto_unpacked_expected += - absl::StrCat(tag(rep_field->number(), wire_type), values[i].second); - default_proto_packed += values[i].first; - default_proto_packed_expected += values[i].second; - packed_proto_unpacked += absl::StrCat( - tag(packed_field->number(), wire_type), values[i].first); - packed_proto_packed += values[i].first; - packed_proto_expected += values[i].second; - unpacked_proto_unpacked += absl::StrCat( - tag(unpacked_field->number(), wire_type), values[i].first); - unpacked_proto_packed += values[i].first; - unpacked_proto_expected += absl::StrCat( - tag(unpacked_field->number(), wire_type), values[i].second); - } - default_proto_packed = absl::StrCat( - tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(default_proto_packed)); - default_proto_packed_expected = absl::StrCat( - tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(default_proto_packed_expected)); - packed_proto_packed = - absl::StrCat(tag(packed_field->number(), - WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(packed_proto_packed)); - packed_proto_expected = - absl::StrCat(tag(packed_field->number(), - WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(packed_proto_expected)); - unpacked_proto_packed = - absl::StrCat(tag(unpacked_field->number(), - WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(unpacked_proto_packed)); - - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(default_proto_packed_expected); - string text; - TextFormat::PrintToString(*test_message, &text); + RunValidProtobufTest(absl::StrCat("RepeatedScalarSelectsLast", type_name), + REQUIRED, proto, text); + } - // Ensures both packed and unpacked data can be parsed. - RunValidProtobufTest( - absl::StrCat("ValidDataRepeated", type_name, ".UnpackedInput"), - REQUIRED, default_proto_unpacked, text, is_proto3); - RunValidProtobufTest( - absl::StrCat("ValidDataRepeated", type_name, ".PackedInput"), - REQUIRED, default_proto_packed, text, is_proto3); - - // proto2 should encode as unpacked by default and proto3 should encode as - // packed by default. - string expected_proto = rep_field->is_packed() - ? default_proto_packed_expected - : default_proto_unpacked_expected; - RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, - ".UnpackedInput.DefaultOutput"), - RECOMMENDED, default_proto_unpacked, - expected_proto, is_proto3); - RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, - ".PackedInput.DefaultOutput"), - RECOMMENDED, default_proto_packed, - expected_proto, is_proto3); - RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, - ".UnpackedInput.PackedOutput"), - RECOMMENDED, packed_proto_unpacked, - packed_proto_expected, is_proto3); - RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, - ".PackedInput.PackedOutput"), - RECOMMENDED, packed_proto_packed, - packed_proto_expected, is_proto3); - RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, - ".UnpackedInput.UnpackedOutput"), - RECOMMENDED, unpacked_proto_unpacked, - unpacked_proto_expected, is_proto3); - RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, - ".PackedInput.UnpackedOutput"), - RECOMMENDED, unpacked_proto_packed, - unpacked_proto_expected, is_proto3); - } else { - string proto; - string expected_proto; - for (size_t i = 0; i < values.size(); i++) { - proto += - absl::StrCat(tag(rep_field->number(), wire_type), values[i].first); - expected_proto += - absl::StrCat(tag(rep_field->number(), wire_type), values[i].second); - } - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(expected_proto); - string text; - TextFormat::PrintToString(*test_message, &text); + // Test repeated fields. + if (FieldDescriptor::IsTypePackable(type)) { + const FieldDescriptor* packed_field = + GetFieldForType(type, true, Packed::kTrue); + const FieldDescriptor* unpacked_field = + GetFieldForType(type, true, Packed::kFalse); + + string default_proto_packed; + string default_proto_unpacked; + string default_proto_packed_expected; + string default_proto_unpacked_expected; + string packed_proto_packed; + string packed_proto_unpacked; + string packed_proto_expected; + string unpacked_proto_packed; + string unpacked_proto_unpacked; + string unpacked_proto_expected; - RunValidProtobufTest(absl::StrCat("ValidDataRepeated", type_name), - REQUIRED, proto, text, is_proto3); + for (size_t i = 0; i < values.size(); i++) { + default_proto_unpacked += + absl::StrCat(tag(rep_field->number(), wire_type), values[i].first); + default_proto_unpacked_expected += + absl::StrCat(tag(rep_field->number(), wire_type), values[i].second); + default_proto_packed += values[i].first; + default_proto_packed_expected += values[i].second; + packed_proto_unpacked += + absl::StrCat(tag(packed_field->number(), wire_type), values[i].first); + packed_proto_packed += values[i].first; + packed_proto_expected += values[i].second; + unpacked_proto_unpacked += absl::StrCat( + tag(unpacked_field->number(), wire_type), values[i].first); + unpacked_proto_packed += values[i].first; + unpacked_proto_expected += absl::StrCat( + tag(unpacked_field->number(), wire_type), values[i].second); + } + default_proto_packed = absl::StrCat( + tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(default_proto_packed)); + default_proto_packed_expected = absl::StrCat( + tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(default_proto_packed_expected)); + packed_proto_packed = absl::StrCat( + tag(packed_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(packed_proto_packed)); + packed_proto_expected = absl::StrCat( + tag(packed_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(packed_proto_expected)); + unpacked_proto_packed = + absl::StrCat(tag(unpacked_field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(unpacked_proto_packed)); + + MessageType test_message; + test_message.MergeFromString(default_proto_packed_expected); + string text; + TextFormat::PrintToString(test_message, &text); + + // Ensures both packed and unpacked data can be parsed. + RunValidProtobufTest( + absl::StrCat("ValidDataRepeated", type_name, ".UnpackedInput"), + REQUIRED, default_proto_unpacked, text); + RunValidProtobufTest( + absl::StrCat("ValidDataRepeated", type_name, ".PackedInput"), REQUIRED, + default_proto_packed, text); + + // proto2 should encode as unpacked by default and proto3 should encode as + // packed by default. + string expected_proto = rep_field->is_packed() + ? default_proto_packed_expected + : default_proto_unpacked_expected; + RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, + ".UnpackedInput.DefaultOutput"), + RECOMMENDED, default_proto_unpacked, + expected_proto); + RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, + ".PackedInput.DefaultOutput"), + RECOMMENDED, default_proto_packed, + expected_proto); + RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, + ".UnpackedInput.PackedOutput"), + RECOMMENDED, packed_proto_unpacked, + packed_proto_expected); + RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, + ".PackedInput.PackedOutput"), + RECOMMENDED, packed_proto_packed, + packed_proto_expected); + RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, + ".UnpackedInput.UnpackedOutput"), + RECOMMENDED, unpacked_proto_unpacked, + unpacked_proto_expected); + RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, + ".PackedInput.UnpackedOutput"), + RECOMMENDED, unpacked_proto_packed, + unpacked_proto_expected); + } else { + string proto; + string expected_proto; + for (size_t i = 0; i < values.size(); i++) { + proto += + absl::StrCat(tag(rep_field->number(), wire_type), values[i].first); + expected_proto += + absl::StrCat(tag(rep_field->number(), wire_type), values[i].second); } + MessageType test_message; + test_message.MergeFromString(expected_proto); + string text; + TextFormat::PrintToString(test_message, &text); + + RunValidProtobufTest(absl::StrCat("ValidDataRepeated", type_name), REQUIRED, + proto, text); } } -void BinaryAndJsonConformanceSuite::TestValidDataForRepeatedScalarMessage() { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::TestValidDataForRepeatedScalarMessage() { std::vector values = { delim(absl::StrCat( tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), @@ -954,10 +890,9 @@ void BinaryAndJsonConformanceSuite::TestValidDataForRepeatedScalarMessage() { } })"; - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { string proto; const FieldDescriptor* field = - GetFieldForType(FieldDescriptor::TYPE_MESSAGE, false, is_proto3); + GetFieldForType(FieldDescriptor::TYPE_MESSAGE, false); for (size_t i = 0; i < values.size(); i++) { proto += absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), @@ -965,48 +900,46 @@ void BinaryAndJsonConformanceSuite::TestValidDataForRepeatedScalarMessage() { } RunValidProtobufTest("RepeatedScalarMessageMerge", REQUIRED, proto, - absl::StrCat(field->name(), ": ", expected), - is_proto3); - } + absl::StrCat(field->name(), ": ", expected)); } -void BinaryAndJsonConformanceSuite::TestValidDataForMapType( +template +void BinaryAndJsonConformanceSuiteImpl::TestValidDataForMapType( FieldDescriptor::Type key_type, FieldDescriptor::Type value_type) { - const string key_type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(key_type))); - const string value_type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(value_type))); - WireFormatLite::WireType key_wire_type = WireFormatLite::WireTypeForFieldType( - static_cast(key_type)); - WireFormatLite::WireType value_wire_type = - WireFormatLite::WireTypeForFieldType( - static_cast(value_type)); - - string key1_data = - absl::StrCat(tag(1, key_wire_type), GetDefaultValue(key_type)); - string value1_data = - absl::StrCat(tag(2, value_wire_type), GetDefaultValue(value_type)); - string key2_data = - absl::StrCat(tag(1, key_wire_type), GetNonDefaultValue(key_type)); - string value2_data = - absl::StrCat(tag(2, value_wire_type), GetNonDefaultValue(value_type)); - - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { - const FieldDescriptor* field = - GetFieldForMapType(key_type, value_type, is_proto3); + const string key_type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(key_type))); + const string value_type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(value_type))); + WireFormatLite::WireType key_wire_type = + WireFormatLite::WireTypeForFieldType( + static_cast(key_type)); + WireFormatLite::WireType value_wire_type = + WireFormatLite::WireTypeForFieldType( + static_cast(value_type)); + + string key1_data = + absl::StrCat(tag(1, key_wire_type), GetDefaultValue(key_type)); + string value1_data = + absl::StrCat(tag(2, value_wire_type), GetDefaultValue(value_type)); + string key2_data = + absl::StrCat(tag(1, key_wire_type), GetNonDefaultValue(key_type)); + string value2_data = + absl::StrCat(tag(2, value_wire_type), GetNonDefaultValue(value_type)); + + const FieldDescriptor* field = GetFieldForMapType(key_type, value_type); { // Tests map with default key and value. string proto = absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(absl::StrCat(key1_data, value1_data))); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto); + MessageType test_message; + test_message.MergeFromString(proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, value_type_name, ".Default"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); } { @@ -1014,13 +947,13 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType( string proto = absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim("")); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto); + MessageType test_message; + test_message.MergeFromString(proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, value_type_name, ".MissingDefault"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); } { @@ -1028,13 +961,13 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType( string proto = absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(absl::StrCat(key2_data, value2_data))); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto); + MessageType test_message; + test_message.MergeFromString(proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, value_type_name, ".NonDefault"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); } { @@ -1042,13 +975,13 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType( string proto = absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(absl::StrCat(value2_data, key2_data))); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto); + MessageType test_message; + test_message.MergeFromString(proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, value_type_name, ".Unordered"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); } { @@ -1060,13 +993,13 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(absl::StrCat(key2_data, value2_data))); string proto = absl::StrCat(proto1, proto2); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto2); + MessageType test_message; + test_message.MergeFromString(proto2); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, value_type_name, ".DuplicateKey"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); } { @@ -1074,14 +1007,14 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType( string proto = absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(absl::StrCat(key1_data, key2_data, value2_data))); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto); + MessageType test_message; + test_message.MergeFromString(proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest( absl::StrCat("ValidDataMap", key_type_name, value_type_name, ".DuplicateKeyInMapEntry"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); } { @@ -1089,41 +1022,41 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType( string proto = absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(absl::StrCat(key2_data, value1_data, value2_data))); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto); + MessageType test_message; + test_message.MergeFromString(proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest( absl::StrCat("ValidDataMap", key_type_name, value_type_name, ".DuplicateValueInMapEntry"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); } - } } -void BinaryAndJsonConformanceSuite::TestOverwriteMessageValueMap() { - string key_data = absl::StrCat( - tag(1, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim("")); - string field1_data = - absl::StrCat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field2_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field31_data = - absl::StrCat(tag(31, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string submsg1_data = delim(absl::StrCat(field1_data, field31_data)); - string submsg2_data = delim(absl::StrCat(field2_data, field31_data)); - string value1_data = absl::StrCat( - tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - submsg1_data))); - string value2_data = absl::StrCat( - tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - submsg2_data))); - - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::TestOverwriteMessageValueMap() { + string key_data = absl::StrCat( + tag(1, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim("")); + string field1_data = + absl::StrCat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1)); + string field2_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); + string field31_data = + absl::StrCat(tag(31, WireFormatLite::WIRETYPE_VARINT), varint(1)); + string submsg1_data = delim(absl::StrCat(field1_data, field31_data)); + string submsg2_data = delim(absl::StrCat(field2_data, field31_data)); + string value1_data = absl::StrCat( + tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + submsg1_data))); + string value2_data = absl::StrCat( + tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + submsg2_data))); + const FieldDescriptor* field = GetFieldForMapType( - FieldDescriptor::TYPE_STRING, FieldDescriptor::TYPE_MESSAGE, is_proto3); + FieldDescriptor::TYPE_STRING, FieldDescriptor::TYPE_MESSAGE); string proto1 = absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), @@ -1132,24 +1065,23 @@ void BinaryAndJsonConformanceSuite::TestOverwriteMessageValueMap() { tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(absl::StrCat(key_data, value2_data))); string proto = absl::StrCat(proto1, proto2); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto2); + MessageType test_message; + test_message.MergeFromString(proto2); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest("ValidDataMap.STRING.MESSAGE.MergeValue", REQUIRED, - proto, text, is_proto3); - } + proto, text); } -void BinaryAndJsonConformanceSuite::TestValidDataForOneofType( +template +void BinaryAndJsonConformanceSuiteImpl::TestValidDataForOneofType( FieldDescriptor::Type type) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( - static_cast(type)); + const string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( + static_cast(type)); - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { - const FieldDescriptor* field = GetFieldForOneofType(type, is_proto3); + const FieldDescriptor* field = GetFieldForOneofType(type); const string default_value = absl::StrCat(tag(field->number(), wire_type), GetDefaultValue(type)); const string non_default_value = @@ -1158,56 +1090,55 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType( { // Tests oneof with default value. const string proto = default_value; - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto); + MessageType test_message; + test_message.MergeFromString(proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest( absl::StrCat("ValidDataOneof", type_name, ".DefaultValue"), REQUIRED, - proto, text, is_proto3); + proto, text); RunValidBinaryProtobufTest( absl::StrCat("ValidDataOneofBinary", type_name, ".DefaultValue"), - RECOMMENDED, proto, proto, is_proto3); + RECOMMENDED, proto, proto); } { // Tests oneof with non-default value. const string proto = non_default_value; - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(proto); + MessageType test_message; + test_message.MergeFromString(proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest( absl::StrCat("ValidDataOneof", type_name, ".NonDefaultValue"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); RunValidBinaryProtobufTest( absl::StrCat("ValidDataOneofBinary", type_name, ".NonDefaultValue"), - RECOMMENDED, proto, proto, is_proto3); + RECOMMENDED, proto, proto); } { // Tests oneof with multiple values of the same field. const string proto = absl::StrCat(default_value, non_default_value); const string expected_proto = non_default_value; - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(expected_proto); + MessageType test_message; + test_message.MergeFromString(expected_proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name, ".MultipleValuesForSameField"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); RunValidBinaryProtobufTest(absl::StrCat("ValidDataOneofBinary", type_name, ".MultipleValuesForSameField"), - RECOMMENDED, proto, expected_proto, is_proto3); + RECOMMENDED, proto, expected_proto); } { // Tests oneof with multiple values of the different fields. - const FieldDescriptor* other_field = - GetFieldForOneofType(type, is_proto3, true); + const FieldDescriptor* other_field = GetFieldForOneofType(type, true); FieldDescriptor::Type other_type = other_field->type(); WireFormatLite::WireType other_wire_type = WireFormatLite::WireTypeForFieldType( @@ -1218,45 +1149,44 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType( const string proto = absl::StrCat(other_value, non_default_value); const string expected_proto = non_default_value; - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(expected_proto); + MessageType test_message; + test_message.MergeFromString(expected_proto); string text; - TextFormat::PrintToString(*test_message, &text); + TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name, ".MultipleValuesForDifferentField"), - REQUIRED, proto, text, is_proto3); + REQUIRED, proto, text); RunValidBinaryProtobufTest( absl::StrCat("ValidDataOneofBinary", type_name, ".MultipleValuesForDifferentField"), - RECOMMENDED, proto, expected_proto, is_proto3); + RECOMMENDED, proto, expected_proto); } - } } -void BinaryAndJsonConformanceSuite::TestMergeOneofMessage() { - string field1_data = - absl::StrCat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field2a_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field2b_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field89_data = - absl::StrCat(tag(89, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string submsg1_data = absl::StrCat( - tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(field1_data, field2a_data, field89_data))); - string submsg2_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(field2b_data, field89_data))); - string merged_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(field1_data, field2b_data, field89_data, - field89_data))); - - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { +template +void BinaryAndJsonConformanceSuiteImpl::TestMergeOneofMessage() { + string field1_data = + absl::StrCat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1)); + string field2a_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); + string field2b_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); + string field89_data = + absl::StrCat(tag(89, WireFormatLite::WIRETYPE_VARINT), varint(1)); + string submsg1_data = absl::StrCat( + tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(field1_data, field2a_data, field89_data))); + string submsg2_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(field2b_data, field89_data))); + string merged_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(field1_data, field2b_data, field89_data, + field89_data))); + const FieldDescriptor* field = - GetFieldForOneofType(FieldDescriptor::TYPE_MESSAGE, is_proto3); + GetFieldForOneofType(FieldDescriptor::TYPE_MESSAGE); string proto1 = absl::StrCat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), @@ -1269,79 +1199,78 @@ void BinaryAndJsonConformanceSuite::TestMergeOneofMessage() { tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(merged_data)); - std::unique_ptr test_message = NewTestMessage(is_proto3); - test_message->MergeFromString(expected_proto); + MessageType test_message; + test_message.MergeFromString(expected_proto); string text; - TextFormat::PrintToString(*test_message, &text); - RunValidProtobufTest("ValidDataOneof.MESSAGE.Merge", REQUIRED, proto, text, - is_proto3); + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest("ValidDataOneof.MESSAGE.Merge", REQUIRED, proto, text); RunValidBinaryProtobufTest("ValidDataOneofBinary.MESSAGE.Merge", - RECOMMENDED, proto, expected_proto, is_proto3); - } + RECOMMENDED, proto, expected_proto); } -void BinaryAndJsonConformanceSuite::TestIllegalTags() { - // field num 0 is illegal - string nullfield[] = {"\1DEADBEEF", "\2\1\1", "\3\4", "\5DEAD"}; - for (int i = 0; i < 4; i++) { - string name = "IllegalZeroFieldNum_Case_0"; - name.back() += i; - ExpectParseFailureForProto(nullfield[i], name, REQUIRED); - } +template +void BinaryAndJsonConformanceSuiteImpl::TestIllegalTags() { + // field num 0 is illegal + string nullfield[] = {"\1DEADBEEF", "\2\1\1", "\3\4", "\5DEAD"}; + for (int i = 0; i < 4; i++) { + string name = "IllegalZeroFieldNum_Case_0"; + name.back() += i; + ExpectParseFailureForProto(nullfield[i], name, REQUIRED); + } } -template -void BinaryAndJsonConformanceSuite::TestOneofMessage(MessageType& message, - bool is_proto3) { - message.set_oneof_uint32(0); - RunValidProtobufTestWithMessage("OneofZeroUint32", RECOMMENDED, &message, - "oneof_uint32: 0", is_proto3); - message.mutable_oneof_nested_message()->set_a(0); - RunValidProtobufTestWithMessage( - "OneofZeroMessage", RECOMMENDED, &message, - is_proto3 ? "oneof_nested_message: {}" : "oneof_nested_message: {a: 0}", - is_proto3); - message.mutable_oneof_nested_message()->set_a(1); - RunValidProtobufTestWithMessage("OneofZeroMessageSetTwice", RECOMMENDED, - &message, "oneof_nested_message: {a: 1}", - is_proto3); - message.set_oneof_string(""); - RunValidProtobufTestWithMessage("OneofZeroString", RECOMMENDED, &message, - "oneof_string: \"\"", is_proto3); - message.set_oneof_bytes(""); - RunValidProtobufTestWithMessage("OneofZeroBytes", RECOMMENDED, &message, - "oneof_bytes: \"\"", is_proto3); - message.set_oneof_bool(false); - RunValidProtobufTestWithMessage("OneofZeroBool", RECOMMENDED, &message, - "oneof_bool: false", is_proto3); - message.set_oneof_uint64(0); - RunValidProtobufTestWithMessage("OneofZeroUint64", RECOMMENDED, &message, - "oneof_uint64: 0", is_proto3); - message.set_oneof_float(0.0f); - RunValidProtobufTestWithMessage("OneofZeroFloat", RECOMMENDED, &message, - "oneof_float: 0", is_proto3); - message.set_oneof_double(0.0); - RunValidProtobufTestWithMessage("OneofZeroDouble", RECOMMENDED, &message, - "oneof_double: 0", is_proto3); - message.set_oneof_enum(MessageType::FOO); - RunValidProtobufTestWithMessage("OneofZeroEnum", RECOMMENDED, &message, - "oneof_enum: FOO", is_proto3); -} - -template -void BinaryAndJsonConformanceSuite::TestUnknownMessage(MessageType& message, - bool is_proto3) { - message.ParseFromString("\xA8\x1F\x01"); - RunValidBinaryProtobufTest("UnknownVarint", REQUIRED, - message.SerializeAsString(), is_proto3); -} - -void BinaryAndJsonConformanceSuite:: - TestBinaryPerformanceForAlternatingUnknownFields() { - string unknown_field_1 = absl::StrCat( - tag(UNKNOWN_FIELD, WireFormatLite::WIRETYPE_VARINT), varint(1234)); - string unknown_field_2 = absl::StrCat( - tag(UNKNOWN_FIELD + 1, WireFormatLite::WIRETYPE_VARINT), varint(5678)); - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { + +template +void BinaryAndJsonConformanceSuiteImpl::TestOneofMessage() { + MessageType message; + message.set_oneof_uint32(0); + RunValidProtobufTestWithMessage("OneofZeroUint32", RECOMMENDED, &message, + "oneof_uint32: 0"); + message.mutable_oneof_nested_message()->set_a(0); + RunValidProtobufTestWithMessage("OneofZeroMessage", RECOMMENDED, &message, + run_proto3_tests_ + ? "oneof_nested_message: {}" + : "oneof_nested_message: {a: 0}"); + message.mutable_oneof_nested_message()->set_a(1); + RunValidProtobufTestWithMessage("OneofZeroMessageSetTwice", RECOMMENDED, + &message, "oneof_nested_message: {a: 1}"); + message.set_oneof_string(""); + RunValidProtobufTestWithMessage("OneofZeroString", RECOMMENDED, &message, + "oneof_string: \"\""); + message.set_oneof_bytes(""); + RunValidProtobufTestWithMessage("OneofZeroBytes", RECOMMENDED, &message, + "oneof_bytes: \"\""); + message.set_oneof_bool(false); + RunValidProtobufTestWithMessage("OneofZeroBool", RECOMMENDED, &message, + "oneof_bool: false"); + message.set_oneof_uint64(0); + RunValidProtobufTestWithMessage("OneofZeroUint64", RECOMMENDED, &message, + "oneof_uint64: 0"); + message.set_oneof_float(0.0f); + RunValidProtobufTestWithMessage("OneofZeroFloat", RECOMMENDED, &message, + "oneof_float: 0"); + message.set_oneof_double(0.0); + RunValidProtobufTestWithMessage("OneofZeroDouble", RECOMMENDED, &message, + "oneof_double: 0"); + message.set_oneof_enum(MessageType::FOO); + RunValidProtobufTestWithMessage("OneofZeroEnum", RECOMMENDED, &message, + "oneof_enum: FOO"); +} + +template +void BinaryAndJsonConformanceSuiteImpl::TestUnknownMessage() { + MessageType message; + message.ParseFromString("\xA8\x1F\x01"); + RunValidBinaryProtobufTest("UnknownVarint", REQUIRED, + message.SerializeAsString()); +} + +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::TestBinaryPerformanceForAlternatingUnknownFields() { + string unknown_field_1 = absl::StrCat( + tag(UNKNOWN_FIELD, WireFormatLite::WIRETYPE_VARINT), varint(1234)); + string unknown_field_2 = absl::StrCat( + tag(UNKNOWN_FIELD + 1, WireFormatLite::WIRETYPE_VARINT), varint(5678)); string proto; for (size_t i = 0; i < kPerformanceRepeatCount; i++) { proto.append(unknown_field_1); @@ -1349,19 +1278,16 @@ void BinaryAndJsonConformanceSuite:: } RunValidBinaryProtobufTest( - "TestBinaryPerformanceForAlternatingUnknownFields", RECOMMENDED, proto, - is_proto3); - } + "TestBinaryPerformanceForAlternatingUnknownFields", RECOMMENDED, proto); } -void BinaryAndJsonConformanceSuite:: +template +void BinaryAndJsonConformanceSuiteImpl:: TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( FieldDescriptor::Type type) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { - int field_number = - GetFieldForType(type, true, is_proto3, Packed::kFalse)->number(); + const string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + int field_number = GetFieldForType(type, true, Packed::kFalse)->number(); string rep_field_proto = absl::StrCat( tag(field_number, WireFormatLite::WireTypeForFieldType( static_cast(type))), @@ -1371,51 +1297,40 @@ void BinaryAndJsonConformanceSuite:: absl::StrCat( "TestBinaryPerformanceMergeMessageWithRepeatedFieldForType", type_name), - rep_field_proto, is_proto3); - } + rep_field_proto); } -void BinaryAndJsonConformanceSuite:: +template +void BinaryAndJsonConformanceSuiteImpl:: TestBinaryPerformanceMergeMessageWithUnknownFieldForType( FieldDescriptor::Type type) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - string unknown_field_proto = absl::StrCat( - tag(UNKNOWN_FIELD, WireFormatLite::WireTypeForFieldType( - static_cast(type))), - GetNonDefaultValue(type)); - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { + const string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + string unknown_field_proto = absl::StrCat( + tag(UNKNOWN_FIELD, WireFormatLite::WireTypeForFieldType( + static_cast(type))), + GetNonDefaultValue(type)); RunBinaryPerformanceMergeMessageWithField( absl::StrCat("TestBinaryPerformanceMergeMessageWithUnknownFieldForType", type_name), - unknown_field_proto, is_proto3); - } + unknown_field_proto); } -void BinaryAndJsonConformanceSuite::RunSuiteImpl() { - // Hack to get the list of test failures based on whether - // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER is enabled or not. - conformance::FailureSet failure_set; - ConformanceRequest req; - ConformanceResponse res; - req.set_message_type(failure_set.GetTypeName()); - req.set_protobuf_payload(""); - req.set_requested_output_format(conformance::WireFormat::PROTOBUF); - RunTest("FindFailures", req, &res); - ABSL_CHECK(failure_set.MergeFromString(res.protobuf_payload())); - for (const string& failure : failure_set.failure()) { - AddExpectedFailedTest(failure); - } - - type_resolver_.reset(NewTypeResolverForDescriptorPool( - kTypeUrlPrefix, DescriptorPool::generated_pool())); - type_url_ = GetTypeUrl(TestAllTypesProto3::descriptor()); +template +BinaryAndJsonConformanceSuiteImpl:: + BinaryAndJsonConformanceSuiteImpl(BinaryAndJsonConformanceSuite* suite, + bool run_proto3_tests) + : suite_(*ABSL_DIE_IF_NULL(suite)), run_proto3_tests_(run_proto3_tests) { + RunAllTests(); +} - if (!performance_) { - for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) { +template +void BinaryAndJsonConformanceSuiteImpl::RunAllTests() { + if (!suite_.performance_) { + for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) { if (i == FieldDescriptor::TYPE_GROUP) continue; TestPrematureEOFForType(static_cast(i)); - } + } TestIllegalTags(); @@ -1630,86 +1545,84 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() { // TestValidDataForType(FieldDescriptor::TYPE_GROUP // Unknown fields. - { - TestAllTypesProto3 messageProto3; - TestAllTypesProto2 messageProto2; - // TODO: update this behavior when unknown field's behavior - // changed in open source. Also delete - // Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput - // from failure list of python_cpp python java - TestUnknownMessage(messageProto3, true); - TestUnknownMessage(messageProto2, false); - } + // TODO: update this behavior when unknown field's behavior + // changed in open source. Also delete + // Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput + // from failure list of python_cpp python java + TestUnknownMessage(); + TestOneofMessage(); RunJsonTests(); - } + } // Flag control performance tests to keep them internal and opt-in only - if (performance_) { + if (suite_.performance_) { RunBinaryPerformanceTests(); RunJsonPerformanceTests(); - } + } +} + +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunBinaryPerformanceTests() { + TestBinaryPerformanceForAlternatingUnknownFields(); + + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_BOOL); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_DOUBLE); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_FLOAT); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_UINT32); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_UINT64); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_STRING); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_BYTES); + + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_BOOL); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_DOUBLE); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_FLOAT); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_UINT32); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_UINT64); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_STRING); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_BYTES); } -void BinaryAndJsonConformanceSuite::RunBinaryPerformanceTests() { - TestBinaryPerformanceForAlternatingUnknownFields(); - - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_BOOL); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_DOUBLE); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_FLOAT); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_UINT32); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_UINT64); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_STRING); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_BYTES); - - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_BOOL); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_DOUBLE); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_FLOAT); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_UINT32); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_UINT64); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_STRING); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_BYTES); -} - -void BinaryAndJsonConformanceSuite::RunJsonPerformanceTests() { - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_BOOL, "true"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_DOUBLE, "123"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_FLOAT, "123"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_UINT32, "123"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_UINT64, "123"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_STRING, "\"foo\""); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_BYTES, "\"foo\""); +template +void BinaryAndJsonConformanceSuiteImpl::RunJsonPerformanceTests() { + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_BOOL, "true"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_DOUBLE, "123"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_FLOAT, "123"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_UINT32, "123"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_UINT64, "123"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_STRING, "\"foo\""); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_BYTES, "\"foo\""); } // This is currently considered valid input by some languages but not others -void BinaryAndJsonConformanceSuite:: +template +void BinaryAndJsonConformanceSuiteImpl:: TestJsonPerformanceMergeMessageWithRepeatedFieldForType( FieldDescriptor::Type type, string field_value) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) { - const FieldDescriptor* field = - GetFieldForType(type, true, is_proto3, Packed::kFalse); + const string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + const FieldDescriptor* field = GetFieldForType(type, true, Packed::kFalse); string field_name = field->name(); string message_field = @@ -1718,7 +1631,7 @@ void BinaryAndJsonConformanceSuite:: absl::StrCat("\"recursive_message\": { ", message_field, "}"); string input = absl::StrCat("{", recursive_message); for (size_t i = 1; i < kPerformanceRepeatCount; i++) { - absl::StrAppend(&input, ",", recursive_message); + absl::StrAppend(&input, ",", recursive_message); } absl::StrAppend(&input, "}"); @@ -1726,80 +1639,100 @@ void BinaryAndJsonConformanceSuite:: absl::StrCat(field_name, ": ", field_value); string expected_textproto = "recursive_message { "; for (size_t i = 0; i < kPerformanceRepeatCount; i++) { - absl::StrAppend(&expected_textproto, textproto_message_field, " "); + absl::StrAppend(&expected_textproto, textproto_message_field, " "); } absl::StrAppend(&expected_textproto, "}"); RunValidJsonTest( absl::StrCat("TestJsonPerformanceMergeMessageWithRepeatedFieldForType", type_name), - RECOMMENDED, input, expected_textproto, is_proto3); - } + RECOMMENDED, input, expected_textproto); } -void BinaryAndJsonConformanceSuite::RunJsonTests() { - RunValidJsonTest("HelloWorld", REQUIRED, - "{\"optionalString\":\"Hello, World!\"}", - "optional_string: 'Hello, World!'"); - - // NOTE: The spec for JSON support is still being sorted out, these may not - // all be correct. - - RunJsonTestsForFieldNameConvention(); - RunJsonTestsForNonRepeatedTypes(); - RunJsonTestsForRepeatedTypes(); - RunJsonTestsForNullTypes(); - RunJsonTestsForWrapperTypes(); - RunJsonTestsForFieldMask(); - RunJsonTestsForStruct(); - RunJsonTestsForValue(); - RunJsonTestsForAny(); - RunJsonTestsForUnknownEnumStringValues(); - - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNumber", REQUIRED, - R"({ +template +void BinaryAndJsonConformanceSuiteImpl::RunJsonTests() { + if (!run_proto3_tests_) { + RunValidJsonTestWithValidator( + "StoresDefaultPrimitive", REQUIRED, + R"({ + "FieldName13": 0 + })", + [](const Json::Value& value) { return value.isMember("FieldName13"); }); + RunValidJsonTestWithValidator( + "FieldNameExtension", RECOMMENDED, + R"({ + "[protobuf_test_messages.proto2.extension_int32]": 1 + })", + [](const Json::Value& value) { + return value.isMember( + "[protobuf_test_messages.proto2.extension_int32]"); + }); + return; + } + RunValidJsonTest("HelloWorld", REQUIRED, + "{\"optionalString\":\"Hello, World!\"}", + "optional_string: 'Hello, World!'"); + + // NOTE: The spec for JSON support is still being sorted out, these may not + // all be correct. + + RunJsonTestsForFieldNameConvention(); + RunJsonTestsForNonRepeatedTypes(); + RunJsonTestsForRepeatedTypes(); + RunJsonTestsForNullTypes(); + RunJsonTestsForWrapperTypes(); + RunJsonTestsForFieldMask(); + RunJsonTestsForStruct(); + RunJsonTestsForValue(); + RunJsonTestsForAny(); + RunJsonTestsForUnknownEnumStringValues(); + + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNumber", REQUIRED, + R"({ "unknown": 1 })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonString", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonString", REQUIRED, + R"({ "unknown": "a" })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonTrue", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonTrue", REQUIRED, + R"({ "unknown": true })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonFalse", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonFalse", REQUIRED, + R"({ "unknown": false })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNull", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNull", REQUIRED, + R"({ "unknown": null })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonObject", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonObject", REQUIRED, + R"({ "unknown": {"a": 1} })", - ""); + ""); - ExpectParseFailureForJson("RejectTopLevelNull", REQUIRED, "null"); + ExpectParseFailureForJson("RejectTopLevelNull", REQUIRED, "null"); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForUnknownEnumStringValues() { - // Tests the handling of unknown enum values when encoded as string labels. - // The expected behavior depends on whether unknown fields are ignored: - // * when ignored, the parser should ignore the unknown enum string value. - // * when not ignored, the parser should fail. - struct TestCase { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunJsonTestsForUnknownEnumStringValues() { + // Tests the handling of unknown enum values when encoded as string labels. + // The expected behavior depends on whether unknown fields are ignored: + // * when ignored, the parser should ignore the unknown enum string value. + // * when not ignored, the parser should fail. + struct TestCase { // Used in the test name. string enum_location; // JSON input which will contain the unknown field. string input_json; - }; + }; const std::vector test_cases = { {"InOptionalField", R"json({ "optional_nested_enum": "UNKNOWN_ENUM_VALUE" @@ -1824,7 +1757,9 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForUnknownEnumStringValues() { } } -void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunJsonTestsForFieldNameConvention() { RunValidJsonTest("FieldNameInSnakeCase", REQUIRED, R"({ "fieldname1": 1, @@ -1998,29 +1933,28 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { "optional_nested_message": {} })"); // Serializers should use lowerCamelCase by default. - RunValidJsonTestWithValidator( - "FieldNameInLowerCamelCase", REQUIRED, - R"({ + RunValidJsonTestWithValidator("FieldNameInLowerCamelCase", REQUIRED, + R"({ "fieldname1": 1, "fieldName2": 2, "FieldName3": 3, "fieldName4": 4 })", - [](const Json::Value& value) { - return value.isMember("fieldname1") && value.isMember("fieldName2") && - value.isMember("FieldName3") && value.isMember("fieldName4"); - }, - true); - RunValidJsonTestWithValidator( - "FieldNameWithNumbers", REQUIRED, - R"({ + [](const Json::Value& value) { + return value.isMember("fieldname1") && + value.isMember("fieldName2") && + value.isMember("FieldName3") && + value.isMember("fieldName4"); + }); + RunValidJsonTestWithValidator("FieldNameWithNumbers", REQUIRED, + R"({ "field0name5": 5, "field0Name6": 6 })", - [](const Json::Value& value) { - return value.isMember("field0name5") && value.isMember("field0Name6"); - }, - true); + [](const Json::Value& value) { + return value.isMember("field0name5") && + value.isMember("field0Name6"); + }); RunValidJsonTestWithValidator( "FieldNameWithMixedCases", REQUIRED, R"({ @@ -2035,8 +1969,7 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { return value.isMember("fieldName7") && value.isMember("FieldName8") && value.isMember("fieldName9") && value.isMember("FieldName10") && value.isMember("FIELDNAME11") && value.isMember("FIELDName12"); - }, - true); + }); RunValidJsonTestWithValidator( "FieldNameWithDoubleUnderscores", RECOMMENDED, R"({ @@ -2051,35 +1984,18 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { return value.isMember("FieldName13") && value.isMember("FieldName14") && value.isMember("fieldName15") && value.isMember("fieldName16") && value.isMember("fieldName17") && value.isMember("FieldName18"); - }, - true); - RunValidJsonTestWithValidator( - "StoresDefaultPrimitive", REQUIRED, - R"({ - "FieldName13": 0 - })", - [](const Json::Value& value) { return value.isMember("FieldName13"); }, - false); + }); RunValidJsonTestWithValidator( "SkipsDefaultPrimitive", REQUIRED, R"({ "FieldName13": 0 })", - [](const Json::Value& value) { return !value.isMember("FieldName13"); }, - true); - RunValidJsonTestWithValidator( - "FieldNameExtension", RECOMMENDED, - R"({ - "[protobuf_test_messages.proto2.extension_int32]": 1 - })", - [](const Json::Value& value) { - return value.isMember( - "[protobuf_test_messages.proto2.extension_int32]"); - }, - false); + [](const Json::Value& value) { return !value.isMember("FieldName13"); }); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunJsonTestsForNonRepeatedTypes() { // Integer fields. RunValidJsonTest("Int32FieldMaxValue", REQUIRED, R"({"optionalInt32": 2147483647})", @@ -2193,15 +2109,13 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { [](const Json::Value& value) { return value["optionalInt64"].type() == Json::stringValue && value["optionalInt64"].asString() == "1"; - }, - true); + }); RunValidJsonTestWithValidator( "Uint64FieldBeString", RECOMMENDED, R"({"optionalUint64": 1})", [](const Json::Value& value) { return value["optionalUint64"].type() == Json::stringValue && value["optionalUint64"].asString() == "1"; - }, - true); + }); // Bool fields. RunValidJsonTest("BoolFieldTrue", REQUIRED, R"({"optionalBool":true})", @@ -2360,8 +2274,7 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { [](const Json::Value& value) { return value["optionalNestedEnum"].type() == Json::intValue && value["optionalNestedEnum"].asInt() == 123; - }, - true); + }); // String fields. RunValidJsonTest("StringField", REQUIRED, @@ -2425,11 +2338,6 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { RunValidJsonTest("OneofFieldNullSecond", REQUIRED, R"({"oneofString": "test", "oneofUint32": null})", "oneof_string: \"test\""); - // Ensure zero values for oneof make it out/backs. - TestAllTypesProto3 messageProto3; - TestAllTypesProto2 messageProto2; - TestOneofMessage(messageProto3, true); - TestOneofMessage(messageProto2, false); RunValidJsonTest("OneofZeroUint32", RECOMMENDED, R"({"oneofUint32": 0})", "oneof_uint32: 0"); RunValidJsonTest("OneofZeroMessage", RECOMMENDED, @@ -2518,7 +2426,9 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { R"({'optionalString': 'Hello world!'})"); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForRepeatedTypes() { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunJsonTestsForRepeatedTypes() { // Repeated fields. RunValidJsonTest("PrimitiveRepeatedField", REQUIRED, R"({"repeatedInt32": [1, 2, 3, 4]})", @@ -2578,7 +2488,9 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForRepeatedTypes() { "{\"repeatedInt32\": [\n 1,\n 2,\n 3,\n 4,\n]}"); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForNullTypes() { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunJsonTestsForNullTypes() { // "null" is accepted for all fields types. RunValidJsonTest("AllFieldAcceptNull", REQUIRED, R"({ @@ -2636,7 +2548,9 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNullTypes() { R"({"mapInt32Int32": {"0": null}})"); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForWrapperTypes() { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunJsonTestsForWrapperTypes() { RunValidJsonTest("OptionalBoolWrapper", REQUIRED, R"({"optionalBoolWrapper": false})", "optional_bool_wrapper: {value: false}"); @@ -2789,32 +2703,24 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForWrapperTypes() { RunValidJsonTestWithValidator( "DurationHasZeroFractionalDigit", RECOMMENDED, - R"({"optionalDuration": "1.000000000s"})", - [](const Json::Value& value) { + R"({"optionalDuration": "1.000000000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1s"; - }, - true); + }); RunValidJsonTestWithValidator( "DurationHas3FractionalDigits", RECOMMENDED, - R"({"optionalDuration": "1.010000000s"})", - [](const Json::Value& value) { + R"({"optionalDuration": "1.010000000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.010s"; - }, - true); + }); RunValidJsonTestWithValidator( "DurationHas6FractionalDigits", RECOMMENDED, - R"({"optionalDuration": "1.000010000s"})", - [](const Json::Value& value) { + R"({"optionalDuration": "1.000010000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.000010s"; - }, - true); + }); RunValidJsonTestWithValidator( "DurationHas9FractionalDigits", RECOMMENDED, - R"({"optionalDuration": "1.000000010s"})", - [](const Json::Value& value) { + R"({"optionalDuration": "1.000000010s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.000000010s"; - }, - true); + }); // Timestamp RunValidJsonTest("TimestampMinValue", REQUIRED, @@ -2868,42 +2774,39 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForWrapperTypes() { R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00Z"; - }, - true); + }); RunValidJsonTestWithValidator( "TimestampHasZeroFractionalDigit", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00Z"; - }, - true); + }); RunValidJsonTestWithValidator( "TimestampHas3FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.010Z"; - }, - true); + }); RunValidJsonTestWithValidator( "TimestampHas6FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.000010Z"; - }, - true); + }); RunValidJsonTestWithValidator( "TimestampHas9FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.000000010Z"; - }, - true); + }); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldMask() { +template +void BinaryAndJsonConformanceSuiteImpl< + MessageType>::RunJsonTestsForFieldMask() { RunValidJsonTest("FieldMask", REQUIRED, R"({"optionalFieldMask": "foo,barBaz"})", R"(optional_field_mask: {paths: "foo" paths: "bar_baz"})"); @@ -2919,7 +2822,8 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldMask() { R"(optional_field_mask: {paths: "foo__bar"})"); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForStruct() { +template +void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForStruct() { RunValidJsonTest("Struct", REQUIRED, R"({ "optionalStruct": { @@ -3003,7 +2907,8 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForStruct() { )"); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForValue() { +template +void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForValue() { RunValidJsonTest("ValueAcceptInteger", REQUIRED, R"({"optionalValue": 1})", "optional_value: { number_value: 1}"); RunValidJsonTest("ValueAcceptFloat", REQUIRED, R"({"optionalValue": 1.5})", @@ -3073,30 +2978,27 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForValue() { )"); RunValidJsonTestWithValidator( "NullValueInOtherOneofOldFormat", RECOMMENDED, - R"({"oneofNullValue": "NULL_VALUE"})", - [](const Json::Value& value) { + R"({"oneofNullValue": "NULL_VALUE"})", [](const Json::Value& value) { return (value.isMember("oneofNullValue") && value["oneofNullValue"].isNull()); - }, - true); + }); RunValidJsonTestWithValidator( "NullValueInOtherOneofNewFormat", RECOMMENDED, - R"({"oneofNullValue": null})", - [](const Json::Value& value) { + R"({"oneofNullValue": null})", [](const Json::Value& value) { return (value.isMember("oneofNullValue") && value["oneofNullValue"].isNull()); - }, - true); + }); RunValidJsonTestWithValidator( "NullValueInNormalMessage", RECOMMENDED, R"({"optionalNullValue": null})", - [](const Json::Value& value) { return value.empty(); }, true); + [](const Json::Value& value) { return value.empty(); }); ExpectSerializeFailureForJson("ValueRejectNanNumberValue", RECOMMENDED, "optional_value: { number_value: nan}"); ExpectSerializeFailureForJson("ValueRejectInfNumberValue", RECOMMENDED, "optional_value: { number_value: inf}"); } -void BinaryAndJsonConformanceSuite::RunJsonTestsForAny() { +template +void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForAny() { RunValidJsonTest("Any", REQUIRED, R"({ "optionalAny": { @@ -3264,5 +3166,88 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForAny() { )"); } +template +const FieldDescriptor* +BinaryAndJsonConformanceSuiteImpl::GetFieldForType( + FieldDescriptor::Type type, bool repeated, Packed packed) const { + const Descriptor* d = MessageType::GetDescriptor(); + for (int i = 0; i < d->field_count(); i++) { + const FieldDescriptor* f = d->field(i); + if (f->type() == type && f->is_repeated() == repeated) { + if ((packed == Packed::kTrue && !f->is_packed()) || + (packed == Packed::kFalse && f->is_packed())) { + continue; + } + return f; + } + } + + absl::string_view packed_string = ""; + const absl::string_view repeated_string = + repeated ? "Repeated " : "Singular "; + if (packed == Packed::kTrue) { + packed_string = "Packed "; + } + if (packed == Packed::kFalse) { + packed_string = "Unpacked "; + } + ABSL_LOG(FATAL) << "Couldn't find field with type: " << repeated_string + << packed_string << FieldDescriptor::TypeName(type) << " for " + << SyntaxIdentifier(); + return nullptr; +} + +template +const FieldDescriptor* +BinaryAndJsonConformanceSuiteImpl::GetFieldForMapType( + FieldDescriptor::Type key_type, FieldDescriptor::Type value_type) const { + const Descriptor* d = MessageType::GetDescriptor(); + for (int i = 0; i < d->field_count(); i++) { + const FieldDescriptor* f = d->field(i); + if (f->is_map()) { + const Descriptor* map_entry = f->message_type(); + const FieldDescriptor* key = map_entry->field(0); + const FieldDescriptor* value = map_entry->field(1); + if (key->type() == key_type && value->type() == value_type) { + return f; + } + } + } + + ABSL_LOG(FATAL) << "Couldn't find map field with type: " + << FieldDescriptor::TypeName(key_type) << " and " + << FieldDescriptor::TypeName(key_type) << " for " + << SyntaxIdentifier(); + return nullptr; +} + +template +const FieldDescriptor* +BinaryAndJsonConformanceSuiteImpl::GetFieldForOneofType( + FieldDescriptor::Type type, bool exclusive) const { + const Descriptor* d = MessageType::GetDescriptor(); + for (int i = 0; i < d->field_count(); i++) { + const FieldDescriptor* f = d->field(i); + if (f->containing_oneof() && ((f->type() == type) ^ exclusive)) { + return f; + } + } + + ABSL_LOG(FATAL) << "Couldn't find oneof field with type: " + << FieldDescriptor::TypeName(type) << " for " + << SyntaxIdentifier(); + return nullptr; +} + +template +std::string BinaryAndJsonConformanceSuiteImpl::SyntaxIdentifier() + const { + if constexpr (std::is_same::value) { + return "Proto2"; + } else { + return "Proto3"; + } +} + } // namespace protobuf } // namespace google diff --git a/conformance/binary_json_conformance_suite.h b/conformance/binary_json_conformance_suite.h index be9579c5fb..452e672802 100644 --- a/conformance/binary_json_conformance_suite.h +++ b/conformance/binary_json_conformance_suite.h @@ -8,19 +8,53 @@ #ifndef CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H #define CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H +#include +#include +#include +#include + #include "json/json.h" #include "conformance_test.h" #include "google/protobuf/descriptor.h" +#include "google/protobuf/util/type_resolver.h" namespace google { namespace protobuf { class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { public: - BinaryAndJsonConformanceSuite() {} + BinaryAndJsonConformanceSuite() = default; private: void RunSuiteImpl() override; + bool ParseJsonResponse(const conformance::ConformanceResponse& response, + Message* test_message); + bool ParseResponse(const conformance::ConformanceResponse& response, + const ConformanceRequestSetting& setting, + Message* test_message) override; + + template + friend class BinaryAndJsonConformanceSuiteImpl; + + std::unique_ptr type_resolver_; + std::string type_url_; +}; + +template +class BinaryAndJsonConformanceSuiteImpl { + public: + BinaryAndJsonConformanceSuiteImpl(BinaryAndJsonConformanceSuite* suite, + bool run_proto3_tests); + + private: + using ConformanceRequestSetting = + BinaryAndJsonConformanceSuite::ConformanceRequestSetting; + using ConformanceLevel = BinaryAndJsonConformanceSuite::ConformanceLevel; + constexpr static ConformanceLevel RECOMMENDED = ConformanceLevel::RECOMMENDED; + constexpr static ConformanceLevel REQUIRED = ConformanceLevel::REQUIRED; + + void RunAllTests(); + void RunBinaryPerformanceTests(); void RunJsonPerformanceTests(); void RunJsonTests(); @@ -37,10 +71,6 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { void RunValidJsonTest(const std::string& test_name, ConformanceLevel level, const std::string& input_json, const std::string& equivalent_text_format); - void RunValidJsonTest(const std::string& test_name, ConformanceLevel level, - const std::string& input_json, - const std::string& equivalent_text_format, - bool is_proto3); void RunValidJsonTestWithMessage(const std::string& test_name, ConformanceLevel level, const std::string& input_json, @@ -57,38 +87,26 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { void RunValidProtobufTest(const std::string& test_name, ConformanceLevel level, const std::string& input_protobuf, - const std::string& equivalent_text_format, - bool is_proto3); + const std::string& equivalent_text_format); void RunValidBinaryProtobufTest(const std::string& test_name, ConformanceLevel level, - const std::string& input_protobuf, - bool is_proto3); + const std::string& input_protobuf); void RunValidBinaryProtobufTest(const std::string& test_name, ConformanceLevel level, const std::string& input_protobuf, - const std::string& expected_protobuf, - bool is_proto3); - void RunBinaryPerformanceMergeMessageWithField(const std::string& test_name, - const std::string& field_proto, - bool is_proto3); + const std::string& expected_protobuf); + void RunBinaryPerformanceMergeMessageWithField( + const std::string& test_name, const std::string& field_proto); void RunValidProtobufTestWithMessage( const std::string& test_name, ConformanceLevel level, - const Message* input, const std::string& equivalent_text_format, - bool is_proto3); - - bool ParseJsonResponse(const conformance::ConformanceResponse& response, - Message* test_message); - bool ParseResponse(const conformance::ConformanceResponse& response, - const ConformanceRequestSetting& setting, - Message* test_message) override; + const Message* input, const std::string& equivalent_text_format); typedef std::function Validator; void RunValidJsonTestWithValidator(const std::string& test_name, ConformanceLevel level, const std::string& input_json, - const Validator& validator, - bool is_proto3); + const Validator& validator); void ExpectParseFailureForJson(const std::string& test_name, ConformanceLevel level, const std::string& input_json); @@ -97,8 +115,7 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { const std::string& text_format); void ExpectParseFailureForProtoWithProtoVersion(const std::string& proto, const std::string& test_name, - ConformanceLevel level, - bool is_proto3); + ConformanceLevel level); void ExpectParseFailureForProto(const std::string& proto, const std::string& test_name, ConformanceLevel level); @@ -107,10 +124,8 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { ConformanceLevel level); void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type); void TestIllegalTags(); - template - void TestOneofMessage(MessageType& message, bool is_proto3); - template - void TestUnknownMessage(MessageType& message, bool is_proto3); + void TestOneofMessage(); + void TestUnknownMessage(); void TestValidDataForType( google::protobuf::FieldDescriptor::Type, std::vector> values); @@ -128,8 +143,22 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { void TestJsonPerformanceMergeMessageWithRepeatedFieldForType( google::protobuf::FieldDescriptor::Type, std::string field_value); - std::unique_ptr type_resolver_; - std::string type_url_; + enum class Packed { + kUnspecified = 0, + kTrue = 1, + kFalse = 2, + }; + const FieldDescriptor* GetFieldForType( + FieldDescriptor::Type type, bool repeated, + Packed packed = Packed::kUnspecified) const; + const FieldDescriptor* GetFieldForMapType( + FieldDescriptor::Type key_type, FieldDescriptor::Type value_type) const; + const FieldDescriptor* GetFieldForOneofType(FieldDescriptor::Type type, + bool exclusive = false) const; + std::string SyntaxIdentifier() const; + + BinaryAndJsonConformanceSuite& suite_; + bool run_proto3_tests_; }; } // namespace protobuf From cb86ad6d81913e4357e21171f9e301608a5aa09f Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Tue, 17 Oct 2023 16:50:30 -0700 Subject: [PATCH 18/95] Ensure that the range of valid editions is always dense. PiperOrigin-RevId: 574302947 --- src/google/protobuf/descriptor_unittest.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 88bab99985..01dc123a83 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -7217,6 +7217,13 @@ TEST_F(ValidationErrorTest, UnusedImportWithOtherError) { "foo.proto: Foo.foo: EXTENDEE: \"Baz\" is not defined.\n"); } +TEST(EditionsTest, DenseRange) { + for (int i = static_cast(PROTOBUF_MINIMUM_EDITION); + i <= static_cast(PROTOBUF_MAXIMUM_EDITION); ++i) { + EXPECT_TRUE(Edition_IsValid(i)); + } +} + using FeaturesBaseTest = ValidationErrorTest; class FeaturesTest : public FeaturesBaseTest { From 39752aaea33a9bac70ca9bf3bed65bc7c81aecdd Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Tue, 17 Oct 2023 16:58:29 -0700 Subject: [PATCH 19/95] Clean up conformance tests warnings and formatting. PiperOrigin-RevId: 574304654 --- conformance/binary_json_conformance_suite.cc | 1347 +++++++++--------- conformance/binary_json_conformance_suite.h | 1 + conformance/conformance_test.cc | 64 +- conformance/conformance_test.h | 10 +- conformance/text_format_conformance_suite.cc | 53 +- conformance/text_format_conformance_suite.h | 3 + 6 files changed, 751 insertions(+), 727 deletions(-) diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index 81ee1a4970..d063c1270b 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -7,24 +7,28 @@ #include "binary_json_conformance_suite.h" +#include +#include +#include #include +#include #include #include #include #include #include -#include "google/protobuf/util/json_util.h" -#include "google/protobuf/util/type_resolver_util.h" #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/log/die_if_null.h" #include "absl/status/status.h" #include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" #include "json/json.h" #include "conformance/conformance.pb.h" #include "conformance_test.h" #include "google/protobuf/endian.h" +#include "google/protobuf/json/json.h" #include "google/protobuf/test_messages_proto2.pb.h" #include "google/protobuf/test_messages_proto2.pb.h" #include "google/protobuf/test_messages_proto3.pb.h" @@ -43,7 +47,6 @@ using google::protobuf::internal::little_endian::FromHost; using google::protobuf::util::NewTypeResolverForDescriptorPool; using protobuf_test_messages::proto2::TestAllTypesProto2; using protobuf_test_messages::proto3::TestAllTypesProto3; -using std::string; namespace { @@ -53,7 +56,7 @@ constexpr absl::string_view kTypeUrlPrefix = "type.googleapis.com"; // Corresponds approx to 500KB wireformat bytes. const size_t kPerformanceRepeatCount = 50000; -string GetTypeUrl(const Descriptor* message) { +std::string GetTypeUrl(const Descriptor* message) { return absl::StrCat(kTypeUrlPrefix, "/", message->full_name()); } @@ -85,52 +88,56 @@ size_t vencode64(uint64_t val, int over_encoded_bytes, char* buf) { return i; } -string varint(uint64_t x) { +std::string varint(uint64_t x) { char buf[VARINT_MAX_LEN]; size_t len = vencode64(x, 0, buf); - return string(buf, len); + return std::string(buf, len); } // Encodes a varint that is |extra| bytes longer than it needs to be, but still // valid. -string longvarint(uint64_t x, int extra) { +std::string longvarint(uint64_t x, int extra) { char buf[VARINT_MAX_LEN]; size_t len = vencode64(x, extra, buf); - return string(buf, len); + return std::string(buf, len); } -string fixed32(void* data) { +std::string fixed32(void* data) { uint32_t data_le; std::memcpy(&data_le, data, 4); data_le = FromHost(data_le); - return string(reinterpret_cast(&data_le), 4); + return std::string(reinterpret_cast(&data_le), 4); } -string fixed64(void* data) { +std::string fixed64(void* data) { uint64_t data_le; std::memcpy(&data_le, data, 8); data_le = FromHost(data_le); - return string(reinterpret_cast(&data_le), 8); + return std::string(reinterpret_cast(&data_le), 8); } -string delim(const string& buf) { +std::string delim(const std::string& buf) { return absl::StrCat(varint(buf.size()), buf); } -string u32(uint32_t u32) { return fixed32(&u32); } -string u64(uint64_t u64) { return fixed64(&u64); } -string flt(float f) { return fixed32(&f); } -string dbl(double d) { return fixed64(&d); } -string zz32(int32_t x) { return varint(WireFormatLite::ZigZagEncode32(x)); } -string zz64(int64_t x) { return varint(WireFormatLite::ZigZagEncode64(x)); } +std::string u32(uint32_t u32) { return fixed32(&u32); } +std::string u64(uint64_t u64) { return fixed64(&u64); } +std::string flt(float f) { return fixed32(&f); } +std::string dbl(double d) { return fixed64(&d); } +std::string zz32(int32_t x) { + return varint(WireFormatLite::ZigZagEncode32(x)); +} +std::string zz64(int64_t x) { + return varint(WireFormatLite::ZigZagEncode64(x)); +} -string tag(uint32_t fieldnum, char wire_type) { +std::string tag(uint32_t fieldnum, char wire_type) { return varint((fieldnum << 3) | wire_type); } -string tag(int fieldnum, char wire_type) { +std::string tag(int fieldnum, char wire_type) { return tag(static_cast(fieldnum), wire_type); } -string GetDefaultValue(FieldDescriptor::Type type) { +std::string GetDefaultValue(FieldDescriptor::Type type) { switch (type) { case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_INT64: @@ -163,7 +170,7 @@ string GetDefaultValue(FieldDescriptor::Type type) { return ""; } -string GetNonDefaultValue(FieldDescriptor::Type type) { +std::string GetNonDefaultValue(FieldDescriptor::Type type) { switch (type) { case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_INT64: @@ -200,14 +207,15 @@ string GetNonDefaultValue(FieldDescriptor::Type type) { #define UNKNOWN_FIELD 666 -string UpperCase(string str) { +std::string UpperCase(std::string str) { for (size_t i = 0; i < str.size(); i++) { str[i] = toupper(str[i]); } return str; } -bool IsProto3Default(FieldDescriptor::Type type, const string& binary_data) { +bool IsProto3Default(FieldDescriptor::Type type, + const std::string& binary_data) { switch (type) { case FieldDescriptor::TYPE_DOUBLE: return binary_data == dbl(0); @@ -243,10 +251,10 @@ namespace protobuf { bool BinaryAndJsonConformanceSuite::ParseJsonResponse( const ConformanceResponse& response, Message* test_message) { - string binary_protobuf; + std::string binary_protobuf; absl::Status status = - JsonToBinaryString(type_resolver_.get(), type_url_, - response.json_payload(), &binary_protobuf); + json::JsonToBinaryString(type_resolver_.get(), type_url_, + response.json_payload(), &binary_protobuf); if (!status.ok()) { return false; @@ -266,7 +274,7 @@ bool BinaryAndJsonConformanceSuite::ParseResponse( const ConformanceRequestSetting& setting, Message* test_message) { const ConformanceRequest& request = setting.GetRequest(); WireFormat requested_output = request.requested_output_format(); - const string& test_name = setting.GetTestName(); + const std::string& test_name = setting.GetTestName(); ConformanceLevel level = setting.GetLevel(); switch (response.result_case()) { @@ -327,8 +335,8 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() { template void BinaryAndJsonConformanceSuiteImpl:: - ExpectParseFailureForProtoWithProtoVersion(const string& proto, - const string& test_name, + ExpectParseFailureForProtoWithProtoVersion(const std::string& proto, + const std::string& test_name, ConformanceLevel level) { MessageType prototype; // We don't expect output, but if the program erroneously accepts the protobuf @@ -339,7 +347,7 @@ void BinaryAndJsonConformanceSuiteImpl:: const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - string effective_test_name = + std::string effective_test_name = absl::StrCat(setting.ConformanceLevelToString(level), ".", SyntaxIdentifier(), ".ProtobufInput.", test_name); @@ -357,7 +365,8 @@ void BinaryAndJsonConformanceSuiteImpl:: // Expect that this precise protobuf will cause a parse error. template void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForProto( - const string& proto, const string& test_name, ConformanceLevel level) { + const std::string& proto, const std::string& test_name, + ConformanceLevel level) { ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level); } @@ -368,16 +377,16 @@ void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForProto( // TODO: implement the second of these. template void BinaryAndJsonConformanceSuiteImpl< - MessageType>::ExpectHardParseFailureForProto(const string& proto, - const string& test_name, + MessageType>::ExpectHardParseFailureForProto(const std::string& proto, + const std::string& test_name, ConformanceLevel level) { return ExpectParseFailureForProto(proto, test_name, level); } template void BinaryAndJsonConformanceSuiteImpl::RunValidJsonTest( - const string& test_name, ConformanceLevel level, const string& input_json, - const string& equivalent_text_format) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_json, const std::string& equivalent_text_format) { MessageType prototype; RunValidJsonTestWithMessage(test_name, level, input_json, equivalent_text_format, prototype); @@ -385,9 +394,10 @@ void BinaryAndJsonConformanceSuiteImpl::RunValidJsonTest( template void BinaryAndJsonConformanceSuiteImpl:: - RunValidJsonTestWithMessage(const string& test_name, ConformanceLevel level, - const string& input_json, - const string& equivalent_text_format, + RunValidJsonTestWithMessage(const std::string& test_name, + ConformanceLevel level, + const std::string& input_json, + const std::string& equivalent_text_format, const Message& prototype) { ConformanceRequestSetting setting1( level, conformance::JSON, conformance::PROTOBUF, conformance::JSON_TEST, @@ -401,10 +411,10 @@ void BinaryAndJsonConformanceSuiteImpl:: template void BinaryAndJsonConformanceSuiteImpl:: - RunValidJsonTestWithProtobufInput(const string& test_name, - ConformanceLevel level, - const TestAllTypesProto3& input, - const string& equivalent_text_format) { + RunValidJsonTestWithProtobufInput( + const std::string& test_name, ConformanceLevel level, + const TestAllTypesProto3& input, + const std::string& equivalent_text_format) { ConformanceRequestSetting setting( level, conformance::PROTOBUF, conformance::JSON, conformance::JSON_TEST, input, test_name, input.SerializeAsString()); @@ -413,10 +423,10 @@ void BinaryAndJsonConformanceSuiteImpl:: template void BinaryAndJsonConformanceSuiteImpl:: - RunValidJsonIgnoreUnknownTest(const string& test_name, + RunValidJsonIgnoreUnknownTest(const std::string& test_name, ConformanceLevel level, - const string& input_json, - const string& equivalent_text_format) { + const std::string& input_json, + const std::string& equivalent_text_format) { TestAllTypesProto3 prototype; ConformanceRequestSetting setting( level, conformance::JSON, conformance::PROTOBUF, @@ -427,8 +437,9 @@ void BinaryAndJsonConformanceSuiteImpl:: template void BinaryAndJsonConformanceSuiteImpl::RunValidProtobufTest( - const string& test_name, ConformanceLevel level, - const string& input_protobuf, const string& equivalent_text_format) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_protobuf, + const std::string& equivalent_text_format) { MessageType prototype; ConformanceRequestSetting setting1( @@ -446,15 +457,15 @@ void BinaryAndJsonConformanceSuiteImpl::RunValidProtobufTest( template void BinaryAndJsonConformanceSuiteImpl::RunValidBinaryProtobufTest( - const string& test_name, ConformanceLevel level, - const string& input_protobuf) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_protobuf) { RunValidBinaryProtobufTest(test_name, level, input_protobuf, input_protobuf); } template void BinaryAndJsonConformanceSuiteImpl::RunValidBinaryProtobufTest( - const string& test_name, ConformanceLevel level, - const string& input_protobuf, const string& expected_protobuf) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_protobuf, const std::string& expected_protobuf) { MessageType prototype; ConformanceRequestSetting setting( level, conformance::PROTOBUF, conformance::PROTOBUF, @@ -464,21 +475,21 @@ void BinaryAndJsonConformanceSuiteImpl::RunValidBinaryProtobufTest( template void BinaryAndJsonConformanceSuiteImpl:: - RunBinaryPerformanceMergeMessageWithField(const string& test_name, - const string& field_proto) { - string message_tag = tag(27, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - string message_proto = absl::StrCat(message_tag, delim(field_proto)); + RunBinaryPerformanceMergeMessageWithField(const std::string& test_name, + const std::string& field_proto) { + std::string message_tag = tag(27, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + std::string message_proto = absl::StrCat(message_tag, delim(field_proto)); - string proto; + std::string proto; for (size_t i = 0; i < kPerformanceRepeatCount; i++) { proto.append(message_proto); } - string multiple_repeated_field_proto; + std::string multiple_repeated_field_proto; for (size_t i = 0; i < kPerformanceRepeatCount; i++) { multiple_repeated_field_proto.append(field_proto); } - string expected_proto = + std::string expected_proto = absl::StrCat(message_tag, delim(multiple_repeated_field_proto)); RunValidBinaryProtobufTest(test_name, RECOMMENDED, proto, expected_proto); @@ -486,10 +497,10 @@ void BinaryAndJsonConformanceSuiteImpl:: template void BinaryAndJsonConformanceSuiteImpl:: - RunValidProtobufTestWithMessage(const string& test_name, + RunValidProtobufTestWithMessage(const std::string& test_name, ConformanceLevel level, const Message* input, - const string& equivalent_text_format) { + const std::string& equivalent_text_format) { RunValidProtobufTest(test_name, level, input->SerializeAsString(), equivalent_text_format); } @@ -501,9 +512,9 @@ void BinaryAndJsonConformanceSuiteImpl:: template // the JSON output directly. void BinaryAndJsonConformanceSuiteImpl< - MessageType>::RunValidJsonTestWithValidator(const string& test_name, + MessageType>::RunValidJsonTestWithValidator(const std::string& test_name, ConformanceLevel level, - const string& input_json, + const std::string& input_json, const Validator& validator) { MessageType prototype; ConformanceRequestSetting setting(level, conformance::JSON, conformance::JSON, @@ -511,7 +522,7 @@ void BinaryAndJsonConformanceSuiteImpl< test_name, input_json); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - string effective_test_name = + std::string effective_test_name = absl::StrCat(setting.ConformanceLevelToString(level), ".", SyntaxIdentifier(), ".JsonInput.", test_name, ".Validator"); @@ -547,7 +558,8 @@ void BinaryAndJsonConformanceSuiteImpl< template void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForJson( - const string& test_name, ConformanceLevel level, const string& input_json) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_json) { TestAllTypesProto3 prototype; // We don't expect output, but if the program erroneously accepts the protobuf // we let it send its response as this. We must not leave it unspecified. @@ -556,7 +568,7 @@ void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForJson( test_name, input_json); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - string effective_test_name = absl::StrCat( + std::string effective_test_name = absl::StrCat( setting.ConformanceLevelToString(level), ".Proto3.JsonInput.", test_name); suite_.RunTest(effective_test_name, request, &response); @@ -571,10 +583,10 @@ void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForJson( } template -void BinaryAndJsonConformanceSuiteImpl< - MessageType>::ExpectSerializeFailureForJson(const string& test_name, - ConformanceLevel level, - const string& text_format) { +void BinaryAndJsonConformanceSuiteImpl:: + ExpectSerializeFailureForJson(const std::string& test_name, + ConformanceLevel level, + const std::string& text_format) { TestAllTypesProto3 payload_message; ABSL_CHECK(TextFormat::ParseFromString(text_format, &payload_message)) << "Failed to parse: " << text_format; @@ -585,7 +597,7 @@ void BinaryAndJsonConformanceSuiteImpl< prototype, test_name, payload_message.SerializeAsString()); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - string effective_test_name = absl::StrCat( + std::string effective_test_name = absl::StrCat( setting.ConformanceLevelToString(level), ".", test_name, ".JsonOutput"); suite_.RunTest(effective_test_name, request, &response); @@ -617,7 +629,7 @@ void BinaryAndJsonConformanceSuiteImpl::TestPrematureEOFForType( WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( static_cast(type)); absl::string_view incomplete = incompletes[wire_type]; - const string type_name = + const std::string type_name = UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); ExpectParseFailureForProto( @@ -669,7 +681,7 @@ void BinaryAndJsonConformanceSuiteImpl::TestPrematureEOFForType( if (type == FieldDescriptor::TYPE_MESSAGE) { // Submessage ends in the middle of a value. - string incomplete_submsg = absl::StrCat( + std::string incomplete_submsg = absl::StrCat( tag(WireFormatLite::TYPE_INT32, WireFormatLite::WIRETYPE_VARINT), incompletes[WireFormatLite::WIRETYPE_VARINT]); ExpectHardParseFailureForProto( @@ -701,7 +713,7 @@ template void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( FieldDescriptor::Type type, std::vector> values) { - const string type_name = + const std::string type_name = UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( static_cast(type)); @@ -710,16 +722,16 @@ void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( // Test singular data for singular fields. for (size_t i = 0; i < values.size(); i++) { - string proto = + std::string proto = absl::StrCat(tag(field->number(), wire_type), values[i].first); // In proto3, default primitive fields should not be encoded. - string expected_proto = + std::string expected_proto = run_proto3_tests_ && IsProto3Default(field->type(), values[i].second) ? "" : absl::StrCat(tag(field->number(), wire_type), values[i].second); MessageType test_message; test_message.MergeFromString(expected_proto); - string text; + std::string text; TextFormat::PrintToString(test_message, &text); RunValidProtobufTest( @@ -734,15 +746,15 @@ void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( // For scalar message fields, repeated values are merged, which is tested // separately. if (type != FieldDescriptor::TYPE_MESSAGE) { - string proto; + std::string proto; for (size_t i = 0; i < values.size(); i++) { proto += absl::StrCat(tag(field->number(), wire_type), values[i].first); } - string expected_proto = + std::string expected_proto = absl::StrCat(tag(field->number(), wire_type), values.back().second); MessageType test_message; test_message.MergeFromString(expected_proto); - string text; + std::string text; TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("RepeatedScalarSelectsLast", type_name), @@ -756,16 +768,16 @@ void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( const FieldDescriptor* unpacked_field = GetFieldForType(type, true, Packed::kFalse); - string default_proto_packed; - string default_proto_unpacked; - string default_proto_packed_expected; - string default_proto_unpacked_expected; - string packed_proto_packed; - string packed_proto_unpacked; - string packed_proto_expected; - string unpacked_proto_packed; - string unpacked_proto_unpacked; - string unpacked_proto_expected; + std::string default_proto_packed; + std::string default_proto_unpacked; + std::string default_proto_packed_expected; + std::string default_proto_unpacked_expected; + std::string packed_proto_packed; + std::string packed_proto_unpacked; + std::string packed_proto_expected; + std::string unpacked_proto_packed; + std::string unpacked_proto_unpacked; + std::string unpacked_proto_expected; for (size_t i = 0; i < values.size(); i++) { default_proto_unpacked += @@ -803,7 +815,7 @@ void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( MessageType test_message; test_message.MergeFromString(default_proto_packed_expected); - string text; + std::string text; TextFormat::PrintToString(test_message, &text); // Ensures both packed and unpacked data can be parsed. @@ -816,9 +828,9 @@ void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( // proto2 should encode as unpacked by default and proto3 should encode as // packed by default. - string expected_proto = rep_field->is_packed() - ? default_proto_packed_expected - : default_proto_unpacked_expected; + std::string expected_proto = rep_field->is_packed() + ? default_proto_packed_expected + : default_proto_unpacked_expected; RunValidBinaryProtobufTest(absl::StrCat("ValidDataRepeated", type_name, ".UnpackedInput.DefaultOutput"), RECOMMENDED, default_proto_unpacked, @@ -844,8 +856,8 @@ void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( RECOMMENDED, unpacked_proto_packed, unpacked_proto_expected); } else { - string proto; - string expected_proto; + std::string proto; + std::string expected_proto; for (size_t i = 0; i < values.size(); i++) { proto += absl::StrCat(tag(rep_field->number(), wire_type), values[i].first); @@ -854,7 +866,7 @@ void BinaryAndJsonConformanceSuiteImpl::TestValidDataForType( } MessageType test_message; test_message.MergeFromString(expected_proto); - string text; + std::string text; TextFormat::PrintToString(test_message, &text); RunValidProtobufTest(absl::StrCat("ValidDataRepeated", type_name), REQUIRED, @@ -887,433 +899,430 @@ void BinaryAndJsonConformanceSuiteImpl< optional_int64: 1234, optional_uint32: 4321, repeated_int32: [1234, 4321], - } + } })"; - string proto; - const FieldDescriptor* field = - GetFieldForType(FieldDescriptor::TYPE_MESSAGE, false); - for (size_t i = 0; i < values.size(); i++) { - proto += absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - values[i]); - } + std::string proto; + const FieldDescriptor* field = + GetFieldForType(FieldDescriptor::TYPE_MESSAGE, false); + for (size_t i = 0; i < values.size(); i++) { + proto += absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + values[i]); + } - RunValidProtobufTest("RepeatedScalarMessageMerge", REQUIRED, proto, - absl::StrCat(field->name(), ": ", expected)); + RunValidProtobufTest("RepeatedScalarMessageMerge", REQUIRED, proto, + absl::StrCat(field->name(), ": ", expected)); } template void BinaryAndJsonConformanceSuiteImpl::TestValidDataForMapType( FieldDescriptor::Type key_type, FieldDescriptor::Type value_type) { - const string key_type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(key_type))); - const string value_type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(value_type))); - WireFormatLite::WireType key_wire_type = - WireFormatLite::WireTypeForFieldType( - static_cast(key_type)); - WireFormatLite::WireType value_wire_type = - WireFormatLite::WireTypeForFieldType( - static_cast(value_type)); - - string key1_data = - absl::StrCat(tag(1, key_wire_type), GetDefaultValue(key_type)); - string value1_data = - absl::StrCat(tag(2, value_wire_type), GetDefaultValue(value_type)); - string key2_data = - absl::StrCat(tag(1, key_wire_type), GetNonDefaultValue(key_type)); - string value2_data = - absl::StrCat(tag(2, value_wire_type), GetNonDefaultValue(value_type)); - - const FieldDescriptor* field = GetFieldForMapType(key_type, value_type); - - { - // Tests map with default key and value. - string proto = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(key1_data, value1_data))); - MessageType test_message; - test_message.MergeFromString(proto); - string text; - TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, - value_type_name, ".Default"), - REQUIRED, proto, text); - } + const std::string key_type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(key_type))); + const std::string value_type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(value_type))); + WireFormatLite::WireType key_wire_type = WireFormatLite::WireTypeForFieldType( + static_cast(key_type)); + WireFormatLite::WireType value_wire_type = + WireFormatLite::WireTypeForFieldType( + static_cast(value_type)); + + std::string key1_data = + absl::StrCat(tag(1, key_wire_type), GetDefaultValue(key_type)); + std::string value1_data = + absl::StrCat(tag(2, value_wire_type), GetDefaultValue(value_type)); + std::string key2_data = + absl::StrCat(tag(1, key_wire_type), GetNonDefaultValue(key_type)); + std::string value2_data = + absl::StrCat(tag(2, value_wire_type), GetNonDefaultValue(value_type)); + + const FieldDescriptor* field = GetFieldForMapType(key_type, value_type); - { - // Tests map with missing default key and value. - string proto = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim("")); - MessageType test_message; - test_message.MergeFromString(proto); - string text; - TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, - value_type_name, ".MissingDefault"), - REQUIRED, proto, text); - } + { + // Tests map with default key and value. + std::string proto = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(key1_data, value1_data))); + MessageType test_message; + test_message.MergeFromString(proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, + value_type_name, ".Default"), + REQUIRED, proto, text); + } - { - // Tests map with non-default key and value. - string proto = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(key2_data, value2_data))); - MessageType test_message; - test_message.MergeFromString(proto); - string text; - TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, - value_type_name, ".NonDefault"), - REQUIRED, proto, text); - } + { + // Tests map with missing default key and value. + std::string proto = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim("")); + MessageType test_message; + test_message.MergeFromString(proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, + value_type_name, ".MissingDefault"), + REQUIRED, proto, text); + } - { - // Tests map with unordered key and value. - string proto = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(value2_data, key2_data))); - MessageType test_message; - test_message.MergeFromString(proto); - string text; - TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, - value_type_name, ".Unordered"), - REQUIRED, proto, text); - } + { + // Tests map with non-default key and value. + std::string proto = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(key2_data, value2_data))); + MessageType test_message; + test_message.MergeFromString(proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, + value_type_name, ".NonDefault"), + REQUIRED, proto, text); + } - { - // Tests map with duplicate key. - string proto1 = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(key2_data, value1_data))); - string proto2 = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(key2_data, value2_data))); - string proto = absl::StrCat(proto1, proto2); - MessageType test_message; - test_message.MergeFromString(proto2); - string text; - TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, - value_type_name, ".DuplicateKey"), - REQUIRED, proto, text); - } + { + // Tests map with unordered key and value. + std::string proto = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(value2_data, key2_data))); + MessageType test_message; + test_message.MergeFromString(proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, + value_type_name, ".Unordered"), + REQUIRED, proto, text); + } - { - // Tests map with duplicate key in map entry. - string proto = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(key1_data, key2_data, value2_data))); - MessageType test_message; - test_message.MergeFromString(proto); - string text; - TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest( - absl::StrCat("ValidDataMap", key_type_name, value_type_name, - ".DuplicateKeyInMapEntry"), - REQUIRED, proto, text); - } + { + // Tests map with duplicate key. + std::string proto1 = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(key2_data, value1_data))); + std::string proto2 = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(key2_data, value2_data))); + std::string proto = absl::StrCat(proto1, proto2); + MessageType test_message; + test_message.MergeFromString(proto2); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, + value_type_name, ".DuplicateKey"), + REQUIRED, proto, text); + } - { - // Tests map with duplicate value in map entry. - string proto = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(key2_data, value1_data, value2_data))); - MessageType test_message; - test_message.MergeFromString(proto); - string text; - TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest( - absl::StrCat("ValidDataMap", key_type_name, value_type_name, - ".DuplicateValueInMapEntry"), - REQUIRED, proto, text); - } + { + // Tests map with duplicate key in map entry. + std::string proto = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(key1_data, key2_data, value2_data))); + MessageType test_message; + test_message.MergeFromString(proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest( + absl::StrCat("ValidDataMap", key_type_name, value_type_name, + ".DuplicateKeyInMapEntry"), + REQUIRED, proto, text); + } + + { + // Tests map with duplicate value in map entry. + std::string proto = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(key2_data, value1_data, value2_data))); + MessageType test_message; + test_message.MergeFromString(proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest( + absl::StrCat("ValidDataMap", key_type_name, value_type_name, + ".DuplicateValueInMapEntry"), + REQUIRED, proto, text); + } } template void BinaryAndJsonConformanceSuiteImpl< MessageType>::TestOverwriteMessageValueMap() { - string key_data = absl::StrCat( - tag(1, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim("")); - string field1_data = - absl::StrCat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field2_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field31_data = - absl::StrCat(tag(31, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string submsg1_data = delim(absl::StrCat(field1_data, field31_data)); - string submsg2_data = delim(absl::StrCat(field2_data, field31_data)); - string value1_data = absl::StrCat( - tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - submsg1_data))); - string value2_data = absl::StrCat( - tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - submsg2_data))); - - const FieldDescriptor* field = GetFieldForMapType( - FieldDescriptor::TYPE_STRING, FieldDescriptor::TYPE_MESSAGE); - - string proto1 = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(key_data, value1_data))); - string proto2 = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(key_data, value2_data))); - string proto = absl::StrCat(proto1, proto2); - MessageType test_message; - test_message.MergeFromString(proto2); - string text; - TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest("ValidDataMap.STRING.MESSAGE.MergeValue", REQUIRED, - proto, text); + std::string key_data = absl::StrCat( + tag(1, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim("")); + std::string field1_data = + absl::StrCat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1)); + std::string field2_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); + std::string field31_data = + absl::StrCat(tag(31, WireFormatLite::WIRETYPE_VARINT), varint(1)); + std::string submsg1_data = delim(absl::StrCat(field1_data, field31_data)); + std::string submsg2_data = delim(absl::StrCat(field2_data, field31_data)); + std::string value1_data = absl::StrCat( + tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + submsg1_data))); + std::string value2_data = absl::StrCat( + tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + submsg2_data))); + + const FieldDescriptor* field = GetFieldForMapType( + FieldDescriptor::TYPE_STRING, FieldDescriptor::TYPE_MESSAGE); + + std::string proto1 = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(key_data, value1_data))); + std::string proto2 = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(key_data, value2_data))); + std::string proto = absl::StrCat(proto1, proto2); + MessageType test_message; + test_message.MergeFromString(proto2); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest("ValidDataMap.STRING.MESSAGE.MergeValue", REQUIRED, + proto, text); } template void BinaryAndJsonConformanceSuiteImpl::TestValidDataForOneofType( FieldDescriptor::Type type) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( - static_cast(type)); - - const FieldDescriptor* field = GetFieldForOneofType(type); - const string default_value = - absl::StrCat(tag(field->number(), wire_type), GetDefaultValue(type)); - const string non_default_value = - absl::StrCat(tag(field->number(), wire_type), GetNonDefaultValue(type)); - - { - // Tests oneof with default value. - const string proto = default_value; - MessageType test_message; - test_message.MergeFromString(proto); - string text; - TextFormat::PrintToString(test_message, &text); - - RunValidProtobufTest( - absl::StrCat("ValidDataOneof", type_name, ".DefaultValue"), REQUIRED, - proto, text); - RunValidBinaryProtobufTest( - absl::StrCat("ValidDataOneofBinary", type_name, ".DefaultValue"), - RECOMMENDED, proto, proto); - } + const std::string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType( + static_cast(type)); - { - // Tests oneof with non-default value. - const string proto = non_default_value; - MessageType test_message; - test_message.MergeFromString(proto); - string text; - TextFormat::PrintToString(test_message, &text); - - RunValidProtobufTest( - absl::StrCat("ValidDataOneof", type_name, ".NonDefaultValue"), - REQUIRED, proto, text); - RunValidBinaryProtobufTest( - absl::StrCat("ValidDataOneofBinary", type_name, ".NonDefaultValue"), - RECOMMENDED, proto, proto); - } + const FieldDescriptor* field = GetFieldForOneofType(type); + const std::string default_value = + absl::StrCat(tag(field->number(), wire_type), GetDefaultValue(type)); + const std::string non_default_value = + absl::StrCat(tag(field->number(), wire_type), GetNonDefaultValue(type)); - { - // Tests oneof with multiple values of the same field. - const string proto = absl::StrCat(default_value, non_default_value); - const string expected_proto = non_default_value; - MessageType test_message; - test_message.MergeFromString(expected_proto); - string text; - TextFormat::PrintToString(test_message, &text); - - RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name, - ".MultipleValuesForSameField"), - REQUIRED, proto, text); - RunValidBinaryProtobufTest(absl::StrCat("ValidDataOneofBinary", type_name, - ".MultipleValuesForSameField"), - RECOMMENDED, proto, expected_proto); - } + { + // Tests oneof with default value. + const std::string proto = default_value; + MessageType test_message; + test_message.MergeFromString(proto); + std::string text; + TextFormat::PrintToString(test_message, &text); - { - // Tests oneof with multiple values of the different fields. - const FieldDescriptor* other_field = GetFieldForOneofType(type, true); - FieldDescriptor::Type other_type = other_field->type(); - WireFormatLite::WireType other_wire_type = - WireFormatLite::WireTypeForFieldType( - static_cast(other_type)); - const string other_value = - absl::StrCat(tag(other_field->number(), other_wire_type), - GetDefaultValue(other_type)); - - const string proto = absl::StrCat(other_value, non_default_value); - const string expected_proto = non_default_value; - MessageType test_message; - test_message.MergeFromString(expected_proto); - string text; - TextFormat::PrintToString(test_message, &text); - - RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name, - ".MultipleValuesForDifferentField"), - REQUIRED, proto, text); - RunValidBinaryProtobufTest( - absl::StrCat("ValidDataOneofBinary", type_name, - ".MultipleValuesForDifferentField"), - RECOMMENDED, proto, expected_proto); - } -} + RunValidProtobufTest( + absl::StrCat("ValidDataOneof", type_name, ".DefaultValue"), REQUIRED, + proto, text); + RunValidBinaryProtobufTest( + absl::StrCat("ValidDataOneofBinary", type_name, ".DefaultValue"), + RECOMMENDED, proto, proto); + } -template -void BinaryAndJsonConformanceSuiteImpl::TestMergeOneofMessage() { - string field1_data = - absl::StrCat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field2a_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field2b_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string field89_data = - absl::StrCat(tag(89, WireFormatLite::WIRETYPE_VARINT), varint(1)); - string submsg1_data = absl::StrCat( - tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(field1_data, field2a_data, field89_data))); - string submsg2_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(field2b_data, field89_data))); - string merged_data = - absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(absl::StrCat(field1_data, field2b_data, field89_data, - field89_data))); - - const FieldDescriptor* field = - GetFieldForOneofType(FieldDescriptor::TYPE_MESSAGE); - - string proto1 = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(submsg1_data)); - string proto2 = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(submsg2_data)); - string proto = absl::StrCat(proto1, proto2); - string expected_proto = absl::StrCat( - tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), - delim(merged_data)); + { + // Tests oneof with non-default value. + const std::string proto = non_default_value; + MessageType test_message; + test_message.MergeFromString(proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + + RunValidProtobufTest( + absl::StrCat("ValidDataOneof", type_name, ".NonDefaultValue"), REQUIRED, + proto, text); + RunValidBinaryProtobufTest( + absl::StrCat("ValidDataOneofBinary", type_name, ".NonDefaultValue"), + RECOMMENDED, proto, proto); + } + { + // Tests oneof with multiple values of the same field. + const std::string proto = absl::StrCat(default_value, non_default_value); + const std::string expected_proto = non_default_value; MessageType test_message; test_message.MergeFromString(expected_proto); - string text; + std::string text; TextFormat::PrintToString(test_message, &text); - RunValidProtobufTest("ValidDataOneof.MESSAGE.Merge", REQUIRED, proto, text); - RunValidBinaryProtobufTest("ValidDataOneofBinary.MESSAGE.Merge", + + RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name, + ".MultipleValuesForSameField"), + REQUIRED, proto, text); + RunValidBinaryProtobufTest(absl::StrCat("ValidDataOneofBinary", type_name, + ".MultipleValuesForSameField"), + RECOMMENDED, proto, expected_proto); + } + + { + // Tests oneof with multiple values of the different fields. + const FieldDescriptor* other_field = GetFieldForOneofType(type, true); + FieldDescriptor::Type other_type = other_field->type(); + WireFormatLite::WireType other_wire_type = + WireFormatLite::WireTypeForFieldType( + static_cast(other_type)); + const std::string other_value = + absl::StrCat(tag(other_field->number(), other_wire_type), + GetDefaultValue(other_type)); + + const std::string proto = absl::StrCat(other_value, non_default_value); + const std::string expected_proto = non_default_value; + MessageType test_message; + test_message.MergeFromString(expected_proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + + RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name, + ".MultipleValuesForDifferentField"), + REQUIRED, proto, text); + RunValidBinaryProtobufTest(absl::StrCat("ValidDataOneofBinary", type_name, + ".MultipleValuesForDifferentField"), RECOMMENDED, proto, expected_proto); + } +} + +template +void BinaryAndJsonConformanceSuiteImpl::TestMergeOneofMessage() { + std::string field1_data = + absl::StrCat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1)); + std::string field2a_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); + std::string field2b_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1)); + std::string field89_data = + absl::StrCat(tag(89, WireFormatLite::WIRETYPE_VARINT), varint(1)); + std::string submsg1_data = absl::StrCat( + tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(field1_data, field2a_data, field89_data))); + std::string submsg2_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(field2b_data, field89_data))); + std::string merged_data = + absl::StrCat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(absl::StrCat(field1_data, field2b_data, field89_data, + field89_data))); + + const FieldDescriptor* field = + GetFieldForOneofType(FieldDescriptor::TYPE_MESSAGE); + + std::string proto1 = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(submsg1_data)); + std::string proto2 = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(submsg2_data)); + std::string proto = absl::StrCat(proto1, proto2); + std::string expected_proto = absl::StrCat( + tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(merged_data)); + + MessageType test_message; + test_message.MergeFromString(expected_proto); + std::string text; + TextFormat::PrintToString(test_message, &text); + RunValidProtobufTest("ValidDataOneof.MESSAGE.Merge", REQUIRED, proto, text); + RunValidBinaryProtobufTest("ValidDataOneofBinary.MESSAGE.Merge", RECOMMENDED, + proto, expected_proto); } template void BinaryAndJsonConformanceSuiteImpl::TestIllegalTags() { - // field num 0 is illegal - string nullfield[] = {"\1DEADBEEF", "\2\1\1", "\3\4", "\5DEAD"}; - for (int i = 0; i < 4; i++) { - string name = "IllegalZeroFieldNum_Case_0"; - name.back() += i; - ExpectParseFailureForProto(nullfield[i], name, REQUIRED); - } + // field num 0 is illegal + std::string nullfield[] = {"\1DEADBEEF", "\2\1\1", "\3\4", "\5DEAD"}; + for (int i = 0; i < 4; i++) { + std::string name = "IllegalZeroFieldNum_Case_0"; + name.back() += i; + ExpectParseFailureForProto(nullfield[i], name, REQUIRED); + } } template void BinaryAndJsonConformanceSuiteImpl::TestOneofMessage() { - MessageType message; - message.set_oneof_uint32(0); - RunValidProtobufTestWithMessage("OneofZeroUint32", RECOMMENDED, &message, - "oneof_uint32: 0"); - message.mutable_oneof_nested_message()->set_a(0); - RunValidProtobufTestWithMessage("OneofZeroMessage", RECOMMENDED, &message, - run_proto3_tests_ - ? "oneof_nested_message: {}" - : "oneof_nested_message: {a: 0}"); - message.mutable_oneof_nested_message()->set_a(1); - RunValidProtobufTestWithMessage("OneofZeroMessageSetTwice", RECOMMENDED, - &message, "oneof_nested_message: {a: 1}"); - message.set_oneof_string(""); - RunValidProtobufTestWithMessage("OneofZeroString", RECOMMENDED, &message, - "oneof_string: \"\""); - message.set_oneof_bytes(""); - RunValidProtobufTestWithMessage("OneofZeroBytes", RECOMMENDED, &message, - "oneof_bytes: \"\""); - message.set_oneof_bool(false); - RunValidProtobufTestWithMessage("OneofZeroBool", RECOMMENDED, &message, - "oneof_bool: false"); - message.set_oneof_uint64(0); - RunValidProtobufTestWithMessage("OneofZeroUint64", RECOMMENDED, &message, - "oneof_uint64: 0"); - message.set_oneof_float(0.0f); - RunValidProtobufTestWithMessage("OneofZeroFloat", RECOMMENDED, &message, - "oneof_float: 0"); - message.set_oneof_double(0.0); - RunValidProtobufTestWithMessage("OneofZeroDouble", RECOMMENDED, &message, - "oneof_double: 0"); - message.set_oneof_enum(MessageType::FOO); - RunValidProtobufTestWithMessage("OneofZeroEnum", RECOMMENDED, &message, - "oneof_enum: FOO"); + MessageType message; + message.set_oneof_uint32(0); + RunValidProtobufTestWithMessage("OneofZeroUint32", RECOMMENDED, &message, + "oneof_uint32: 0"); + message.mutable_oneof_nested_message()->set_a(0); + RunValidProtobufTestWithMessage("OneofZeroMessage", RECOMMENDED, &message, + run_proto3_tests_ + ? "oneof_nested_message: {}" + : "oneof_nested_message: {a: 0}"); + message.mutable_oneof_nested_message()->set_a(1); + RunValidProtobufTestWithMessage("OneofZeroMessageSetTwice", RECOMMENDED, + &message, "oneof_nested_message: {a: 1}"); + message.set_oneof_string(""); + RunValidProtobufTestWithMessage("OneofZeroString", RECOMMENDED, &message, + "oneof_string: \"\""); + message.set_oneof_bytes(""); + RunValidProtobufTestWithMessage("OneofZeroBytes", RECOMMENDED, &message, + "oneof_bytes: \"\""); + message.set_oneof_bool(false); + RunValidProtobufTestWithMessage("OneofZeroBool", RECOMMENDED, &message, + "oneof_bool: false"); + message.set_oneof_uint64(0); + RunValidProtobufTestWithMessage("OneofZeroUint64", RECOMMENDED, &message, + "oneof_uint64: 0"); + message.set_oneof_float(0.0f); + RunValidProtobufTestWithMessage("OneofZeroFloat", RECOMMENDED, &message, + "oneof_float: 0"); + message.set_oneof_double(0.0); + RunValidProtobufTestWithMessage("OneofZeroDouble", RECOMMENDED, &message, + "oneof_double: 0"); + message.set_oneof_enum(MessageType::FOO); + RunValidProtobufTestWithMessage("OneofZeroEnum", RECOMMENDED, &message, + "oneof_enum: FOO"); } template void BinaryAndJsonConformanceSuiteImpl::TestUnknownMessage() { - MessageType message; - message.ParseFromString("\xA8\x1F\x01"); - RunValidBinaryProtobufTest("UnknownVarint", REQUIRED, - message.SerializeAsString()); + MessageType message; + message.ParseFromString("\xA8\x1F\x01"); + RunValidBinaryProtobufTest("UnknownVarint", REQUIRED, + message.SerializeAsString()); } template void BinaryAndJsonConformanceSuiteImpl< MessageType>::TestBinaryPerformanceForAlternatingUnknownFields() { - string unknown_field_1 = absl::StrCat( - tag(UNKNOWN_FIELD, WireFormatLite::WIRETYPE_VARINT), varint(1234)); - string unknown_field_2 = absl::StrCat( - tag(UNKNOWN_FIELD + 1, WireFormatLite::WIRETYPE_VARINT), varint(5678)); - string proto; - for (size_t i = 0; i < kPerformanceRepeatCount; i++) { - proto.append(unknown_field_1); - proto.append(unknown_field_2); - } + std::string unknown_field_1 = absl::StrCat( + tag(UNKNOWN_FIELD, WireFormatLite::WIRETYPE_VARINT), varint(1234)); + std::string unknown_field_2 = absl::StrCat( + tag(UNKNOWN_FIELD + 1, WireFormatLite::WIRETYPE_VARINT), varint(5678)); + std::string proto; + for (size_t i = 0; i < kPerformanceRepeatCount; i++) { + proto.append(unknown_field_1); + proto.append(unknown_field_2); + } - RunValidBinaryProtobufTest( - "TestBinaryPerformanceForAlternatingUnknownFields", RECOMMENDED, proto); + RunValidBinaryProtobufTest("TestBinaryPerformanceForAlternatingUnknownFields", + RECOMMENDED, proto); } template void BinaryAndJsonConformanceSuiteImpl:: TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( FieldDescriptor::Type type) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - int field_number = GetFieldForType(type, true, Packed::kFalse)->number(); - string rep_field_proto = absl::StrCat( - tag(field_number, WireFormatLite::WireTypeForFieldType( - static_cast(type))), - GetNonDefaultValue(type)); - - RunBinaryPerformanceMergeMessageWithField( - absl::StrCat( - "TestBinaryPerformanceMergeMessageWithRepeatedFieldForType", - type_name), - rep_field_proto); + const std::string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + int field_number = GetFieldForType(type, true, Packed::kFalse)->number(); + std::string rep_field_proto = absl::StrCat( + tag(field_number, WireFormatLite::WireTypeForFieldType( + static_cast(type))), + GetNonDefaultValue(type)); + + RunBinaryPerformanceMergeMessageWithField( + absl::StrCat("TestBinaryPerformanceMergeMessageWithRepeatedFieldForType", + type_name), + rep_field_proto); } template void BinaryAndJsonConformanceSuiteImpl:: TestBinaryPerformanceMergeMessageWithUnknownFieldForType( FieldDescriptor::Type type) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - string unknown_field_proto = absl::StrCat( - tag(UNKNOWN_FIELD, WireFormatLite::WireTypeForFieldType( - static_cast(type))), - GetNonDefaultValue(type)); - RunBinaryPerformanceMergeMessageWithField( - absl::StrCat("TestBinaryPerformanceMergeMessageWithUnknownFieldForType", - type_name), - unknown_field_proto); + const std::string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + std::string unknown_field_proto = absl::StrCat( + tag(UNKNOWN_FIELD, WireFormatLite::WireTypeForFieldType( + static_cast(type))), + GetNonDefaultValue(type)); + RunBinaryPerformanceMergeMessageWithField( + absl::StrCat("TestBinaryPerformanceMergeMessageWithUnknownFieldForType", + type_name), + unknown_field_proto); } template @@ -1321,16 +1330,16 @@ BinaryAndJsonConformanceSuiteImpl:: BinaryAndJsonConformanceSuiteImpl(BinaryAndJsonConformanceSuite* suite, bool run_proto3_tests) : suite_(*ABSL_DIE_IF_NULL(suite)), run_proto3_tests_(run_proto3_tests) { - RunAllTests(); + RunAllTests(); } template void BinaryAndJsonConformanceSuiteImpl::RunAllTests() { - if (!suite_.performance_) { - for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) { + if (!suite_.performance_) { + for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) { if (i == FieldDescriptor::TYPE_GROUP) continue; TestPrematureEOFForType(static_cast(i)); - } + } TestIllegalTags(); @@ -1553,104 +1562,104 @@ void BinaryAndJsonConformanceSuiteImpl::RunAllTests() { TestOneofMessage(); RunJsonTests(); - } + } // Flag control performance tests to keep them internal and opt-in only - if (suite_.performance_) { + if (suite_.performance_) { RunBinaryPerformanceTests(); RunJsonPerformanceTests(); - } + } } template void BinaryAndJsonConformanceSuiteImpl< MessageType>::RunBinaryPerformanceTests() { - TestBinaryPerformanceForAlternatingUnknownFields(); - - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_BOOL); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_DOUBLE); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_FLOAT); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_UINT32); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_UINT64); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_STRING); - TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_BYTES); - - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_BOOL); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_DOUBLE); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_FLOAT); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_UINT32); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_UINT64); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_STRING); - TestBinaryPerformanceMergeMessageWithUnknownFieldForType( - FieldDescriptor::TYPE_BYTES); + TestBinaryPerformanceForAlternatingUnknownFields(); + + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_BOOL); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_DOUBLE); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_FLOAT); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_UINT32); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_UINT64); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_STRING); + TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_BYTES); + + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_BOOL); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_DOUBLE); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_FLOAT); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_UINT32); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_UINT64); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_STRING); + TestBinaryPerformanceMergeMessageWithUnknownFieldForType( + FieldDescriptor::TYPE_BYTES); } template void BinaryAndJsonConformanceSuiteImpl::RunJsonPerformanceTests() { - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_BOOL, "true"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_DOUBLE, "123"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_FLOAT, "123"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_UINT32, "123"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_UINT64, "123"); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_STRING, "\"foo\""); - TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::TYPE_BYTES, "\"foo\""); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_BOOL, "true"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_DOUBLE, "123"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_FLOAT, "123"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_UINT32, "123"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_UINT64, "123"); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_STRING, "\"foo\""); + TestJsonPerformanceMergeMessageWithRepeatedFieldForType( + FieldDescriptor::TYPE_BYTES, "\"foo\""); } // This is currently considered valid input by some languages but not others template void BinaryAndJsonConformanceSuiteImpl:: TestJsonPerformanceMergeMessageWithRepeatedFieldForType( - FieldDescriptor::Type type, string field_value) { - const string type_name = - UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); - const FieldDescriptor* field = GetFieldForType(type, true, Packed::kFalse); - string field_name = field->name(); - - string message_field = - absl::StrCat("\"", field_name, "\": [", field_value, "]"); - string recursive_message = - absl::StrCat("\"recursive_message\": { ", message_field, "}"); - string input = absl::StrCat("{", recursive_message); - for (size_t i = 1; i < kPerformanceRepeatCount; i++) { + FieldDescriptor::Type type, std::string field_value) { + const std::string type_name = + UpperCase(absl::StrCat(".", FieldDescriptor::TypeName(type))); + const FieldDescriptor* field = GetFieldForType(type, true, Packed::kFalse); + std::string field_name = field->name(); + + std::string message_field = + absl::StrCat("\"", field_name, "\": [", field_value, "]"); + std::string recursive_message = + absl::StrCat("\"recursive_message\": { ", message_field, "}"); + std::string input = absl::StrCat("{", recursive_message); + for (size_t i = 1; i < kPerformanceRepeatCount; i++) { absl::StrAppend(&input, ",", recursive_message); - } - absl::StrAppend(&input, "}"); + } + absl::StrAppend(&input, "}"); - string textproto_message_field = - absl::StrCat(field_name, ": ", field_value); - string expected_textproto = "recursive_message { "; - for (size_t i = 0; i < kPerformanceRepeatCount; i++) { + std::string textproto_message_field = + absl::StrCat(field_name, ": ", field_value); + std::string expected_textproto = "recursive_message { "; + for (size_t i = 0; i < kPerformanceRepeatCount; i++) { absl::StrAppend(&expected_textproto, textproto_message_field, " "); - } - absl::StrAppend(&expected_textproto, "}"); - RunValidJsonTest( - absl::StrCat("TestJsonPerformanceMergeMessageWithRepeatedFieldForType", - type_name), - RECOMMENDED, input, expected_textproto); + } + absl::StrAppend(&expected_textproto, "}"); + RunValidJsonTest( + absl::StrCat("TestJsonPerformanceMergeMessageWithRepeatedFieldForType", + type_name), + RECOMMENDED, input, expected_textproto); } template void BinaryAndJsonConformanceSuiteImpl::RunJsonTests() { - if (!run_proto3_tests_) { + if (!run_proto3_tests_) { RunValidJsonTestWithValidator( "StoresDefaultPrimitive", REQUIRED, R"({ @@ -1667,72 +1676,72 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTests() { "[protobuf_test_messages.proto2.extension_int32]"); }); return; - } - RunValidJsonTest("HelloWorld", REQUIRED, - "{\"optionalString\":\"Hello, World!\"}", - "optional_string: 'Hello, World!'"); - - // NOTE: The spec for JSON support is still being sorted out, these may not - // all be correct. - - RunJsonTestsForFieldNameConvention(); - RunJsonTestsForNonRepeatedTypes(); - RunJsonTestsForRepeatedTypes(); - RunJsonTestsForNullTypes(); - RunJsonTestsForWrapperTypes(); - RunJsonTestsForFieldMask(); - RunJsonTestsForStruct(); - RunJsonTestsForValue(); - RunJsonTestsForAny(); - RunJsonTestsForUnknownEnumStringValues(); - - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNumber", REQUIRED, - R"({ + } + RunValidJsonTest("HelloWorld", REQUIRED, + "{\"optionalString\":\"Hello, World!\"}", + "optional_string: 'Hello, World!'"); + + // NOTE: The spec for JSON support is still being sorted out, these may not + // all be correct. + + RunJsonTestsForFieldNameConvention(); + RunJsonTestsForNonRepeatedTypes(); + RunJsonTestsForRepeatedTypes(); + RunJsonTestsForNullTypes(); + RunJsonTestsForWrapperTypes(); + RunJsonTestsForFieldMask(); + RunJsonTestsForStruct(); + RunJsonTestsForValue(); + RunJsonTestsForAny(); + RunJsonTestsForUnknownEnumStringValues(); + + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNumber", REQUIRED, + R"({ "unknown": 1 })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonString", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonString", REQUIRED, + R"({ "unknown": "a" })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonTrue", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonTrue", REQUIRED, + R"({ "unknown": true })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonFalse", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonFalse", REQUIRED, + R"({ "unknown": false })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNull", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNull", REQUIRED, + R"({ "unknown": null })", - ""); - RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonObject", REQUIRED, - R"({ + ""); + RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonObject", REQUIRED, + R"({ "unknown": {"a": 1} })", - ""); + ""); - ExpectParseFailureForJson("RejectTopLevelNull", REQUIRED, "null"); + ExpectParseFailureForJson("RejectTopLevelNull", REQUIRED, "null"); } template void BinaryAndJsonConformanceSuiteImpl< MessageType>::RunJsonTestsForUnknownEnumStringValues() { - // Tests the handling of unknown enum values when encoded as string labels. - // The expected behavior depends on whether unknown fields are ignored: - // * when ignored, the parser should ignore the unknown enum string value. - // * when not ignored, the parser should fail. - struct TestCase { + // Tests the handling of unknown enum values when encoded as string labels. + // The expected behavior depends on whether unknown fields are ignored: + // * when ignored, the parser should ignore the unknown enum string value. + // * when not ignored, the parser should fail. + struct TestCase { // Used in the test name. - string enum_location; + std::string enum_location; // JSON input which will contain the unknown field. - string input_json; - }; + std::string input_json; + }; const std::vector test_cases = { {"InOptionalField", R"json({ "optional_nested_enum": "UNKNOWN_ENUM_VALUE" @@ -2393,17 +2402,17 @@ void BinaryAndJsonConformanceSuiteImpl< "mapStringNestedMessage": { "hello": {"a": 1234}, "world": {"a": 5678} - } + } })", R"( map_string_nested_message: { key: "hello" value: {a: 1234} - } + } map_string_nested_message: { key: "world" value: {a: 5678} - } + } )"); // Since Map keys are represented as JSON strings, escaping should be allowed. RunValidJsonTest("Int32MapEscapedKey", REQUIRED, @@ -2736,7 +2745,7 @@ void BinaryAndJsonConformanceSuiteImpl< "repeatedTimestamp": [ "0001-01-01T00:00:00Z", "9999-12-31T23:59:59.999999999Z" - ] + ] })", "repeated_timestamp: {seconds: -62135596800}" "repeated_timestamp: {seconds: 253402300799 nanos: 999999999}"); @@ -2835,44 +2844,44 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForStruct() { "listValue": [1234, "5678"], "objectValue": { "value": 0 - } - } + } + } })", R"( optional_struct: { fields: { key: "nullValue" value: {null_value: NULL_VALUE} - } + } fields: { key: "intValue" value: {number_value: 1234} - } + } fields: { key: "boolValue" value: {bool_value: true} - } + } fields: { key: "doubleValue" value: {number_value: 1234.5678} - } + } fields: { key: "stringValue" value: {string_value: "Hello world!"} - } + } fields: { key: "listValue" value: { list_value: { values: { number_value: 1234 - } + } values: { string_value: "5678" - } - } - } } + } + } + } fields: { key: "objectValue" value: { @@ -2881,18 +2890,18 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForStruct() { key: "value" value: { number_value: 0 - } - } - } } } } + } + } + } )"); RunValidJsonTest("StructWithEmptyListValue", REQUIRED, R"({ "optionalStruct": { "listValue": [] - } + } })", R"( optional_struct: { @@ -2900,10 +2909,10 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForStruct() { key: "listValue" value: { list_value: { - } - } - } } + } + } + } )"); } @@ -2927,12 +2936,12 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForValue() { list_value: { values: { number_value: 0 - } + } values: { string_value: "hello" - } - } - } + } + } + } )"); RunValidJsonTest("ValueAcceptObject", REQUIRED, R"({"optionalValue": {"value": 1}})", @@ -2943,10 +2952,10 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForValue() { key: "value" value: { number_value: 1 - } - } - } } + } + } + } )"); RunValidJsonTest("RepeatedValue", REQUIRED, R"({ @@ -2954,14 +2963,14 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForValue() { })", R"( repeated_value: [ - { + { list_value: { values: [ { string_value: "a"} - ] - } - } ] + } + } + ] )"); RunValidJsonTest("RepeatedListValue", REQUIRED, R"({ @@ -2969,12 +2978,12 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForValue() { })", R"( repeated_list_value: [ - { + { values: [ { string_value: "a"} - ] - } - ] + ] + } + ] )"); RunValidJsonTestWithValidator( "NullValueInOtherOneofOldFormat", RECOMMENDED, @@ -3004,14 +3013,14 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForAny() { "optionalAny": { "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3", "optionalInt32": 12345 - } + } })", R"( optional_any: { - [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { + [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { optional_int32: 12345 - } - } + } + } )"); RunValidJsonTest("AnyNested", REQUIRED, R"({ @@ -3020,17 +3029,17 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForAny() { "value": { "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3", "optionalInt32": 12345 - } - } + } + } })", R"( optional_any: { - [type.googleapis.com/google.protobuf.Any] { - [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { + [type.googleapis.com/google.protobuf.Any] { + [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { optional_int32: 12345 - } - } - } + } + } + } )"); // The special "@type" tag is not required to appear first. RunValidJsonTest("AnyUnorderedTypeTag", REQUIRED, @@ -3038,14 +3047,14 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForAny() { "optionalAny": { "optionalInt32": 12345, "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3" - } + } })", R"( optional_any: { - [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { + [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { optional_int32: 12345 - } - } + } + } )"); // Well-known types in Any. RunValidJsonTest("AnyWithInt32ValueWrapper", REQUIRED, @@ -3053,58 +3062,58 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForAny() { "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Int32Value", "value": 12345 - } + } })", R"( optional_any: { - [type.googleapis.com/google.protobuf.Int32Value] { + [type.googleapis.com/google.protobuf.Int32Value] { value: 12345 - } - } + } + } )"); RunValidJsonTest("AnyWithDuration", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.5s" - } + } })", R"( optional_any: { - [type.googleapis.com/google.protobuf.Duration] { + [type.googleapis.com/google.protobuf.Duration] { seconds: 1 nanos: 500000000 - } - } + } + } )"); RunValidJsonTest("AnyWithTimestamp", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Timestamp", "value": "1970-01-01T00:00:00Z" - } + } })", R"( optional_any: { - [type.googleapis.com/google.protobuf.Timestamp] { + [type.googleapis.com/google.protobuf.Timestamp] { seconds: 0 nanos: 0 - } - } + } + } )"); RunValidJsonTest("AnyWithFieldMask", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.FieldMask", "value": "foo,barBaz" - } + } })", R"( optional_any: { - [type.googleapis.com/google.protobuf.FieldMask] { + [type.googleapis.com/google.protobuf.FieldMask] { paths: ["foo", "bar_baz"] - } - } + } + } )"); RunValidJsonTest("AnyWithStruct", REQUIRED, R"({ @@ -3112,20 +3121,20 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForAny() { "@type": "type.googleapis.com/google.protobuf.Struct", "value": { "foo": 1 - } - } + } + } })", R"( optional_any: { - [type.googleapis.com/google.protobuf.Struct] { + [type.googleapis.com/google.protobuf.Struct] { fields: { key: "foo" value: { number_value: 1 - } - } - } } + } + } + } )"); RunValidJsonTest("AnyWithValueForJsonObject", REQUIRED, R"({ @@ -3133,36 +3142,36 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForAny() { "@type": "type.googleapis.com/google.protobuf.Value", "value": { "foo": 1 - } - } + } + } })", R"( optional_any: { - [type.googleapis.com/google.protobuf.Value] { + [type.googleapis.com/google.protobuf.Value] { struct_value: { fields: { key: "foo" value: { number_value: 1 - } - } - } } } + } + } + } )"); RunValidJsonTest("AnyWithValueForInteger", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Value", "value": 1 - } + } })", R"( optional_any: { - [type.googleapis.com/google.protobuf.Value] { + [type.googleapis.com/google.protobuf.Value] { number_value: 1 - } - } + } + } )"); } diff --git a/conformance/binary_json_conformance_suite.h b/conformance/binary_json_conformance_suite.h index 452e672802..f6a87088b1 100644 --- a/conformance/binary_json_conformance_suite.h +++ b/conformance/binary_json_conformance_suite.h @@ -8,6 +8,7 @@ #ifndef CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H #define CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H +#include #include #include #include diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 88cfdc2ad8..fc80ec6d0f 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -9,12 +9,15 @@ #include +#include +#include #include +#include #include #include "google/protobuf/util/field_comparator.h" -#include "google/protobuf/util/json_util.h" #include "google/protobuf/util/message_differencer.h" +#include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -28,15 +31,14 @@ using conformance::ConformanceRequest; using conformance::ConformanceResponse; using conformance::WireFormat; -using google::protobuf::TextFormat; using google::protobuf::util::DefaultFieldComparator; using google::protobuf::util::MessageDifferencer; using std::string; namespace { -static string ToOctString(const string& binary_string) { - string oct_string; +static std::string ToOctString(const std::string& binary_string) { + std::string oct_string; for (size_t i = 0; i < binary_string.size(); i++) { uint8_t c = binary_string.at(i); uint8_t high = c / 64; @@ -96,7 +98,7 @@ ConformanceTestSuite::ConformanceRequestSetting::ConformanceRequestSetting( ConformanceLevel level, conformance::WireFormat input_format, conformance::WireFormat output_format, conformance::TestCategory test_category, const Message& prototype_message, - const string& test_name, const string& input) + const std::string& test_name, const std::string& input) : level_(level), input_format_(input_format), output_format_(output_format), @@ -139,8 +141,9 @@ ConformanceTestSuite::ConformanceRequestSetting::NewTestMessage() const { return std::unique_ptr(prototype_message_for_compare_->New()); } -string ConformanceTestSuite::ConformanceRequestSetting::GetTestName() const { - string rname; +std::string ConformanceTestSuite::ConformanceRequestSetting::GetTestName() + const { + std::string rname; switch (FileDescriptorLegacy(prototype_message_.GetDescriptor()->file()) .syntax()) { case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3: @@ -158,7 +161,7 @@ string ConformanceTestSuite::ConformanceRequestSetting::GetTestName() const { OutputFormatString(output_format_)); } -string +std::string ConformanceTestSuite::ConformanceRequestSetting::ConformanceLevelToString( ConformanceLevel level) const { switch (level) { @@ -171,7 +174,7 @@ ConformanceTestSuite::ConformanceRequestSetting::ConformanceLevelToString( return ""; } -string ConformanceTestSuite::ConformanceRequestSetting::InputFormatString( +std::string ConformanceTestSuite::ConformanceRequestSetting::InputFormatString( conformance::WireFormat format) const { switch (format) { case conformance::PROTOBUF: @@ -186,7 +189,7 @@ string ConformanceTestSuite::ConformanceRequestSetting::InputFormatString( return ""; } -string ConformanceTestSuite::ConformanceRequestSetting::OutputFormatString( +std::string ConformanceTestSuite::ConformanceRequestSetting::OutputFormatString( conformance::WireFormat format) const { switch (format) { case conformance::PROTOBUF: @@ -208,7 +211,7 @@ void ConformanceTestSuite::TruncateDebugPayload(string* payload) { } } -const ConformanceRequest ConformanceTestSuite::TruncateRequest( +ConformanceRequest ConformanceTestSuite::TruncateRequest( const ConformanceRequest& request) { ConformanceRequest debug_request(request); switch (debug_request.payload_case()) { @@ -231,7 +234,7 @@ const ConformanceRequest ConformanceTestSuite::TruncateRequest( return debug_request; } -const ConformanceResponse ConformanceTestSuite::TruncateResponse( +ConformanceResponse ConformanceTestSuite::TruncateResponse( const ConformanceResponse& response) { ConformanceResponse debug_response(response); switch (debug_response.result_case()) { @@ -254,7 +257,7 @@ const ConformanceResponse ConformanceTestSuite::TruncateResponse( return debug_response; } -void ConformanceTestSuite::ReportSuccess(const string& test_name) { +void ConformanceTestSuite::ReportSuccess(const std::string& test_name) { if (expected_to_fail_.erase(test_name) != 0) { absl::StrAppendFormat( &output_, @@ -266,7 +269,7 @@ void ConformanceTestSuite::ReportSuccess(const string& test_name) { successes_++; } -void ConformanceTestSuite::ReportFailure(const string& test_name, +void ConformanceTestSuite::ReportFailure(const std::string& test_name, ConformanceLevel level, const ConformanceRequest& request, const ConformanceResponse& response, @@ -286,7 +289,7 @@ void ConformanceTestSuite::ReportFailure(const string& test_name, TruncateResponse(response).ShortDebugString()); } -void ConformanceTestSuite::ReportSkip(const string& test_name, +void ConformanceTestSuite::ReportSkip(const std::string& test_name, const ConformanceRequest& request, const ConformanceResponse& response) { if (verbose_) { @@ -299,19 +302,20 @@ void ConformanceTestSuite::ReportSkip(const string& test_name, void ConformanceTestSuite::RunValidInputTest( const ConformanceRequestSetting& setting, - const string& equivalent_text_format) { + const std::string& equivalent_text_format) { std::unique_ptr reference_message(setting.NewTestMessage()); ABSL_CHECK(TextFormat::ParseFromString(equivalent_text_format, reference_message.get())) << "Failed to parse data for test case: " << setting.GetTestName() << ", data: " << equivalent_text_format; - const string equivalent_wire_format = reference_message->SerializeAsString(); + const std::string equivalent_wire_format = + reference_message->SerializeAsString(); RunValidBinaryInputTest(setting, equivalent_wire_format); } void ConformanceTestSuite::RunValidBinaryInputTest( const ConformanceRequestSetting& setting, - const string& equivalent_wire_format, bool require_same_wire_format) { + const std::string& equivalent_wire_format, bool require_same_wire_format) { const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; RunTest(setting.GetTestName(), request, &response); @@ -321,11 +325,12 @@ void ConformanceTestSuite::RunValidBinaryInputTest( void ConformanceTestSuite::VerifyResponse( const ConformanceRequestSetting& setting, - const string& equivalent_wire_format, const ConformanceResponse& response, - bool need_report_success, bool require_same_wire_format) { + const std::string& equivalent_wire_format, + const ConformanceResponse& response, bool need_report_success, + bool require_same_wire_format) { std::unique_ptr test_message(setting.NewTestMessage()); const ConformanceRequest& request = setting.GetRequest(); - const string& test_name = setting.GetTestName(); + const std::string& test_name = setting.GetTestName(); ConformanceLevel level = setting.GetLevel(); std::unique_ptr reference_message = setting.NewTestMessage(); @@ -358,7 +363,7 @@ void ConformanceTestSuite::VerifyResponse( DefaultFieldComparator field_comparator; field_comparator.set_treat_nan_as_equal(true); differencer.set_field_comparator(&field_comparator); - string differences; + std::string differences; differencer.ReportDifferencesToString(&differences); bool check = false; @@ -366,7 +371,7 @@ void ConformanceTestSuite::VerifyResponse( if (require_same_wire_format) { ABSL_DCHECK_EQ(response.result_case(), ConformanceResponse::kProtobufPayload); - const string& protobuf_payload = response.protobuf_payload(); + const std::string& protobuf_payload = response.protobuf_payload(); check = equivalent_wire_format == protobuf_payload; differences = absl::StrCat("Expect: ", ToOctString(equivalent_wire_format), ", but got: ", ToOctString(protobuf_payload)); @@ -386,15 +391,15 @@ void ConformanceTestSuite::VerifyResponse( } } -void ConformanceTestSuite::RunTest(const string& test_name, +void ConformanceTestSuite::RunTest(const std::string& test_name, const ConformanceRequest& request, ConformanceResponse* response) { if (test_names_.insert(test_name).second == false) { ABSL_LOG(FATAL) << "Duplicated test name: " << test_name; } - string serialized_request; - string serialized_response; + std::string serialized_request; + std::string serialized_response; request.SerializeToString(&serialized_request); runner_->RunTest(test_name, serialized_request, &serialized_response); @@ -412,7 +417,7 @@ void ConformanceTestSuite::RunTest(const string& test_name, } } -string ConformanceTestSuite::WireFormatToString(WireFormat wire_format) { +std::string ConformanceTestSuite::WireFormatToString(WireFormat wire_format) { switch (wire_format) { case conformance::PROTOBUF: return "PROTOBUF"; @@ -435,7 +440,8 @@ void ConformanceTestSuite::AddExpectedFailedTest(const std::string& test_name) { } bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, - std::string* output, const string& filename, + std::string* output, + const std::string& filename, conformance::FailureSet* failure_list) { runner_ = runner; successes_ = 0; @@ -449,7 +455,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, failure_list_filename_ = filename; expected_to_fail_.clear(); - for (const string& failure : failure_list->failure()) { + for (const std::string& failure : failure_list->failure()) { AddExpectedFailedTest(failure); } RunSuiteImpl(); diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index 0e3fb704ac..bdc7a697fe 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -14,13 +14,15 @@ #ifndef CONFORMANCE_CONFORMANCE_TEST_H #define CONFORMANCE_CONFORMANCE_TEST_H -#include +#include +#include #include #include #include "google/protobuf/util/type_resolver.h" #include "absl/container/btree_set.h" #include "absl/container/flat_hash_set.h" +#include "absl/strings/string_view.h" #include "conformance/conformance.pb.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/wire_format_lite.h" @@ -204,7 +206,7 @@ class ConformanceTestSuite { return request_; } - const ConformanceLevel GetLevel() const { return level_; } + ConformanceLevel GetLevel() const { return level_; } std::string ConformanceLevelToString(ConformanceLevel level) const; @@ -245,9 +247,9 @@ class ConformanceTestSuite { bool need_report_success, bool require_same_wire_format); void TruncateDebugPayload(std::string* payload); - const conformance::ConformanceRequest TruncateRequest( + conformance::ConformanceRequest TruncateRequest( const conformance::ConformanceRequest& request); - const conformance::ConformanceResponse TruncateResponse( + conformance::ConformanceResponse TruncateResponse( const conformance::ConformanceResponse& response); void ReportSuccess(const std::string& test_name); diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index 25740ee9b4..fb0ca1f6d5 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -7,7 +7,10 @@ #include "text_format_conformance_suite.h" -#include "google/protobuf/any.pb.h" +#include +#include +#include + #include "absl/log/absl_log.h" #include "absl/strings/str_cat.h" #include "conformance_test.h" @@ -20,12 +23,9 @@ namespace proto2_messages = protobuf_test_messages::proto2; using conformance::ConformanceRequest; using conformance::ConformanceResponse; using conformance::WireFormat; -using google::protobuf::Message; -using google::protobuf::TextFormat; using proto2_messages::TestAllTypesProto2; using proto2_messages::UnknownToTestAllTypes; using protobuf_test_messages::proto3::TestAllTypesProto3; -using std::string; namespace google { namespace protobuf { @@ -61,7 +61,7 @@ bool TextFormatConformanceTestSuite::ParseResponse( const ConformanceRequestSetting& setting, Message* test_message) { const ConformanceRequest& request = setting.GetRequest(); WireFormat requested_output = request.requested_output_format(); - const string& test_name = setting.GetTestName(); + const std::string& test_name = setting.GetTestName(); ConformanceLevel level = setting.GetLevel(); switch (response.result_case()) { @@ -111,9 +111,9 @@ bool TextFormatConformanceTestSuite::ParseResponse( return true; } -void TextFormatConformanceTestSuite::ExpectParseFailure(const string& test_name, - ConformanceLevel level, - const string& input) { +void TextFormatConformanceTestSuite::ExpectParseFailure( + const std::string& test_name, ConformanceLevel level, + const std::string& input) { TestAllTypesProto3 prototype; // We don't expect output, but if the program erroneously accepts the protobuf // we let it send its response as this. We must not leave it unspecified. @@ -122,7 +122,7 @@ void TextFormatConformanceTestSuite::ExpectParseFailure(const string& test_name, conformance::TEXT_FORMAT_TEST, prototype, test_name, input); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - string effective_test_name = + std::string effective_test_name = absl::StrCat(setting.ConformanceLevelToString(level), ".Proto3.TextFormatInput.", test_name); @@ -138,36 +138,38 @@ void TextFormatConformanceTestSuite::ExpectParseFailure(const string& test_name, } void TextFormatConformanceTestSuite::RunValidTextFormatTest( - const string& test_name, ConformanceLevel level, const string& input_text) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_text) { TestAllTypesProto3 prototype; RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype); } void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2( - const string& test_name, ConformanceLevel level, const string& input_text) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_text) { TestAllTypesProto2 prototype; RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype); } void TextFormatConformanceTestSuite::RunValidTextFormatTestWithExpected( - const string& test_name, ConformanceLevel level, const string& input_text, - const string& expected_text) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_text, const std::string& expected_text) { TestAllTypesProto3 prototype; RunValidTextFormatTestWithMessage(test_name, level, input_text, expected_text, prototype); } void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2WithExpected( - const string& test_name, ConformanceLevel level, const string& input_text, - const string& expected_text) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_text, const std::string& expected_text) { TestAllTypesProto2 prototype; RunValidTextFormatTestWithMessage(test_name, level, input_text, expected_text, prototype); } void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage( - const string& test_name, ConformanceLevel level, const string& input_text, - const Message& prototype) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_text, const Message& prototype) { ConformanceRequestSetting setting1( level, conformance::TEXT_FORMAT, conformance::PROTOBUF, conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text); @@ -179,8 +181,9 @@ void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage( } void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage( - const string& test_name, ConformanceLevel level, const string& input_text, - const string& expected_text, const Message& prototype) { + const std::string& test_name, ConformanceLevel level, + const std::string& input_text, const std::string& expected_text, + const Message& prototype) { ConformanceRequestSetting setting1( level, conformance::TEXT_FORMAT, conformance::PROTOBUF, conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text); @@ -192,8 +195,8 @@ void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage( } void TextFormatConformanceTestSuite::RunValidUnknownTextFormatTest( - const string& test_name, const Message& message) { - string serialized_input; + const std::string& test_name, const Message& message) { + std::string serialized_input; message.SerializeToString(&serialized_input); TestAllTypesProto3 prototype; ConformanceRequestSetting setting1( @@ -509,16 +512,16 @@ void TextFormatConformanceTestSuite::RunTextFormatPerformanceTests() { // This is currently considered valid input by some languages but not others void TextFormatConformanceTestSuite:: TestTextFormatPerformanceMergeMessageWithRepeatedField( - const string& test_type_name, const string& message_field) { - string recursive_message = + const std::string& test_type_name, const std::string& message_field) { + std::string recursive_message = absl::StrCat("recursive_message { ", message_field, " }"); - string input; + std::string input; for (size_t i = 0; i < kPerformanceRepeatCount; i++) { absl::StrAppend(&input, recursive_message); } - string expected = "recursive_message { "; + std::string expected = "recursive_message { "; for (size_t i = 0; i < kPerformanceRepeatCount; i++) { absl::StrAppend(&expected, message_field, " "); } diff --git a/conformance/text_format_conformance_suite.h b/conformance/text_format_conformance_suite.h index 045fdc2a31..1917ee565b 100644 --- a/conformance/text_format_conformance_suite.h +++ b/conformance/text_format_conformance_suite.h @@ -8,7 +8,10 @@ #ifndef TEXT_FORMAT_CONFORMANCE_SUITE_H_ #define TEXT_FORMAT_CONFORMANCE_SUITE_H_ +#include + #include "conformance_test.h" +#include "google/protobuf/message.h" namespace google { namespace protobuf { From 28e573e77fc3b453dd242e3848b19e7adbf04984 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Tue, 17 Oct 2023 17:26:08 -0700 Subject: [PATCH 20/95] Restructure syntax branches in text format conformance tests. This doesn't change the tests at all, but refactors them to be more reusable in different contexts. Specifically, this will make it easier to add corresponding editions-based tests. This also splits the concept of "uses a proto3 message" and "runs proto3 tests", in preparation for that change. PiperOrigin-RevId: 574310612 --- conformance/BUILD.bazel | 3 + conformance/binary_json_conformance_suite.cc | 14 +- conformance/conformance_test.cc | 18 +- conformance/conformance_test.h | 3 + conformance/text_format_conformance_suite.cc | 584 ++++++++++--------- conformance/text_format_conformance_suite.h | 60 +- 6 files changed, 354 insertions(+), 328 deletions(-) diff --git a/conformance/BUILD.bazel b/conformance/BUILD.bazel index 42c1b3da34..eafd606b09 100644 --- a/conformance/BUILD.bazel +++ b/conformance/BUILD.bazel @@ -171,6 +171,9 @@ cc_library( ":conformance_test", ":test_messages_proto2_proto_cc", ":test_messages_proto3_proto_cc", + "@com_google_absl//absl/log:absl_log", + "@com_google_absl//absl/log:die_if_null", + "@com_google_absl//absl/strings", ], ) diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index d063c1270b..dbacc05450 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -349,7 +349,7 @@ void BinaryAndJsonConformanceSuiteImpl:: ConformanceResponse response; std::string effective_test_name = absl::StrCat(setting.ConformanceLevelToString(level), ".", - SyntaxIdentifier(), ".ProtobufInput.", test_name); + setting.GetSyntaxIdentifier(), ".ProtobufInput.", test_name); suite_.RunTest(effective_test_name, request, &response); if (response.result_case() == ConformanceResponse::kParseError) { @@ -522,9 +522,9 @@ void BinaryAndJsonConformanceSuiteImpl< test_name, input_json); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - std::string effective_test_name = - absl::StrCat(setting.ConformanceLevelToString(level), ".", - SyntaxIdentifier(), ".JsonInput.", test_name, ".Validator"); + std::string effective_test_name = absl::StrCat( + setting.ConformanceLevelToString(level), ".", + setting.GetSyntaxIdentifier(), ".JsonInput.", test_name, ".Validator"); suite_.RunTest(effective_test_name, request, &response); @@ -3202,7 +3202,7 @@ BinaryAndJsonConformanceSuiteImpl::GetFieldForType( } ABSL_LOG(FATAL) << "Couldn't find field with type: " << repeated_string << packed_string << FieldDescriptor::TypeName(type) << " for " - << SyntaxIdentifier(); + << d->full_name(); return nullptr; } @@ -3226,7 +3226,7 @@ BinaryAndJsonConformanceSuiteImpl::GetFieldForMapType( ABSL_LOG(FATAL) << "Couldn't find map field with type: " << FieldDescriptor::TypeName(key_type) << " and " << FieldDescriptor::TypeName(key_type) << " for " - << SyntaxIdentifier(); + << d->full_name(); return nullptr; } @@ -3244,7 +3244,7 @@ BinaryAndJsonConformanceSuiteImpl::GetFieldForOneofType( ABSL_LOG(FATAL) << "Couldn't find oneof field with type: " << FieldDescriptor::TypeName(type) << " for " - << SyntaxIdentifier(); + << d->full_name(); return nullptr; } diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index fc80ec6d0f..94efbcc466 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -141,22 +141,22 @@ ConformanceTestSuite::ConformanceRequestSetting::NewTestMessage() const { return std::unique_ptr(prototype_message_for_compare_->New()); } -std::string ConformanceTestSuite::ConformanceRequestSetting::GetTestName() - const { - std::string rname; +std::string +ConformanceTestSuite::ConformanceRequestSetting::GetSyntaxIdentifier() const { switch (FileDescriptorLegacy(prototype_message_.GetDescriptor()->file()) .syntax()) { case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3: - rname = ".Proto3."; - break; + return "Proto3"; case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2: - rname = ".Proto2."; - break; + return "Proto2"; default: - break; + return "Unknown"; } +} - return absl::StrCat(ConformanceLevelToString(level_), rname, +string ConformanceTestSuite::ConformanceRequestSetting::GetTestName() const { + return absl::StrCat(ConformanceLevelToString(level_), ".", + GetSyntaxIdentifier(), ".", InputFormatString(input_format_), ".", test_name_, ".", OutputFormatString(output_format_)); } diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index bdc7a697fe..00559d9e1a 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -19,6 +19,7 @@ #include #include +#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/util/type_resolver.h" #include "absl/container/btree_set.h" #include "absl/container/flat_hash_set.h" @@ -200,6 +201,8 @@ class ConformanceTestSuite { std::unique_ptr NewTestMessage() const; + std::string GetSyntaxIdentifier() const; + std::string GetTestName() const; const conformance::ConformanceRequest& GetRequest() const { diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index fb0ca1f6d5..ae39296917 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -12,19 +12,18 @@ #include #include "absl/log/absl_log.h" +#include "absl/log/die_if_null.h" #include "absl/strings/str_cat.h" #include "conformance_test.h" #include "google/protobuf/test_messages_proto2.pb.h" #include "google/protobuf/test_messages_proto3.pb.h" #include "google/protobuf/text_format.h" -namespace proto2_messages = protobuf_test_messages::proto2; - using conformance::ConformanceRequest; using conformance::ConformanceResponse; using conformance::WireFormat; -using proto2_messages::TestAllTypesProto2; -using proto2_messages::UnknownToTestAllTypes; +using protobuf_test_messages::proto2::TestAllTypesProto2; +using protobuf_test_messages::proto2::UnknownToTestAllTypes; using protobuf_test_messages::proto3::TestAllTypesProto3; namespace google { @@ -111,10 +110,35 @@ bool TextFormatConformanceTestSuite::ParseResponse( return true; } -void TextFormatConformanceTestSuite::ExpectParseFailure( +void TextFormatConformanceTestSuite::RunSuiteImpl() { + TextFormatConformanceTestSuiteImpl(this); + TextFormatConformanceTestSuiteImpl(this); +} + +template +TextFormatConformanceTestSuiteImpl:: + TextFormatConformanceTestSuiteImpl(TextFormatConformanceTestSuite* suite) + : suite_(*ABSL_DIE_IF_NULL(suite)) { + // Flag control performance tests to keep them internal and opt-in only + if (suite_.performance_) { + RunTextFormatPerformanceTests(); + } else { + if (MessageType::GetDescriptor()->name() == "TestAllTypesProto2") { + RunGroupTests(); + } + if (MessageType::GetDescriptor()->name() == "TestAllTypesProto3") { + RunAnyTests(); + // TODO Run these over proto2 also. + RunAllTests(); + } + } +} + +template +void TextFormatConformanceTestSuiteImpl::ExpectParseFailure( const std::string& test_name, ConformanceLevel level, const std::string& input) { - TestAllTypesProto3 prototype; + MessageType prototype; // We don't expect output, but if the program erroneously accepts the protobuf // we let it send its response as this. We must not leave it unspecified. ConformanceRequestSetting setting( @@ -122,89 +146,75 @@ void TextFormatConformanceTestSuite::ExpectParseFailure( conformance::TEXT_FORMAT_TEST, prototype, test_name, input); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - std::string effective_test_name = - absl::StrCat(setting.ConformanceLevelToString(level), - ".Proto3.TextFormatInput.", test_name); + std::string effective_test_name = absl::StrCat( + setting.ConformanceLevelToString(level), ".", + setting.GetSyntaxIdentifier(), ".TextFormatInput.", test_name); - RunTest(effective_test_name, request, &response); + suite_.RunTest(effective_test_name, request, &response); if (response.result_case() == ConformanceResponse::kParseError) { - ReportSuccess(effective_test_name); + suite_.ReportSuccess(effective_test_name); } else if (response.result_case() == ConformanceResponse::kSkipped) { - ReportSkip(effective_test_name, request, response); + suite_.ReportSkip(effective_test_name, request, response); } else { - ReportFailure(effective_test_name, level, request, response, - "Should have failed to parse, but didn't."); + suite_.ReportFailure(effective_test_name, level, request, response, + "Should have failed to parse, but didn't."); } } -void TextFormatConformanceTestSuite::RunValidTextFormatTest( +template +void TextFormatConformanceTestSuiteImpl::RunValidTextFormatTest( const std::string& test_name, ConformanceLevel level, const std::string& input_text) { - TestAllTypesProto3 prototype; + MessageType prototype; RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype); } -void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2( - const std::string& test_name, ConformanceLevel level, - const std::string& input_text) { - TestAllTypesProto2 prototype; - RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype); -} - -void TextFormatConformanceTestSuite::RunValidTextFormatTestWithExpected( - const std::string& test_name, ConformanceLevel level, - const std::string& input_text, const std::string& expected_text) { - TestAllTypesProto3 prototype; - RunValidTextFormatTestWithMessage(test_name, level, input_text, expected_text, - prototype); -} - -void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2WithExpected( - const std::string& test_name, ConformanceLevel level, - const std::string& input_text, const std::string& expected_text) { - TestAllTypesProto2 prototype; - RunValidTextFormatTestWithMessage(test_name, level, input_text, expected_text, - prototype); -} - -void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage( - const std::string& test_name, ConformanceLevel level, - const std::string& input_text, const Message& prototype) { +template +void TextFormatConformanceTestSuiteImpl:: + RunValidTextFormatTestWithMessage(const std::string& test_name, + ConformanceLevel level, + const std::string& input_text, + const Message& message) { ConformanceRequestSetting setting1( level, conformance::TEXT_FORMAT, conformance::PROTOBUF, - conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text); - RunValidInputTest(setting1, input_text); + conformance::TEXT_FORMAT_TEST, message, test_name, input_text); + suite_.RunValidInputTest(setting1, input_text); ConformanceRequestSetting setting2( level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT, - conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text); - RunValidInputTest(setting2, input_text); + conformance::TEXT_FORMAT_TEST, message, test_name, input_text); + suite_.RunValidInputTest(setting2, input_text); } -void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage( - const std::string& test_name, ConformanceLevel level, - const std::string& input_text, const std::string& expected_text, - const Message& prototype) { +template +void TextFormatConformanceTestSuiteImpl:: + RunValidTextFormatTestWithExpected(const std::string& test_name, + ConformanceLevel level, + const std::string& input_text, + const std::string& expected_text) { + MessageType prototype; ConformanceRequestSetting setting1( level, conformance::TEXT_FORMAT, conformance::PROTOBUF, conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text); - RunValidInputTest(setting1, expected_text); + suite_.RunValidInputTest(setting1, expected_text); ConformanceRequestSetting setting2( level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text); - RunValidInputTest(setting2, expected_text); + suite_.RunValidInputTest(setting2, expected_text); } -void TextFormatConformanceTestSuite::RunValidUnknownTextFormatTest( - const std::string& test_name, const Message& message) { +template +void TextFormatConformanceTestSuiteImpl< + MessageType>::RunValidUnknownTextFormatTest(const std::string& test_name, + const Message& message) { std::string serialized_input; message.SerializeToString(&serialized_input); - TestAllTypesProto3 prototype; + MessageType prototype; ConformanceRequestSetting setting1( RECOMMENDED, conformance::PROTOBUF, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT_TEST, prototype, absl::StrCat(test_name, "_Drop"), serialized_input); setting1.SetPrototypeMessageForCompare(message); - RunValidBinaryInputTest(setting1, ""); + suite_.RunValidBinaryInputTest(setting1, ""); ConformanceRequestSetting setting2( RECOMMENDED, conformance::PROTOBUF, conformance::TEXT_FORMAT, @@ -212,207 +222,182 @@ void TextFormatConformanceTestSuite::RunValidUnknownTextFormatTest( absl::StrCat(test_name, "_Print"), serialized_input); setting2.SetPrototypeMessageForCompare(message); setting2.SetPrintUnknownFields(true); - RunValidBinaryInputTest(setting2, serialized_input); + suite_.RunValidBinaryInputTest(setting2, serialized_input); } -void TextFormatConformanceTestSuite::RunSuiteImpl() { - if (!performance_) { - RunValidTextFormatTest("HelloWorld", REQUIRED, - "optional_string: 'Hello, World!'"); - // Integer fields. - RunValidTextFormatTest("Int32FieldMaxValue", REQUIRED, - "optional_int32: 2147483647"); - RunValidTextFormatTest("Int32FieldMinValue", REQUIRED, - "optional_int32: -2147483648"); - RunValidTextFormatTest("Uint32FieldMaxValue", REQUIRED, - "optional_uint32: 4294967295"); - RunValidTextFormatTest("Int64FieldMaxValue", REQUIRED, - "optional_int64: 9223372036854775807"); - RunValidTextFormatTest("Int64FieldMinValue", REQUIRED, - "optional_int64: -9223372036854775808"); - RunValidTextFormatTest("Uint64FieldMaxValue", REQUIRED, - "optional_uint64: 18446744073709551615"); - - // Parsers reject out-of-bound integer values. - ExpectParseFailure("Int32FieldTooLarge", REQUIRED, - "optional_int32: 2147483648"); - ExpectParseFailure("Int32FieldTooSmall", REQUIRED, - "optional_int32: -2147483649"); - ExpectParseFailure("Uint32FieldTooLarge", REQUIRED, - "optional_uint32: 4294967296"); - ExpectParseFailure("Int64FieldTooLarge", REQUIRED, - "optional_int64: 9223372036854775808"); - ExpectParseFailure("Int64FieldTooSmall", REQUIRED, - "optional_int64: -9223372036854775809"); - ExpectParseFailure("Uint64FieldTooLarge", REQUIRED, - "optional_uint64: 18446744073709551616"); - - // Floating point fields - RunValidTextFormatTest("FloatField", REQUIRED, "optional_float: 3.192837"); - RunValidTextFormatTest("FloatFieldWithVeryPreciseNumber", REQUIRED, - "optional_float: 3.123456789123456789"); - RunValidTextFormatTest("FloatFieldMaxValue", REQUIRED, - "optional_float: 3.4028235e+38"); - RunValidTextFormatTest("FloatFieldMinValue", REQUIRED, - "optional_float: 1.17549e-38"); - RunValidTextFormatTest("FloatFieldNaNValue", REQUIRED, - "optional_float: NaN"); - RunValidTextFormatTest("FloatFieldPosInfValue", REQUIRED, - "optional_float: inf"); - RunValidTextFormatTest("FloatFieldNegInfValue", REQUIRED, - "optional_float: -inf"); - RunValidTextFormatTest("FloatFieldWithInt32Max", REQUIRED, - "optional_float: 4294967296"); - RunValidTextFormatTest("FloatFieldLargerThanInt64", REQUIRED, - "optional_float: 9223372036854775808"); - RunValidTextFormatTest("FloatFieldTooLarge", REQUIRED, - "optional_float: 3.4028235e+39"); - RunValidTextFormatTest("FloatFieldTooSmall", REQUIRED, - "optional_float: 1.17549e-39"); - RunValidTextFormatTest("FloatFieldLargerThanUint64", REQUIRED, - "optional_float: 18446744073709551616"); - - // String literals x {Strings, Bytes} - for (const auto& field_type : std::vector{"String", "Bytes"}) { - const std::string field_name = - field_type == "String" ? "optional_string" : "optional_bytes"; - RunValidTextFormatTest( - absl::StrCat("StringLiteralConcat", field_type), REQUIRED, - absl::StrCat(field_name, ": 'first' \"second\"\n'third'")); - RunValidTextFormatTest( - absl::StrCat("StringLiteralBasicEscapes", field_type), REQUIRED, - absl::StrCat(field_name, ": '\\a\\b\\f\\n\\r\\t\\v\\?\\\\\\'\\\"'")); - RunValidTextFormatTest( - absl::StrCat("StringLiteralOctalEscapes", field_type), REQUIRED, - absl::StrCat(field_name, ": '\\341\\210\\264'")); - RunValidTextFormatTest( - absl::StrCat("StringLiteralHexEscapes", field_type), REQUIRED, - absl::StrCat(field_name, ": '\\xe1\\x88\\xb4'")); - RunValidTextFormatTest( - absl::StrCat("StringLiteralShortUnicodeEscape", field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\u1234'")); - RunValidTextFormatTest( - absl::StrCat("StringLiteralLongUnicodeEscapes", field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\U00001234\\U00010437'")); - // String literals don't include line feeds. - ExpectParseFailure( - absl::StrCat("StringLiteralIncludesLF", field_type), REQUIRED, - absl::StrCat(field_name, ": 'first line\nsecond line'")); - // Unicode escapes don't include code points that lie beyond the planes - // (> 0x10ffff). - ExpectParseFailure( - absl::StrCat("StringLiteralLongUnicodeEscapeTooLarge", field_type), - REQUIRED, absl::StrCat(field_name, ": '\\U00110000'")); - // Unicode escapes don't include surrogates. - ExpectParseFailure( - absl::StrCat("StringLiteralShortUnicodeEscapeSurrogatePair", - field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\ud801\\udc37'")); - ExpectParseFailure( - absl::StrCat("StringLiteralShortUnicodeEscapeSurrogateFirstOnly", - field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\ud800'")); - ExpectParseFailure( - absl::StrCat("StringLiteralShortUnicodeEscapeSurrogateSecondOnly", - field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\udc00'")); - ExpectParseFailure( - absl::StrCat("StringLiteralLongUnicodeEscapeSurrogateFirstOnly", - field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d800'")); - ExpectParseFailure( - absl::StrCat("StringLiteralLongUnicodeEscapeSurrogateSecondOnly", - field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\U0000dc00'")); - ExpectParseFailure( - absl::StrCat("StringLiteralLongUnicodeEscapeSurrogatePair", - field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d801\\U00000dc37'")); - ExpectParseFailure( - absl::StrCat("StringLiteralUnicodeEscapeSurrogatePairLongShort", - field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d801\\udc37'")); - ExpectParseFailure( - absl::StrCat("StringLiteralUnicodeEscapeSurrogatePairShortLong", - field_type), - RECOMMENDED, absl::StrCat(field_name, ": '\\ud801\\U0000dc37'")); - - // The following method depend on the type of field, as strings have extra - // validation. - const auto test_method = - field_type == "String" - ? &TextFormatConformanceTestSuite::ExpectParseFailure - : &TextFormatConformanceTestSuite::RunValidTextFormatTest; - - // String fields reject invalid UTF-8 byte sequences; bytes fields don't. - (this->*test_method)(absl::StrCat(field_type, "FieldBadUTF8Octal"), - REQUIRED, absl::StrCat(field_name, ": '\\300'")); - (this->*test_method)(absl::StrCat(field_type, "FieldBadUTF8Hex"), - REQUIRED, absl::StrCat(field_name, ": '\\xc0'")); - } +template +void TextFormatConformanceTestSuiteImpl::RunGroupTests() { + RunValidTextFormatTest("GroupFieldNoColon", REQUIRED, + "Data { group_int32: 1 }"); + RunValidTextFormatTest("GroupFieldWithColon", REQUIRED, + "Data: { group_int32: 1 }"); + RunValidTextFormatTest("GroupFieldEmpty", REQUIRED, "Data {}"); +} - // Group fields - RunValidTextFormatTestProto2("GroupFieldNoColon", REQUIRED, - "Data { group_int32: 1 }"); - RunValidTextFormatTestProto2("GroupFieldWithColon", REQUIRED, - "Data: { group_int32: 1 }"); - RunValidTextFormatTestProto2("GroupFieldEmpty", REQUIRED, "Data {}"); - - // Unknown Fields - UnknownToTestAllTypes message; - // Unable to print unknown Fixed32/Fixed64 fields as if they are known. - // Fixed32/Fixed64 fields are not added in the tests. - message.set_optional_int32(123); - message.set_optional_string("hello"); - message.set_optional_bool(true); - RunValidUnknownTextFormatTest("ScalarUnknownFields", message); - - message.Clear(); - message.mutable_nested_message()->set_c(111); - RunValidUnknownTextFormatTest("MessageUnknownFields", message); - - message.Clear(); - message.mutable_optionalgroup()->set_a(321); - RunValidUnknownTextFormatTest("GroupUnknownFields", message); - - message.add_repeated_int32(1); - message.add_repeated_int32(2); - message.add_repeated_int32(3); - RunValidUnknownTextFormatTest("RepeatedUnknownFields", message); - - // Any fields - RunValidTextFormatTest("AnyField", REQUIRED, - R"( - optional_any: { - [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { - optional_int32: 12345 - } - } - )"); - RunValidTextFormatTest("AnyFieldWithRawBytes", REQUIRED, - R"( - optional_any: { - type_url: "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3" - value: "\b\271`" - } - )"); - ExpectParseFailure("AnyFieldWithInvalidType", REQUIRED, - R"( - optional_any: { - [type.googleapis.com/unknown] { - optional_int32: 12345 - } - } - )"); +template +void TextFormatConformanceTestSuiteImpl::RunAllTests() { + RunValidTextFormatTest("HelloWorld", REQUIRED, + "optional_string: 'Hello, World!'"); + // Integer fields. + RunValidTextFormatTest("Int32FieldMaxValue", REQUIRED, + "optional_int32: 2147483647"); + RunValidTextFormatTest("Int32FieldMinValue", REQUIRED, + "optional_int32: -2147483648"); + RunValidTextFormatTest("Uint32FieldMaxValue", REQUIRED, + "optional_uint32: 4294967295"); + RunValidTextFormatTest("Int64FieldMaxValue", REQUIRED, + "optional_int64: 9223372036854775807"); + RunValidTextFormatTest("Int64FieldMinValue", REQUIRED, + "optional_int64: -9223372036854775808"); + RunValidTextFormatTest("Uint64FieldMaxValue", REQUIRED, + "optional_uint64: 18446744073709551615"); + + // Parsers reject out-of-bound integer values. + ExpectParseFailure("Int32FieldTooLarge", REQUIRED, + "optional_int32: 2147483648"); + ExpectParseFailure("Int32FieldTooSmall", REQUIRED, + "optional_int32: -2147483649"); + ExpectParseFailure("Uint32FieldTooLarge", REQUIRED, + "optional_uint32: 4294967296"); + ExpectParseFailure("Int64FieldTooLarge", REQUIRED, + "optional_int64: 9223372036854775808"); + ExpectParseFailure("Int64FieldTooSmall", REQUIRED, + "optional_int64: -9223372036854775809"); + ExpectParseFailure("Uint64FieldTooLarge", REQUIRED, + "optional_uint64: 18446744073709551616"); + + // Floating point fields + RunValidTextFormatTest("FloatField", REQUIRED, "optional_float: 3.192837"); + RunValidTextFormatTest("FloatFieldWithVeryPreciseNumber", REQUIRED, + "optional_float: 3.123456789123456789"); + RunValidTextFormatTest("FloatFieldMaxValue", REQUIRED, + "optional_float: 3.4028235e+38"); + RunValidTextFormatTest("FloatFieldMinValue", REQUIRED, + "optional_float: 1.17549e-38"); + RunValidTextFormatTest("FloatFieldNaNValue", REQUIRED, "optional_float: NaN"); + RunValidTextFormatTest("FloatFieldPosInfValue", REQUIRED, + "optional_float: inf"); + RunValidTextFormatTest("FloatFieldNegInfValue", REQUIRED, + "optional_float: -inf"); + RunValidTextFormatTest("FloatFieldWithInt32Max", REQUIRED, + "optional_float: 4294967296"); + RunValidTextFormatTest("FloatFieldLargerThanInt64", REQUIRED, + "optional_float: 9223372036854775808"); + RunValidTextFormatTest("FloatFieldTooLarge", REQUIRED, + "optional_float: 3.4028235e+39"); + RunValidTextFormatTest("FloatFieldTooSmall", REQUIRED, + "optional_float: 1.17549e-39"); + RunValidTextFormatTest("FloatFieldLargerThanUint64", REQUIRED, + "optional_float: 18446744073709551616"); + + // String literals x {Strings, Bytes} + for (const auto& field_type : std::vector{"String", "Bytes"}) { + const std::string field_name = + field_type == "String" ? "optional_string" : "optional_bytes"; + RunValidTextFormatTest( + absl::StrCat("StringLiteralConcat", field_type), REQUIRED, + absl::StrCat(field_name, ": 'first' \"second\"\n'third'")); + RunValidTextFormatTest( + absl::StrCat("StringLiteralBasicEscapes", field_type), REQUIRED, + absl::StrCat(field_name, ": '\\a\\b\\f\\n\\r\\t\\v\\?\\\\\\'\\\"'")); + RunValidTextFormatTest( + absl::StrCat("StringLiteralOctalEscapes", field_type), REQUIRED, + absl::StrCat(field_name, ": '\\341\\210\\264'")); + RunValidTextFormatTest(absl::StrCat("StringLiteralHexEscapes", field_type), + REQUIRED, + absl::StrCat(field_name, ": '\\xe1\\x88\\xb4'")); + RunValidTextFormatTest( + absl::StrCat("StringLiteralShortUnicodeEscape", field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\u1234'")); + RunValidTextFormatTest( + absl::StrCat("StringLiteralLongUnicodeEscapes", field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\U00001234\\U00010437'")); + // String literals don't include line feeds. + ExpectParseFailure(absl::StrCat("StringLiteralIncludesLF", field_type), + REQUIRED, + absl::StrCat(field_name, ": 'first line\nsecond line'")); + // Unicode escapes don't include code points that lie beyond the planes + // (> 0x10ffff). + ExpectParseFailure( + absl::StrCat("StringLiteralLongUnicodeEscapeTooLarge", field_type), + REQUIRED, absl::StrCat(field_name, ": '\\U00110000'")); + // Unicode escapes don't include surrogates. + ExpectParseFailure( + absl::StrCat("StringLiteralShortUnicodeEscapeSurrogatePair", + field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\ud801\\udc37'")); + ExpectParseFailure( + absl::StrCat("StringLiteralShortUnicodeEscapeSurrogateFirstOnly", + field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\ud800'")); + ExpectParseFailure( + absl::StrCat("StringLiteralShortUnicodeEscapeSurrogateSecondOnly", + field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\udc00'")); + ExpectParseFailure( + absl::StrCat("StringLiteralLongUnicodeEscapeSurrogateFirstOnly", + field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d800'")); + ExpectParseFailure( + absl::StrCat("StringLiteralLongUnicodeEscapeSurrogateSecondOnly", + field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\U0000dc00'")); + ExpectParseFailure( + absl::StrCat("StringLiteralLongUnicodeEscapeSurrogatePair", field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d801\\U00000dc37'")); + ExpectParseFailure( + absl::StrCat("StringLiteralUnicodeEscapeSurrogatePairLongShort", + field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d801\\udc37'")); + ExpectParseFailure( + absl::StrCat("StringLiteralUnicodeEscapeSurrogatePairShortLong", + field_type), + RECOMMENDED, absl::StrCat(field_name, ": '\\ud801\\U0000dc37'")); + + // The following method depend on the type of field, as strings have extra + // validation. + const auto test_method = + field_type == "String" + ? &TextFormatConformanceTestSuiteImpl::ExpectParseFailure + : &TextFormatConformanceTestSuiteImpl::RunValidTextFormatTest; + + // String fields reject invalid UTF-8 byte sequences; bytes fields don't. + (this->*test_method)(absl::StrCat(field_type, "FieldBadUTF8Octal"), + REQUIRED, absl::StrCat(field_name, ": '\\300'")); + (this->*test_method)(absl::StrCat(field_type, "FieldBadUTF8Hex"), REQUIRED, + absl::StrCat(field_name, ": '\\xc0'")); + } - // Map fields - TestAllTypesProto3 prototype; - (*prototype.mutable_map_string_string())["c"] = "value"; - (*prototype.mutable_map_string_string())["b"] = "value"; - (*prototype.mutable_map_string_string())["a"] = "value"; - RunValidTextFormatTestWithMessage("AlphabeticallySortedMapStringKeys", - REQUIRED, - R"( + // Unknown Fields + UnknownToTestAllTypes message; + // Unable to print unknown Fixed32/Fixed64 fields as if they are known. + // Fixed32/Fixed64 fields are not added in the tests. + message.set_optional_int32(123); + message.set_optional_string("hello"); + message.set_optional_bool(true); + RunValidUnknownTextFormatTest("ScalarUnknownFields", message); + + message.Clear(); + message.mutable_nested_message()->set_c(111); + RunValidUnknownTextFormatTest("MessageUnknownFields", message); + + message.Clear(); + message.mutable_optionalgroup()->set_a(321); + RunValidUnknownTextFormatTest("GroupUnknownFields", message); + + message.add_repeated_int32(1); + message.add_repeated_int32(2); + message.add_repeated_int32(3); + RunValidUnknownTextFormatTest("RepeatedUnknownFields", message); + + // Map fields + MessageType prototype; + (*prototype.mutable_map_string_string())["c"] = "value"; + (*prototype.mutable_map_string_string())["b"] = "value"; + (*prototype.mutable_map_string_string())["a"] = "value"; + RunValidTextFormatTestWithMessage("AlphabeticallySortedMapStringKeys", + REQUIRED, + R"( map_string_string { key: "a" value: "value" @@ -426,15 +411,14 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { value: "value" } )", - prototype); - - prototype.Clear(); - (*prototype.mutable_map_int32_int32())[3] = 0; - (*prototype.mutable_map_int32_int32())[2] = 0; - (*prototype.mutable_map_int32_int32())[1] = 0; - RunValidTextFormatTestWithMessage("AlphabeticallySortedMapIntKeys", - REQUIRED, - R"( + prototype); + + prototype.Clear(); + (*prototype.mutable_map_int32_int32())[3] = 0; + (*prototype.mutable_map_int32_int32())[2] = 0; + (*prototype.mutable_map_int32_int32())[1] = 0; + RunValidTextFormatTestWithMessage("AlphabeticallySortedMapIntKeys", REQUIRED, + R"( map_int32_int32 { key: 1 value: 0 @@ -448,14 +432,13 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { value: 0 } )", - prototype); - - prototype.Clear(); - (*prototype.mutable_map_bool_bool())[true] = false; - (*prototype.mutable_map_bool_bool())[false] = false; - RunValidTextFormatTestWithMessage("AlphabeticallySortedMapBoolKeys", - REQUIRED, - R"( + prototype); + + prototype.Clear(); + (*prototype.mutable_map_bool_bool())[true] = false; + (*prototype.mutable_map_bool_bool())[false] = false; + RunValidTextFormatTestWithMessage("AlphabeticallySortedMapBoolKeys", REQUIRED, + R"( map_bool_bool { key: false value: false @@ -465,12 +448,12 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { value: false } )", - prototype); + prototype); - prototype.Clear(); - ConformanceRequestSetting setting_map( - REQUIRED, conformance::TEXT_FORMAT, conformance::PROTOBUF, - conformance::TEXT_FORMAT_TEST, prototype, "DuplicateMapKey", R"( + prototype.Clear(); + ConformanceRequestSetting setting_map( + REQUIRED, conformance::TEXT_FORMAT, conformance::PROTOBUF, + conformance::TEXT_FORMAT_TEST, prototype, "DuplicateMapKey", R"( map_string_nested_message { key: "duplicate" value: { a: 123 } @@ -480,21 +463,47 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { value: { corecursive: {} } } )"); - // The last-specified value will be retained in a parsed map - RunValidInputTest(setting_map, R"( + // The last-specified value will be retained in a parsed map + suite_.RunValidInputTest(setting_map, R"( map_string_nested_message { key: "duplicate" value: { corecursive: {} } } )"); - } - // Flag control performance tests to keep them internal and opt-in only - if (performance_) { - RunTextFormatPerformanceTests(); - } } -void TextFormatConformanceTestSuite::RunTextFormatPerformanceTests() { +template +void TextFormatConformanceTestSuiteImpl::RunAnyTests() { + // Any fields + RunValidTextFormatTest("AnyField", REQUIRED, + R"( + optional_any: { + [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] + { optional_int32: 12345 + } + } + )"); + RunValidTextFormatTest("AnyFieldWithRawBytes", REQUIRED, + R"( + optional_any: { + type_url: + "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3" value: + "\b\271`" + } + )"); + ExpectParseFailure("AnyFieldWithInvalidType", REQUIRED, + R"( + optional_any: { + [type.googleapis.com/unknown] { + optional_int32: 12345 + } + } + )"); +} + +template +void TextFormatConformanceTestSuiteImpl< + MessageType>::RunTextFormatPerformanceTests() { TestTextFormatPerformanceMergeMessageWithRepeatedField("Bool", "repeated_bool: true"); TestTextFormatPerformanceMergeMessageWithRepeatedField( @@ -510,7 +519,8 @@ void TextFormatConformanceTestSuite::RunTextFormatPerformanceTests() { } // This is currently considered valid input by some languages but not others -void TextFormatConformanceTestSuite:: +template +void TextFormatConformanceTestSuiteImpl:: TestTextFormatPerformanceMergeMessageWithRepeatedField( const std::string& test_type_name, const std::string& message_field) { std::string recursive_message = @@ -527,13 +537,9 @@ void TextFormatConformanceTestSuite:: } absl::StrAppend(&expected, "}"); - RunValidTextFormatTestProto2WithExpected( - absl::StrCat("TestTextFormatPerformanceMergeMessageWithRepeatedField", - test_type_name, "Proto2"), - RECOMMENDED, input, expected); RunValidTextFormatTestWithExpected( absl::StrCat("TestTextFormatPerformanceMergeMessageWithRepeatedField", - test_type_name, "Proto3"), + test_type_name), RECOMMENDED, input, expected); } diff --git a/conformance/text_format_conformance_suite.h b/conformance/text_format_conformance_suite.h index 1917ee565b..27de29e13a 100644 --- a/conformance/text_format_conformance_suite.h +++ b/conformance/text_format_conformance_suite.h @@ -22,41 +22,55 @@ class TextFormatConformanceTestSuite : public ConformanceTestSuite { private: void RunSuiteImpl() override; + + bool ParseTextFormatResponse(const conformance::ConformanceResponse& response, + const ConformanceRequestSetting& setting, + Message* test_message); + bool ParseResponse(const conformance::ConformanceResponse& response, + const ConformanceRequestSetting& setting, + Message* test_message) override; + + template + friend class TextFormatConformanceTestSuiteImpl; +}; + +template +class TextFormatConformanceTestSuiteImpl { + public: + explicit TextFormatConformanceTestSuiteImpl( + TextFormatConformanceTestSuite* suite); + + private: + using ConformanceRequestSetting = + TextFormatConformanceTestSuite::ConformanceRequestSetting; + using ConformanceLevel = TextFormatConformanceTestSuite::ConformanceLevel; + constexpr static ConformanceLevel RECOMMENDED = ConformanceLevel::RECOMMENDED; + constexpr static ConformanceLevel REQUIRED = ConformanceLevel::REQUIRED; + + void RunAllTests(); + + void RunGroupTests(); + void RunAnyTests(); + void RunTextFormatPerformanceTests(); void RunValidTextFormatTest(const std::string& test_name, ConformanceLevel level, const std::string& input); - void RunValidTextFormatTestProto2(const std::string& test_name, - ConformanceLevel level, - const std::string& input); void RunValidTextFormatTestWithExpected(const std::string& test_name, ConformanceLevel level, - const std::string& input, - const std::string& expected); - void RunValidTextFormatTestProto2WithExpected(const std::string& test_name, - ConformanceLevel level, - const std::string& input, - const std::string& expected); - void RunValidTextFormatTestWithMessage(const std::string& test_name, - ConformanceLevel level, - const std::string& input_text, - const Message& prototype); + const std::string& input_text, + const std::string& expected_text); + void RunValidUnknownTextFormatTest(const std::string& test_name, + const Message& message); void RunValidTextFormatTestWithMessage(const std::string& test_name, ConformanceLevel level, const std::string& input_text, - const std::string& expected_text, - const Message& prototype); - void RunValidUnknownTextFormatTest(const std::string& test_name, - const Message& message); + const Message& message); void ExpectParseFailure(const std::string& test_name, ConformanceLevel level, const std::string& input); - bool ParseTextFormatResponse(const conformance::ConformanceResponse& response, - const ConformanceRequestSetting& setting, - Message* test_message); - bool ParseResponse(const conformance::ConformanceResponse& response, - const ConformanceRequestSetting& setting, - Message* test_message) override; void TestTextFormatPerformanceMergeMessageWithRepeatedField( const std::string& test_type_name, const std::string& message_field); + + TextFormatConformanceTestSuite& suite_; }; } // namespace protobuf From 2b26c00aa178a504e0630d330742b9c22be4ef4e Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 18 Oct 2023 07:39:29 -0700 Subject: [PATCH 21/95] Clarify comments on GetResolvedSourceFeatures PiperOrigin-RevId: 574472013 --- src/google/protobuf/compiler/code_generator.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index b8bc3792d0..7ce2cfba72 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -135,9 +135,9 @@ class PROTOC_EXPORT CodeGenerator { protected: // Retrieves the resolved source features for a given descriptor. All the - // features that are imported (from the proto file) and linked in (from the - // callers binary) will be fully resolved. These should be used to make any - // feature-based decisions during code generation. + // global features and language features returned by GetFeatureExtensions will + // be fully resolved. These should be used to make any feature-based decisions + // during code generation. template static const FeatureSet& GetResolvedSourceFeatures(const DescriptorT& desc) { return ::google::protobuf::internal::InternalFeatureHelper::GetFeatures(desc); From 0aeb4099816fa20d9aa04b1392fc1866cdc7eb8f Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 18 Oct 2023 08:02:26 -0700 Subject: [PATCH 22/95] Automated rollback of commit e699aa601a30add5a4c86844eedb941d49afbbb2. PiperOrigin-RevId: 574477310 --- src/google/protobuf/compiler/python/pyi_generator.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/google/protobuf/compiler/python/pyi_generator.cc b/src/google/protobuf/compiler/python/pyi_generator.cc index 13b67d2bc0..35a4e4ec2d 100644 --- a/src/google/protobuf/compiler/python/pyi_generator.cc +++ b/src/google/protobuf/compiler/python/pyi_generator.cc @@ -17,6 +17,7 @@ #include "absl/strings/ascii.h" #include "absl/strings/match.h" #include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "google/protobuf/compiler/python/helpers.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" From c3031091411ce66d62abd56309f15a6497722dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Sad=C5=82ocha?= Date: Wed, 18 Oct 2023 08:34:52 -0700 Subject: [PATCH 23/95] Implement mutators for singular primitive fields with presence PiperOrigin-RevId: 574485191 --- rust/internal.rs | 4 +- rust/primitive.rs | 35 ++- rust/test/shared/accessors_test.rs | 297 ++++++++++++++++++ rust/vtable.rs | 55 ++++ .../rust/accessors/singular_scalar.cc | 100 +++++- 5 files changed, 484 insertions(+), 7 deletions(-) diff --git a/rust/internal.rs b/rust/internal.rs index e56c9dc555..d7ea96baaf 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -10,8 +10,8 @@ //! generated code. pub use crate::vtable::{ - new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, PrimitiveVTable, - RawVTableMutator, + new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, PrimitiveOptionalMutVTable, + PrimitiveVTable, RawVTableMutator, }; use std::ptr::NonNull; use std::slice; diff --git a/rust/primitive.rs b/rust/primitive.rs index 220b84e469..e69afe66f4 100644 --- a/rust/primitive.rs +++ b/rust/primitive.rs @@ -7,8 +7,11 @@ use crate::__internal::Private; use crate::__runtime::InnerPrimitiveMut; -use crate::vtable::{PrimitiveVTable, ProxiedWithRawVTable}; -use crate::{Mut, MutProxy, Proxied, SettableValue, View, ViewProxy}; +use crate::vtable::{ + PrimitiveOptionalMutVTable, PrimitiveVTable, ProxiedWithRawOptionalVTable, + ProxiedWithRawVTable, RawVTableOptionalMutatorData, +}; +use crate::{Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy}; #[derive(Debug)] pub struct PrimitiveMut<'a, T: ProxiedWithRawVTable> { @@ -104,6 +107,34 @@ macro_rules! impl_singular_primitives { PrimitiveMut::from_inner(Private, inner) } } + + impl ProxiedWithPresence for $t { + type PresentMutData<'a> = RawVTableOptionalMutatorData<'a, $t>; + type AbsentMutData<'a> = RawVTableOptionalMutatorData<'a, $t>; + + fn clear_present_field( + present_mutator: Self::PresentMutData<'_>, + ) -> Self::AbsentMutData<'_> { + present_mutator.clear() + } + + fn set_absent_to_default( + absent_mutator: Self::AbsentMutData<'_>, + ) -> Self::PresentMutData<'_> { + absent_mutator.set_absent_to_default() + } + } + + impl ProxiedWithRawOptionalVTable for $t { + type OptionalVTable = PrimitiveOptionalMutVTable<$t>; + + fn upcast_vtable( + _private: Private, + optional_vtable: &'static Self::OptionalVTable, + ) -> &'static Self::VTable { + &optional_vtable.base + } + } )* } } diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs index 910f9f133e..ef33f21bf3 100644 --- a/rust/test/shared/accessors_test.rs +++ b/rust/test/shared/accessors_test.rs @@ -51,6 +51,33 @@ fn test_optional_fixed32_accessors() { assert_that!(msg.optional_fixed32(), eq(0)); } +#[test] +fn test_default_fixed32_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_fixed32(), eq(47)); + assert_that!(msg.default_fixed32_mut().get(), eq(47)); + assert_that!(msg.default_fixed32_mut().is_set(), eq(false)); + assert_that!(msg.default_fixed32_opt(), eq(Optional::Unset(47))); + + msg.default_fixed32_mut().set(999); + assert_that!(msg.default_fixed32(), eq(999)); + assert_that!(msg.default_fixed32_mut().get(), eq(999)); + assert_that!(msg.default_fixed32_mut().is_set(), eq(true)); + assert_that!(msg.default_fixed32_opt(), eq(Optional::Set(999))); + + msg.default_fixed32_mut().clear(); + assert_that!(msg.default_fixed32(), eq(47)); + assert_that!(msg.default_fixed32_mut().get(), eq(47)); + assert_that!(msg.default_fixed32_mut().is_set(), eq(false)); + assert_that!(msg.default_fixed32_opt(), eq(Optional::Unset(47))); + + msg.default_fixed32_mut().or_default(); + assert_that!(msg.default_fixed32(), eq(47)); + assert_that!(msg.default_fixed32_mut().get(), eq(47)); + assert_that!(msg.default_fixed32_mut().is_set(), eq(true)); + assert_that!(msg.default_fixed32_opt(), eq(Optional::Set(47))); +} + #[test] fn test_optional_fixed64_accessors() { let mut msg = TestAllTypes::new(); @@ -66,6 +93,33 @@ fn test_optional_fixed64_accessors() { assert_that!(msg.optional_fixed64(), eq(0)); } +#[test] +fn test_default_fixed64_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_fixed64(), eq(48)); + assert_that!(msg.default_fixed64_mut().get(), eq(48)); + assert_that!(msg.default_fixed64_mut().is_set(), eq(false)); + assert_that!(msg.default_fixed64_opt(), eq(Optional::Unset(48))); + + msg.default_fixed64_mut().set(999); + assert_that!(msg.default_fixed64(), eq(999)); + assert_that!(msg.default_fixed64_mut().get(), eq(999)); + assert_that!(msg.default_fixed64_mut().is_set(), eq(true)); + assert_that!(msg.default_fixed64_opt(), eq(Optional::Set(999))); + + msg.default_fixed64_mut().clear(); + assert_that!(msg.default_fixed64(), eq(48)); + assert_that!(msg.default_fixed64_mut().get(), eq(48)); + assert_that!(msg.default_fixed64_mut().is_set(), eq(false)); + assert_that!(msg.default_fixed64_opt(), eq(Optional::Unset(48))); + + msg.default_fixed64_mut().or_default(); + assert_that!(msg.default_fixed64(), eq(48)); + assert_that!(msg.default_fixed64_mut().get(), eq(48)); + assert_that!(msg.default_fixed64_mut().is_set(), eq(true)); + assert_that!(msg.default_fixed64_opt(), eq(Optional::Set(48))); +} + #[test] fn test_optional_int32_accessors() { let mut msg = TestAllTypes::new(); @@ -81,6 +135,33 @@ fn test_optional_int32_accessors() { assert_that!(msg.optional_int32(), eq(0)); } +#[test] +fn test_default_int32_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_int32(), eq(41)); + assert_that!(msg.default_int32_mut().get(), eq(41)); + assert_that!(msg.default_int32_mut().is_set(), eq(false)); + assert_that!(msg.default_int32_opt(), eq(Optional::Unset(41))); + + msg.default_int32_mut().set(999); + assert_that!(msg.default_int32(), eq(999)); + assert_that!(msg.default_int32_mut().get(), eq(999)); + assert_that!(msg.default_int32_mut().is_set(), eq(true)); + assert_that!(msg.default_int32_opt(), eq(Optional::Set(999))); + + msg.default_int32_mut().clear(); + assert_that!(msg.default_int32(), eq(41)); + assert_that!(msg.default_int32_mut().get(), eq(41)); + assert_that!(msg.default_int32_mut().is_set(), eq(false)); + assert_that!(msg.default_int32_opt(), eq(Optional::Unset(41))); + + msg.default_int32_mut().or_default(); + assert_that!(msg.default_int32(), eq(41)); + assert_that!(msg.default_int32_mut().get(), eq(41)); + assert_that!(msg.default_int32_mut().is_set(), eq(true)); + assert_that!(msg.default_int32_opt(), eq(Optional::Set(41))); +} + #[test] fn test_optional_int64_accessors() { let mut msg = TestAllTypes::new(); @@ -96,6 +177,33 @@ fn test_optional_int64_accessors() { assert_that!(msg.optional_int64(), eq(0)); } +#[test] +fn test_default_int64_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_int64(), eq(42)); + assert_that!(msg.default_int64_mut().get(), eq(42)); + assert_that!(msg.default_int64_mut().is_set(), eq(false)); + assert_that!(msg.default_int64_opt(), eq(Optional::Unset(42))); + + msg.default_int64_mut().set(999); + assert_that!(msg.default_int64(), eq(999)); + assert_that!(msg.default_int64_mut().get(), eq(999)); + assert_that!(msg.default_int64_mut().is_set(), eq(true)); + assert_that!(msg.default_int64_opt(), eq(Optional::Set(999))); + + msg.default_int64_mut().clear(); + assert_that!(msg.default_int64(), eq(42)); + assert_that!(msg.default_int64_mut().get(), eq(42)); + assert_that!(msg.default_int64_mut().is_set(), eq(false)); + assert_that!(msg.default_int64_opt(), eq(Optional::Unset(42))); + + msg.default_int64_mut().or_default(); + assert_that!(msg.default_int64(), eq(42)); + assert_that!(msg.default_int64_mut().get(), eq(42)); + assert_that!(msg.default_int64_mut().is_set(), eq(true)); + assert_that!(msg.default_int64_opt(), eq(Optional::Set(42))); +} + #[test] fn test_optional_sint32_accessors() { let mut msg = TestAllTypes::new(); @@ -111,6 +219,33 @@ fn test_optional_sint32_accessors() { assert_that!(msg.optional_sint32(), eq(0)); } +#[test] +fn test_default_sint32_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_sint32(), eq(-45)); + assert_that!(msg.default_sint32_mut().get(), eq(-45)); + assert_that!(msg.default_sint32_mut().is_set(), eq(false)); + assert_that!(msg.default_sint32_opt(), eq(Optional::Unset(-45))); + + msg.default_sint32_mut().set(999); + assert_that!(msg.default_sint32(), eq(999)); + assert_that!(msg.default_sint32_mut().get(), eq(999)); + assert_that!(msg.default_sint32_mut().is_set(), eq(true)); + assert_that!(msg.default_sint32_opt(), eq(Optional::Set(999))); + + msg.default_sint32_mut().clear(); + assert_that!(msg.default_sint32(), eq(-45)); + assert_that!(msg.default_sint32_mut().get(), eq(-45)); + assert_that!(msg.default_sint32_mut().is_set(), eq(false)); + assert_that!(msg.default_sint32_opt(), eq(Optional::Unset(-45))); + + msg.default_sint32_mut().or_default(); + assert_that!(msg.default_sint32(), eq(-45)); + assert_that!(msg.default_sint32_mut().get(), eq(-45)); + assert_that!(msg.default_sint32_mut().is_set(), eq(true)); + assert_that!(msg.default_sint32_opt(), eq(Optional::Set(-45))); +} + #[test] fn test_optional_sint64_accessors() { let mut msg = TestAllTypes::new(); @@ -126,6 +261,33 @@ fn test_optional_sint64_accessors() { assert_that!(msg.optional_sint64(), eq(0)); } +#[test] +fn test_default_sint64_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_sint64(), eq(46)); + assert_that!(msg.default_sint64_mut().get(), eq(46)); + assert_that!(msg.default_sint64_mut().is_set(), eq(false)); + assert_that!(msg.default_sint64_opt(), eq(Optional::Unset(46))); + + msg.default_sint64_mut().set(999); + assert_that!(msg.default_sint64(), eq(999)); + assert_that!(msg.default_sint64_mut().get(), eq(999)); + assert_that!(msg.default_sint64_mut().is_set(), eq(true)); + assert_that!(msg.default_sint64_opt(), eq(Optional::Set(999))); + + msg.default_sint64_mut().clear(); + assert_that!(msg.default_sint64(), eq(46)); + assert_that!(msg.default_sint64_mut().get(), eq(46)); + assert_that!(msg.default_sint64_mut().is_set(), eq(false)); + assert_that!(msg.default_sint64_opt(), eq(Optional::Unset(46))); + + msg.default_sint64_mut().or_default(); + assert_that!(msg.default_sint64(), eq(46)); + assert_that!(msg.default_sint64_mut().get(), eq(46)); + assert_that!(msg.default_sint64_mut().is_set(), eq(true)); + assert_that!(msg.default_sint64_opt(), eq(Optional::Set(46))); +} + #[test] fn test_optional_uint32_accessors() { let mut msg = TestAllTypes::new(); @@ -141,6 +303,33 @@ fn test_optional_uint32_accessors() { assert_that!(msg.optional_uint32(), eq(0)); } +#[test] +fn test_default_uint32_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_uint32(), eq(43)); + assert_that!(msg.default_uint32_mut().get(), eq(43)); + assert_that!(msg.default_uint32_mut().is_set(), eq(false)); + assert_that!(msg.default_uint32_opt(), eq(Optional::Unset(43))); + + msg.default_uint32_mut().set(999); + assert_that!(msg.default_uint32(), eq(999)); + assert_that!(msg.default_uint32_mut().get(), eq(999)); + assert_that!(msg.default_uint32_mut().is_set(), eq(true)); + assert_that!(msg.default_uint32_opt(), eq(Optional::Set(999))); + + msg.default_uint32_mut().clear(); + assert_that!(msg.default_uint32(), eq(43)); + assert_that!(msg.default_uint32_mut().get(), eq(43)); + assert_that!(msg.default_uint32_mut().is_set(), eq(false)); + assert_that!(msg.default_uint32_opt(), eq(Optional::Unset(43))); + + msg.default_uint32_mut().or_default(); + assert_that!(msg.default_uint32(), eq(43)); + assert_that!(msg.default_uint32_mut().get(), eq(43)); + assert_that!(msg.default_uint32_mut().is_set(), eq(true)); + assert_that!(msg.default_uint32_opt(), eq(Optional::Set(43))); +} + #[test] fn test_optional_uint64_accessors() { let mut msg = TestAllTypes::new(); @@ -156,6 +345,33 @@ fn test_optional_uint64_accessors() { assert_that!(msg.optional_uint64(), eq(0)); } +#[test] +fn test_default_uint64_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_uint64(), eq(44)); + assert_that!(msg.default_uint64_mut().get(), eq(44)); + assert_that!(msg.default_uint64_mut().is_set(), eq(false)); + assert_that!(msg.default_uint64_opt(), eq(Optional::Unset(44))); + + msg.default_uint64_mut().set(999); + assert_that!(msg.default_uint64(), eq(999)); + assert_that!(msg.default_uint64_mut().get(), eq(999)); + assert_that!(msg.default_uint64_mut().is_set(), eq(true)); + assert_that!(msg.default_uint64_opt(), eq(Optional::Set(999))); + + msg.default_uint64_mut().clear(); + assert_that!(msg.default_uint64(), eq(44)); + assert_that!(msg.default_uint64_mut().get(), eq(44)); + assert_that!(msg.default_uint64_mut().is_set(), eq(false)); + assert_that!(msg.default_uint64_opt(), eq(Optional::Unset(44))); + + msg.default_uint64_mut().or_default(); + assert_that!(msg.default_uint64(), eq(44)); + assert_that!(msg.default_uint64_mut().get(), eq(44)); + assert_that!(msg.default_uint64_mut().is_set(), eq(true)); + assert_that!(msg.default_uint64_opt(), eq(Optional::Set(44))); +} + #[test] fn test_optional_float_accessors() { let mut msg = TestAllTypes::new(); @@ -171,6 +387,33 @@ fn test_optional_float_accessors() { assert_that!(msg.optional_float(), eq(0.0)); } +#[test] +fn test_default_float_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_float(), eq(51.5)); + assert_that!(msg.default_float_mut().get(), eq(51.5)); + assert_that!(msg.default_float_mut().is_set(), eq(false)); + assert_that!(msg.default_float_opt(), eq(Optional::Unset(51.5))); + + msg.default_float_mut().set(999.9); + assert_that!(msg.default_float(), eq(999.9)); + assert_that!(msg.default_float_mut().get(), eq(999.9)); + assert_that!(msg.default_float_mut().is_set(), eq(true)); + assert_that!(msg.default_float_opt(), eq(Optional::Set(999.9))); + + msg.default_float_mut().clear(); + assert_that!(msg.default_float(), eq(51.5)); + assert_that!(msg.default_float_mut().get(), eq(51.5)); + assert_that!(msg.default_float_mut().is_set(), eq(false)); + assert_that!(msg.default_float_opt(), eq(Optional::Unset(51.5))); + + msg.default_float_mut().or_default(); + assert_that!(msg.default_float(), eq(51.5)); + assert_that!(msg.default_float_mut().get(), eq(51.5)); + assert_that!(msg.default_float_mut().is_set(), eq(true)); + assert_that!(msg.default_float_opt(), eq(Optional::Set(51.5))); +} + #[test] fn test_optional_double_accessors() { let mut msg = TestAllTypes::new(); @@ -186,6 +429,33 @@ fn test_optional_double_accessors() { assert_that!(msg.optional_double(), eq(0.0)); } +#[test] +fn test_default_double_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_double(), eq(52e3)); + assert_that!(msg.default_double_mut().get(), eq(52e3)); + assert_that!(msg.default_double_mut().is_set(), eq(false)); + assert_that!(msg.default_double_opt(), eq(Optional::Unset(52e3))); + + msg.default_double_mut().set(999.9); + assert_that!(msg.default_double(), eq(999.9)); + assert_that!(msg.default_double_mut().get(), eq(999.9)); + assert_that!(msg.default_double_mut().is_set(), eq(true)); + assert_that!(msg.default_double_opt(), eq(Optional::Set(999.9))); + + msg.default_double_mut().clear(); + assert_that!(msg.default_double(), eq(52e3)); + assert_that!(msg.default_double_mut().get(), eq(52e3)); + assert_that!(msg.default_double_mut().is_set(), eq(false)); + assert_that!(msg.default_double_opt(), eq(Optional::Unset(52e3))); + + msg.default_double_mut().or_default(); + assert_that!(msg.default_double(), eq(52e3)); + assert_that!(msg.default_double_mut().get(), eq(52e3)); + assert_that!(msg.default_double_mut().is_set(), eq(true)); + assert_that!(msg.default_double_opt(), eq(Optional::Set(52e3))); +} + #[test] fn test_optional_bool_accessors() { let mut msg = TestAllTypes::new(); @@ -198,6 +468,33 @@ fn test_optional_bool_accessors() { assert_that!(msg.optional_bool_opt(), eq(Optional::Unset(false))); } +#[test] +fn test_default_bool_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.default_bool(), eq(true)); + assert_that!(msg.default_bool_mut().get(), eq(true)); + assert_that!(msg.default_bool_mut().is_set(), eq(false)); + assert_that!(msg.default_bool_opt(), eq(Optional::Unset(true))); + + msg.default_bool_mut().set(false); + assert_that!(msg.default_bool(), eq(false)); + assert_that!(msg.default_bool_mut().get(), eq(false)); + assert_that!(msg.default_bool_mut().is_set(), eq(true)); + assert_that!(msg.default_bool_opt(), eq(Optional::Set(false))); + + msg.default_bool_mut().clear(); + assert_that!(msg.default_bool(), eq(true)); + assert_that!(msg.default_bool_mut().get(), eq(true)); + assert_that!(msg.default_bool_mut().is_set(), eq(false)); + assert_that!(msg.default_bool_opt(), eq(Optional::Unset(true))); + + msg.default_bool_mut().or_default(); + assert_that!(msg.default_bool(), eq(true)); + assert_that!(msg.default_bool_mut().get(), eq(true)); + assert_that!(msg.default_bool_mut().is_set(), eq(true)); + assert_that!(msg.default_bool_opt(), eq(Optional::Set(true))); +} + #[test] fn test_optional_bytes_accessors() { let mut msg = TestAllTypes::new(); diff --git a/rust/vtable.rs b/rust/vtable.rs index 6d6e4e96ba..2327e56b69 100644 --- a/rust/vtable.rs +++ b/rust/vtable.rs @@ -258,6 +258,15 @@ pub struct PrimitiveVTable { pub(crate) getter: unsafe extern "C" fn(msg: RawMessage) -> T, } +#[doc(hidden)] +#[derive(Debug)] +/// A generic thunk vtable for mutating an `optional` primitive field. +pub struct PrimitiveOptionalMutVTable { + pub(crate) base: PrimitiveVTable, + pub(crate) clearer: unsafe extern "C" fn(msg: RawMessage), + pub(crate) default: T, +} + impl PrimitiveVTable { #[doc(hidden)] pub const fn new( @@ -269,6 +278,19 @@ impl PrimitiveVTable { } } +impl PrimitiveOptionalMutVTable { + #[doc(hidden)] + pub const fn new( + _private: Private, + getter: unsafe extern "C" fn(msg: RawMessage) -> T, + setter: unsafe extern "C" fn(msg: RawMessage, val: T), + clearer: unsafe extern "C" fn(msg: RawMessage), + default: T, + ) -> Self { + Self { base: PrimitiveVTable { getter, setter }, clearer, default } + } +} + macro_rules! impl_raw_vtable_mutator_get_set { ($($t:ty),*) => { $( @@ -398,3 +420,36 @@ impl<'msg> RawVTableOptionalMutatorData<'msg, [u8]> { self } } + +macro_rules! impl_raw_vtable_optional_mutator_data { + ($($t:ty),*) => { + $( + impl<'msg> RawVTableOptionalMutatorData<'msg, $t> { + pub(crate) fn set_absent_to_default(self) -> Self { + // SAFETY: + // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as + // promised by the caller of `new`. + self.set(self.vtable.default) + } + + pub(crate) fn set(self, val: $t) -> Self { + // SAFETY: + // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as + // promised by the caller of `new`. + unsafe { (self.vtable.base.setter)(self.msg_ref.msg(), val.into()) } + self + } + + pub(crate) fn clear(self) -> Self { + // SAFETY: + // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as + // promised by the caller of `new`. + unsafe { (self.vtable.clearer)(self.msg_ref.msg()) } + self + } + } + )* + } +} + +impl_raw_vtable_optional_mutator_data!(bool, f32, f64, i32, i64, u32, u64); diff --git a/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc b/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc index 3f8594bb16..818dc7ce9b 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc @@ -5,12 +5,20 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd +#include +#include +#include + +#include "absl/log/absl_log.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/rust/accessors/accessor_generator.h" #include "google/protobuf/compiler/rust/context.h" #include "google/protobuf/compiler/rust/naming.h" #include "google/protobuf/descriptor.h" +#include "google/protobuf/io/strtod.h" namespace google { namespace protobuf { @@ -23,6 +31,72 @@ void SingularScalar::InMsgImpl(Context field) const { {"field", field.desc().name()}, {"Scalar", PrimitiveRsTypeName(field.desc())}, {"hazzer_thunk", Thunk(field, "has")}, + {"default_value", + [&] { + switch (field.desc().type()) { + case FieldDescriptor::TYPE_DOUBLE: + if (std::isfinite(field.desc().default_value_double())) { + return absl::StrCat( + io::SimpleDtoa(field.desc().default_value_double()), + "f64"); + } else if (std::isnan(field.desc().default_value_double())) { + return std::string("f64::NAN"); + } else if (field.desc().default_value_double() == + std::numeric_limits::infinity()) { + return std::string("f64::INFINITY"); + } else if (field.desc().default_value_double() == + -std::numeric_limits::infinity()) { + return std::string("f64::NEG_INFINITY"); + } else { + ABSL_LOG(FATAL) << "unreachable"; + } + case FieldDescriptor::TYPE_FLOAT: + if (std::isfinite(field.desc().default_value_float())) { + return absl::StrCat( + io::SimpleFtoa(field.desc().default_value_float()), + "f32"); + } else if (std::isnan(field.desc().default_value_float())) { + return std::string("f32::NAN"); + } else if (field.desc().default_value_float() == + std::numeric_limits::infinity()) { + return std::string("f32::INFINITY"); + } else if (field.desc().default_value_float() == + -std::numeric_limits::infinity()) { + return std::string("f32::NEG_INFINITY"); + } else { + ABSL_LOG(FATAL) << "unreachable"; + } + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_SINT32: + return absl::StrFormat("%d", + field.desc().default_value_int32()); + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_SFIXED64: + case FieldDescriptor::TYPE_SINT64: + return absl::StrFormat("%d", + field.desc().default_value_int64()); + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_UINT64: + return absl::StrFormat("%u", + field.desc().default_value_uint64()); + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_UINT32: + return absl::StrFormat("%u", + field.desc().default_value_uint32()); + case FieldDescriptor::TYPE_BOOL: + return absl::StrFormat("%v", + field.desc().default_value_bool()); + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + case FieldDescriptor::TYPE_ENUM: + ABSL_LOG(FATAL) << "Non-singular scalar field type passed: " + << field.desc().type_name(); + } + ABSL_LOG(FATAL) << "unreachable"; + }()}, {"getter", [&] { field.Emit({}, R"rs( @@ -38,7 +112,7 @@ void SingularScalar::InMsgImpl(Context field) const { field.Emit({}, R"rs( pub fn r#$field$_opt(&self) -> $pb$::Optional<$Scalar$> { if !unsafe { $hazzer_thunk$(self.inner.msg) } { - return $pb$::Optional::Unset(<$Scalar$>::default()); + return $pb$::Optional::Unset($default_value$); } let value = unsafe { $getter_thunk$(self.inner.msg) }; $pb$::Optional::Set(value) @@ -64,8 +138,28 @@ void SingularScalar::InMsgImpl(Context field) const { {"field_mutator_getter", [&] { if (field.desc().has_presence()) { - // TODO: implement mutator for fields with presence. - return; + field.Emit({}, R"rs( + pub fn r#$field$_mut(&mut self) -> $pb$::FieldEntry<'_, $Scalar$> { + static VTABLE: $pbi$::PrimitiveOptionalMutVTable<$Scalar$> = + $pbi$::PrimitiveOptionalMutVTable::new( + $pbi$::Private, + $getter_thunk$, + $setter_thunk$, + $clearer_thunk$, + $default_value$, + ); + + unsafe { + let has = $hazzer_thunk$(self.inner.msg); + $pbi$::new_vtable_field_entry::<$Scalar$>( + $pbi$::Private, + $pbr$::MutatorMessageRef::new($pbi$::Private, &mut self.inner), + &VTABLE, + has, + ) + } + } + )rs"); } else { field.Emit({}, R"rs( pub fn r#$field$_mut(&mut self) -> $pb$::PrimitiveMut<'_, $Scalar$> { From dc67f8afc1feb2abf60f14bdce41d437946d9a5c Mon Sep 17 00:00:00 2001 From: Hong Shin Date: Wed, 18 Oct 2023 08:40:45 -0700 Subject: [PATCH 24/95] Perform preliminary migration of accessors_proto3_test to googletest-rust PiperOrigin-RevId: 574486887 --- rust/test/shared/BUILD | 6 ++ rust/test/shared/accessors_proto3_test.rs | 118 +++++++++++----------- 2 files changed, 66 insertions(+), 58 deletions(-) diff --git a/rust/test/shared/BUILD b/rust/test/shared/BUILD index 79d43ddd4e..b2c4aaf164 100644 --- a/rust/test/shared/BUILD +++ b/rust/test/shared/BUILD @@ -193,15 +193,18 @@ rust_test( srcs = ["accessors_proto3_test.rs"], aliases = { "//rust:protobuf_cpp": "protobuf", + "//rust/test/shared:matchers_cpp": "matchers", }, tags = [ # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. "not_build:arm", ], deps = [ + "//third_party/gtest_rust/googletest", "//rust:protobuf_cpp", "//rust/test:unittest_proto3_cc_rust_proto", "//rust/test:unittest_proto3_optional_cc_rust_proto", + "//rust/test/shared:matchers_cpp", ], ) @@ -210,15 +213,18 @@ rust_test( srcs = ["accessors_proto3_test.rs"], aliases = { "//rust:protobuf_upb": "protobuf", + "//rust/test/shared:matchers_upb": "matchers", }, tags = [ # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. "not_build:arm", ], deps = [ + "//third_party/gtest_rust/googletest", "//rust:protobuf_upb", "//rust/test:unittest_proto3_optional_upb_rust_proto", "//rust/test:unittest_proto3_upb_rust_proto", + "//rust/test/shared:matchers_upb", ], ) diff --git a/rust/test/shared/accessors_proto3_test.rs b/rust/test/shared/accessors_proto3_test.rs index 84d58a9e9c..3260c0d11d 100644 --- a/rust/test/shared/accessors_proto3_test.rs +++ b/rust/test/shared/accessors_proto3_test.rs @@ -7,6 +7,8 @@ /// Tests covering accessors for singular bool, int32, int64, and bytes fields /// on proto3. +use googletest::prelude::*; +use matchers::{is_set, is_unset}; use protobuf::Optional; use unittest_proto3::proto3_unittest::{TestAllTypes, TestAllTypes_}; use unittest_proto3_optional::proto2_unittest::TestProto3Optional; @@ -14,31 +16,31 @@ use unittest_proto3_optional::proto2_unittest::TestProto3Optional; #[test] fn test_fixed32_accessors() { let mut msg = TestAllTypes::new(); - assert_eq!(msg.optional_fixed32(), 0); - assert_eq!(msg.optional_fixed32_mut().get(), 0); + assert_that!(msg.optional_fixed32(), eq(0)); + assert_that!(msg.optional_fixed32_mut().get(), eq(0)); msg.optional_fixed32_mut().set(42); - assert_eq!(msg.optional_fixed32_mut().get(), 42); - assert_eq!(msg.optional_fixed32(), 42); + assert_that!(msg.optional_fixed32_mut().get(), eq(42)); + assert_that!(msg.optional_fixed32(), eq(42)); msg.optional_fixed32_mut().clear(); - assert_eq!(msg.optional_fixed32(), 0); - assert_eq!(msg.optional_fixed32_mut().get(), 0); + assert_that!(msg.optional_fixed32(), eq(0)); + assert_that!(msg.optional_fixed32_mut().get(), eq(0)); } #[test] fn test_bool_accessors() { let mut msg = TestAllTypes::new(); - assert!(!msg.optional_bool()); - assert!(!msg.optional_bool_mut().get()); + assert_that!(msg.optional_bool(), eq(false)); + assert_that!(msg.optional_bool_mut().get(), eq(false)); msg.optional_bool_mut().set(true); - assert!(msg.optional_bool()); - assert!(msg.optional_bool_mut().get()); + assert_that!(msg.optional_bool(), eq(true)); + assert_that!(msg.optional_bool_mut().get(), eq(true)); msg.optional_bool_mut().clear(); - assert!(!msg.optional_bool()); - assert!(!msg.optional_bool_mut().get()); + assert_that!(msg.optional_bool(), eq(false)); + assert_that!(msg.optional_bool_mut().get(), eq(false)); } #[test] @@ -46,73 +48,73 @@ fn test_bytes_accessors() { let mut msg = TestAllTypes::new(); // Note: even though it's named 'optional_bytes', the field is actually not // proto3 optional, so it does not support presence. - assert_eq!(msg.optional_bytes(), b""); - assert_eq!(msg.optional_bytes_mut().get(), b""); + assert_that!(*msg.optional_bytes(), empty()); + assert_that!(*msg.optional_bytes_mut().get(), empty()); msg.optional_bytes_mut().set(b"accessors_test"); - assert_eq!(msg.optional_bytes(), b"accessors_test"); - assert_eq!(msg.optional_bytes_mut().get(), b"accessors_test"); + assert_that!(msg.optional_bytes(), eq(b"accessors_test")); + assert_that!(msg.optional_bytes_mut().get(), eq(b"accessors_test")); { let s = Vec::from(&b"hello world"[..]); msg.optional_bytes_mut().set(&s[..]); } - assert_eq!(msg.optional_bytes(), b"hello world"); - assert_eq!(msg.optional_bytes_mut().get(), b"hello world"); + assert_that!(msg.optional_bytes(), eq(b"hello world")); + assert_that!(msg.optional_bytes_mut().get(), eq(b"hello world")); msg.optional_bytes_mut().clear(); - assert_eq!(msg.optional_bytes(), b""); - assert_eq!(msg.optional_bytes_mut().get(), b""); + assert_that!(*msg.optional_bytes(), empty()); + assert_that!(*msg.optional_bytes_mut().get(), empty()); msg.optional_bytes_mut().set(b""); - assert_eq!(msg.optional_bytes(), b""); - assert_eq!(msg.optional_bytes_mut().get(), b""); + assert_that!(*msg.optional_bytes(), empty()); + assert_that!(*msg.optional_bytes_mut().get(), empty()); } #[test] fn test_optional_bytes_accessors() { let mut msg = TestProto3Optional::new(); - assert_eq!(msg.optional_bytes(), b""); - assert_eq!(msg.optional_bytes_opt(), Optional::Unset(&b""[..])); - assert_eq!(msg.optional_bytes_mut().get(), b""); - assert!(msg.optional_bytes_mut().is_unset()); + assert_that!(*msg.optional_bytes(), empty()); + assert_that!(msg.optional_bytes_opt(), eq(Optional::Unset(&b""[..]))); + assert_that!(*msg.optional_bytes_mut().get(), empty()); + assert_that!(msg.optional_bytes_mut(), is_unset()); { let s = Vec::from(&b"hello world"[..]); msg.optional_bytes_mut().set(&s[..]); } - assert_eq!(msg.optional_bytes(), b"hello world"); - assert_eq!(msg.optional_bytes_opt(), Optional::Set(&b"hello world"[..])); - assert!(msg.optional_bytes_mut().is_set()); - assert_eq!(msg.optional_bytes_mut().get(), b"hello world"); + assert_that!(msg.optional_bytes(), eq(b"hello world")); + assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b"hello world"[..]))); + assert_that!(msg.optional_bytes_mut(), is_set()); + assert_that!(msg.optional_bytes_mut().get(), eq(b"hello world")); msg.optional_bytes_mut().or_default().set(b"accessors_test"); - assert_eq!(msg.optional_bytes(), b"accessors_test"); - assert_eq!(msg.optional_bytes_opt(), Optional::Set(&b"accessors_test"[..])); - assert!(msg.optional_bytes_mut().is_set()); - assert_eq!(msg.optional_bytes_mut().get(), b"accessors_test"); - assert_eq!(msg.optional_bytes_mut().or_default().get(), b"accessors_test"); + assert_that!(msg.optional_bytes(), eq(b"accessors_test")); + assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b"accessors_test"[..]))); + assert_that!(msg.optional_bytes_mut(), is_set()); + assert_that!(msg.optional_bytes_mut().get(), eq(b"accessors_test")); + assert_that!(msg.optional_bytes_mut().or_default().get(), eq(b"accessors_test")); msg.optional_bytes_mut().clear(); - assert_eq!(msg.optional_bytes(), b""); - assert_eq!(msg.optional_bytes_opt(), Optional::Unset(&b""[..])); - assert!(msg.optional_bytes_mut().is_unset()); + assert_that!(*msg.optional_bytes(), empty()); + assert_that!(msg.optional_bytes_opt(), eq(Optional::Unset(&b""[..]))); + assert_that!(msg.optional_bytes_mut(), is_unset()); msg.optional_bytes_mut().set(b""); - assert_eq!(msg.optional_bytes(), b""); - assert_eq!(msg.optional_bytes_opt(), Optional::Set(&b""[..])); + assert_that!(*msg.optional_bytes(), empty()); + assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b""[..]))); msg.optional_bytes_mut().clear(); msg.optional_bytes_mut().or_default(); - assert_eq!(msg.optional_bytes(), b""); - assert_eq!(msg.optional_bytes_opt(), Optional::Set(&b""[..])); + assert_that!(*msg.optional_bytes(), empty()); + assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b""[..]))); msg.optional_bytes_mut().or_default().set(b"\xffbinary\x85non-utf8"); - assert_eq!(msg.optional_bytes(), b"\xffbinary\x85non-utf8"); - assert_eq!(msg.optional_bytes_opt(), Optional::Set(&b"\xffbinary\x85non-utf8"[..])); - assert!(msg.optional_bytes_mut().is_set()); - assert_eq!(msg.optional_bytes_mut().get(), b"\xffbinary\x85non-utf8"); - assert_eq!(msg.optional_bytes_mut().or_default().get(), b"\xffbinary\x85non-utf8"); + assert_that!(msg.optional_bytes(), eq(b"\xffbinary\x85non-utf8")); + assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b"\xffbinary\x85non-utf8"[..]))); + assert_that!(msg.optional_bytes_mut(), is_set()); + assert_that!(msg.optional_bytes_mut().get(), eq(b"\xffbinary\x85non-utf8")); + assert_that!(msg.optional_bytes_mut().or_default().get(), eq(b"\xffbinary\x85non-utf8")); } #[test] @@ -149,7 +151,7 @@ fn test_optional_string_accessors() { assert_eq!(msg.optional_string(), ""); assert_eq!(msg.optional_string_opt(), Optional::Unset("".into())); assert_eq!(msg.optional_string_mut().get(), ""); - assert!(msg.optional_string_mut().is_unset()); + assert_that!(msg.optional_string_mut(), is_unset()); { let s = String::from("hello world"); @@ -157,20 +159,20 @@ fn test_optional_string_accessors() { } assert_eq!(msg.optional_string(), "hello world"); assert_eq!(msg.optional_string_opt(), Optional::Set("hello world".into())); - assert!(msg.optional_string_mut().is_set()); + assert_that!(msg.optional_string_mut(), is_set()); assert_eq!(msg.optional_string_mut().get(), "hello world"); msg.optional_string_mut().or_default().set("accessors_test"); assert_eq!(msg.optional_string(), "accessors_test"); assert_eq!(msg.optional_string_opt(), Optional::Set("accessors_test".into())); - assert!(msg.optional_string_mut().is_set()); + assert_that!(msg.optional_string_mut(), is_set()); assert_eq!(msg.optional_string_mut().get(), "accessors_test"); assert_eq!(msg.optional_string_mut().or_default().get(), "accessors_test"); msg.optional_string_mut().clear(); assert_eq!(msg.optional_string(), ""); assert_eq!(msg.optional_string_opt(), Optional::Unset("".into())); - assert!(msg.optional_string_mut().is_unset()); + assert_that!(msg.optional_string_mut(), is_unset()); msg.optional_string_mut().set(""); assert_eq!(msg.optional_string(), ""); @@ -187,20 +189,20 @@ fn test_oneof_accessors() { use TestAllTypes_::OneofField::*; let mut msg = TestAllTypes::new(); - assert!(matches!(msg.oneof_field(), not_set(_))); + assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); msg.oneof_uint32_set(Some(7)); - assert_eq!(msg.oneof_uint32_opt(), Optional::Set(7)); - assert!(matches!(msg.oneof_field(), OneofUint32(7))); + assert_that!(msg.oneof_uint32_opt(), eq(Optional::Set(7))); + assert_that!(msg.oneof_field(), matches_pattern!(OneofUint32(eq(7)))); msg.oneof_uint32_set(None); - assert_eq!(msg.oneof_uint32_opt(), Optional::Unset(0)); - assert!(matches!(msg.oneof_field(), not_set(_))); + assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0))); + assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); msg.oneof_uint32_set(Some(7)); msg.oneof_bytes_mut().set(b""); - assert_eq!(msg.oneof_uint32_opt(), Optional::Unset(0)); + assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0))); // This should show it set to the OneofBytes but its not supported yet. - assert!(matches!(msg.oneof_field(), not_set(_))); + assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); } From bac6e765afb311a6e90f542c7370f8016e5014c0 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 18 Oct 2023 10:04:21 -0700 Subject: [PATCH 25/95] Migrate some protobuf internal macros to Abseil public ones. This reduces the size of port_def.inc, and reduces the total input to the preprocessor. PiperOrigin-RevId: 574510248 --- src/google/protobuf/arenastring.h | 4 +- .../compiler/command_line_interface.cc | 2 +- src/google/protobuf/compiler/cpp/file.cc | 12 +- src/google/protobuf/compiler/cpp/message.cc | 2 +- .../compiler/cpp/parse_function_generator.cc | 7 +- .../compiler/java/java_features.pb.cc | 34 +- .../protobuf/compiler/java/java_features.pb.h | 2 +- src/google/protobuf/compiler/plugin.pb.cc | 138 +- src/google/protobuf/compiler/plugin.pb.h | 8 +- src/google/protobuf/cpp_features.pb.cc | 30 +- src/google/protobuf/cpp_features.pb.h | 2 +- src/google/protobuf/descriptor.cc | 2 +- src/google/protobuf/descriptor.pb.cc | 1172 +++++++++-------- src/google/protobuf/descriptor.pb.h | 64 +- src/google/protobuf/endian.h | 24 +- src/google/protobuf/generated_message_bases.h | 2 +- .../generated_message_tctable_lite.cc | 2 +- src/google/protobuf/io/coded_stream.cc | 2 +- src/google/protobuf/io/coded_stream.h | 18 +- .../protobuf/io/zero_copy_stream_impl_lite.cc | 2 +- src/google/protobuf/message_lite.h | 35 +- src/google/protobuf/parse_context.h | 6 +- src/google/protobuf/port_def.inc | 106 -- src/google/protobuf/port_undef.inc | 11 - src/google/protobuf/repeated_field.h | 6 +- src/google/protobuf/repeated_ptr_field.h | 6 +- src/google/protobuf/stubs/common.cc | 4 - src/google/protobuf/stubs/port.h | 38 +- src/google/protobuf/wire_format.cc | 2 +- src/google/protobuf/wire_format_lite.cc | 6 +- src/google/protobuf/wire_format_lite.h | 4 +- 31 files changed, 804 insertions(+), 949 deletions(-) diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index dea2aecab7..dc9fe561c4 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -337,7 +337,7 @@ struct PROTOBUF_EXPORT ArenaStringPtr { // Returns a pointer to the stored contents for this instance. // This method is for internal debugging and tracking purposes only. PROTOBUF_NDEBUG_INLINE const std::string* UnsafeGetPointer() const - PROTOBUF_RETURNS_NONNULL { + ABSL_ATTRIBUTE_RETURNS_NONNULL { return tagged_ptr_.Get(); } @@ -383,7 +383,7 @@ struct PROTOBUF_EXPORT ArenaStringPtr { // Generated code only! An optimization, in certain cases the generated // code is certain we can obtain a std::string with no default checks and // tag tests. - std::string* UnsafeMutablePointer() PROTOBUF_RETURNS_NONNULL; + std::string* UnsafeMutablePointer() ABSL_ATTRIBUTE_RETURNS_NONNULL; // Returns true if this instances holds an immutable default value. inline bool IsDefault() const { return tagged_ptr_.IsDefault(); } diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index df3bae36e9..1f34645e26 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -1899,7 +1899,7 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( break; // only for --decode_raw } // --decode (not raw) is handled the same way as the rest of the modes. - PROTOBUF_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case MODE_ENCODE: case MODE_PRINT: missing_proto_definitions = diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index 416afb0fab..1c88b8a226 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -1131,13 +1131,14 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { }}, }, R"cc( - const ::uint32_t $tablename$::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - $offsets$, + const ::uint32_t + $tablename$::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + $offsets$, }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { $schemas$, }; @@ -1212,7 +1213,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { } }}}, R"cc( - const char $desc_name$[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + const char $desc_name$[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { $encoded_file_proto$, }; )cc"); diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 829361e72c..20c8f33a5d 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -1529,7 +1529,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { if (!HasSimpleBaseClass(descriptor_, options_)) { format( - "PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;\n" + "ABSL_ATTRIBUTE_REINITIALIZES void Clear() final;\n" "bool IsInitialized() const final;\n" "\n" "::size_t ByteSizeLong() const final;\n"); diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index 1b8ffc4c5e..6fb3aa85e3 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -235,9 +235,12 @@ void ParseFunctionGenerator::GenerateDataDecls(io::Printer* p) { // Since most (>80%) messages are never present, messages that are // present are considered hot enough to be clustered together. if (IsPresentMessage(descriptor_, options_)) { - p->Emit("PROTOBUF_SECTION_VARIABLE(proto_parse_table_hot)"); + p->Emit( + "ABSL_ATTRIBUTE_SECTION_VARIABLE(proto_parse_table_hot)"); } else { - p->Emit("PROTOBUF_SECTION_VARIABLE(proto_parse_table_lukewarm)"); + p->Emit( + "ABSL_ATTRIBUTE_SECTION_VARIABLE(proto_parse_table_" + "lukewarm)"); } }}, {"table_size_log2", tc_table_info_->table_size_log2}, diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc index 99ab9eb8d0..e3dac1672b 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.cc +++ b/src/google/protobuf/compiler/java/java_features.pb.cc @@ -46,31 +46,33 @@ static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fjava_2 static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[1]; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - PROTOBUF_FIELD_OFFSET(::pb::JavaFeatures, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::pb::JavaFeatures, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::pb::JavaFeatures, _impl_.legacy_closed_enum_), - PROTOBUF_FIELD_OFFSET(::pb::JavaFeatures, _impl_.utf8_validation_), - 0, - 1, +const ::uint32_t + TableStruct_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + PROTOBUF_FIELD_OFFSET(::pb::JavaFeatures, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::pb::JavaFeatures, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::pb::JavaFeatures, _impl_.legacy_closed_enum_), + PROTOBUF_FIELD_OFFSET(::pb::JavaFeatures, _impl_.utf8_validation_), + 0, + 1, }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 10, -1, sizeof(::pb::JavaFeatures)}, }; static const ::_pb::Message* const file_default_instances[] = { &::pb::_JavaFeatures_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n1google/protobuf/compiler/java/java_fea" "tures.proto\022\002pb\032 google/protobuf/descrip" "tor.proto\"\352\001\n\014JavaFeatures\022>\n\022legacy_clo" diff --git a/src/google/protobuf/compiler/java/java_features.pb.h b/src/google/protobuf/compiler/java/java_features.pb.h index 048b5778fa..66c51efb87 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.h +++ b/src/google/protobuf/compiler/java/java_features.pb.h @@ -201,7 +201,7 @@ class PROTOC_EXPORT JavaFeatures final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 684bdd31d7..8b8084c62f 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -130,76 +130,77 @@ static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.major_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.minor_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.patch_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.suffix_), - 1, - 2, - 3, - 0, - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.file_to_generate_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.parameter_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.proto_file_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.source_file_descriptors_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.compiler_version_), - ~0u, - 0, - ~0u, - ~0u, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.insertion_point_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.content_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.generated_code_info_), - 0, - 1, - 2, - 3, - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.error_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.supported_features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.file_), - 0, - 1, - ~0u, +const ::uint32_t + TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.major_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.minor_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.patch_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.suffix_), + 1, + 2, + 3, + 0, + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.file_to_generate_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.parameter_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.proto_file_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.source_file_descriptors_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.compiler_version_), + ~0u, + 0, + ~0u, + ~0u, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.insertion_point_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.content_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.generated_code_info_), + 0, + 1, + 2, + 3, + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.error_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.supported_features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.file_), + 0, + 1, + ~0u, }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 12, -1, sizeof(::google::protobuf::compiler::Version)}, {16, 29, -1, sizeof(::google::protobuf::compiler::CodeGeneratorRequest)}, {34, 46, -1, sizeof(::google::protobuf::compiler::CodeGeneratorResponse_File)}, @@ -212,7 +213,8 @@ static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::compiler::_CodeGeneratorResponse_File_default_instance_._instance, &::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n%google/protobuf/compiler/plugin.proto\022" "\030google.protobuf.compiler\032 google/protob" "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030" diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 90fb5f0ae3..1a2c568124 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -218,7 +218,7 @@ class PROTOC_EXPORT Version final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -440,7 +440,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -678,7 +678,7 @@ class PROTOC_EXPORT CodeGeneratorResponse final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -917,7 +917,7 @@ class PROTOC_EXPORT CodeGeneratorRequest final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc index ec3d53d733..762c63077a 100644 --- a/src/google/protobuf/cpp_features.pb.cc +++ b/src/google/protobuf/cpp_features.pb.cc @@ -46,29 +46,31 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_.legacy_closed_enum_), - 0, +const ::uint32_t + TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_.legacy_closed_enum_), + 0, }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 9, -1, sizeof(::pb::CppFeatures)}, }; static const ::_pb::Message* const file_default_instances[] = { &::pb::_CppFeatures_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fcpp_5ffeatures_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fcpp_5ffeatures_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\"google/protobuf/cpp_features.proto\022\002pb" "\032 google/protobuf/descriptor.proto\"M\n\013Cp" "pFeatures\022>\n\022legacy_closed_enum\030\001 \001(\010B\"\210" diff --git a/src/google/protobuf/cpp_features.pb.h b/src/google/protobuf/cpp_features.pb.h index 8169b4fb86..fddd800989 100644 --- a/src/google/protobuf/cpp_features.pb.h +++ b/src/google/protobuf/cpp_features.pb.h @@ -170,7 +170,7 @@ class PROTOBUF_EXPORT CppFeatures final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 751c4b8bec..0f1cd6bc86 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -1266,7 +1266,7 @@ class FileDescriptorTables { FieldsByNumberSet fields_by_number_; // Not including extensions. EnumValuesByNumberSet enum_values_by_number_; mutable EnumValuesByNumberSet unknown_enum_values_by_number_ - PROTOBUF_GUARDED_BY(unknown_enum_values_mu_); + ABSL_GUARDED_BY(unknown_enum_values_mu_); // Populated on first request to save space, hence constness games. mutable absl::once_flag locations_by_path_once_; diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 8e880a77c7..ce7e962bf4 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -1003,593 +1003,594 @@ static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eprot static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[17]; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _impl_.file_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.package_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.dependency_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.public_dependency_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.weak_dependency_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.message_type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.enum_type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.service_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.extension_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.source_code_info_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.syntax_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.edition_), - 0, - 1, - ~0u, - ~0u, - ~0u, - ~0u, - ~0u, - ~0u, - ~0u, - 3, - 4, - 2, - 5, - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _impl_.start_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _impl_.end_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _impl_.options_), - 1, - 2, - 0, - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _impl_.start_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _impl_.end_), - 0, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.field_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.extension_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.nested_type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.enum_type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.extension_range_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.oneof_decl_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.reserved_range_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.reserved_name_), - 0, - ~0u, - ~0u, - ~0u, - ~0u, - ~0u, - ~0u, - 1, - ~0u, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.number_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.full_name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.reserved_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.repeated_), - 2, - 0, - 1, - 3, - 4, - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_.uninterpreted_option_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_.declaration_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_.verification_), - ~0u, - ~0u, - 0, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.number_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.label_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.type_name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.extendee_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.default_value_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.oneof_index_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.json_name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.proto3_optional_), - 0, - 6, - 9, - 10, - 2, - 1, - 3, - 7, - 4, - 5, - 8, - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _impl_.options_), - 0, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _impl_.start_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _impl_.end_), - 0, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.value_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.reserved_range_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.reserved_name_), - 0, - ~0u, - 1, - ~0u, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _impl_.number_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _impl_.options_), - 0, - 2, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _impl_.method_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _impl_.options_), - 0, - ~0u, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.input_type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.output_type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.client_streaming_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.server_streaming_), - 0, - 1, - 2, - 3, - 4, - 5, - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_package_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_outer_classname_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_multiple_files_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_generate_equals_and_hash_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_string_check_utf8_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.optimize_for_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.go_package_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.cc_generic_services_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_generic_services_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.py_generic_services_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.php_generic_services_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.deprecated_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.cc_enable_arenas_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.objc_class_prefix_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.csharp_namespace_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.swift_prefix_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.php_class_prefix_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.php_namespace_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.php_metadata_namespace_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.ruby_package_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.uninterpreted_option_), - 0, - 1, - 11, - 12, - 13, - 19, - 2, - 14, - 15, - 16, - 17, - 18, - 20, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.message_set_wire_format_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.no_standard_descriptor_accessor_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.deprecated_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.map_entry_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.deprecated_legacy_json_field_conflicts_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.uninterpreted_option_), - 1, - 2, - 3, - 4, - 5, - 0, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions_EditionDefault, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions_EditionDefault, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions_EditionDefault, _impl_.edition_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions_EditionDefault, _impl_.value_), - 1, - 0, - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.ctype_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.packed_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.jstype_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.lazy_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.unverified_lazy_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.deprecated_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.weak_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.debug_redact_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.retention_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.targets_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.edition_defaults_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.uninterpreted_option_), - 1, - 3, - 2, - 4, - 5, - 6, - 7, - 8, - 9, - ~0u, - ~0u, - 0, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _impl_.uninterpreted_option_), - 0, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.allow_alias_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.deprecated_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.deprecated_legacy_json_field_conflicts_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.uninterpreted_option_), - 1, - 2, - 3, - 0, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_.deprecated_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_.debug_redact_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_.uninterpreted_option_), - 1, - 0, - 2, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_.deprecated_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_.uninterpreted_option_), - 0, - 1, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_.deprecated_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_.idempotency_level_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_.features_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_.uninterpreted_option_), - 1, - 2, - 0, - ~0u, - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _impl_.name_part_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _impl_.is_extension_), - 0, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.identifier_value_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.positive_int_value_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.negative_int_value_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.double_value_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.string_value_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.aggregate_value_), - ~0u, - 0, - 3, - 4, - 5, - 1, - 2, - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _internal_metadata_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_._extensions_), - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.field_presence_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.enum_type_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.repeated_field_encoding_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.utf8_validation_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.message_encoding_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.json_format_), - 0, - 1, - 2, - 3, - 4, - 5, - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault, _impl_.edition_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault, _impl_.features_), - 1, - 0, - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _impl_.defaults_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _impl_.minimum_edition_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _impl_.maximum_edition_), - ~0u, - 0, - 1, - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.path_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.span_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.leading_comments_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.trailing_comments_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.leading_detached_comments_), - ~0u, - ~0u, - 0, - 1, - ~0u, - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo, _impl_.location_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.path_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.source_file_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.begin_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.end_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.semantic_), - ~0u, - 0, - 1, - 2, - 3, - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo, _impl_.annotation_), +const ::uint32_t + TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _impl_.file_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.package_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.dependency_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.public_dependency_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.weak_dependency_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.message_type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.enum_type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.service_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.extension_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.source_code_info_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.syntax_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _impl_.edition_), + 0, + 1, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + 3, + 4, + 2, + 5, + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _impl_.start_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _impl_.end_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _impl_.options_), + 1, + 2, + 0, + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _impl_.start_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _impl_.end_), + 0, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.field_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.extension_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.nested_type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.enum_type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.extension_range_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.oneof_decl_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.reserved_range_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::DescriptorProto, _impl_.reserved_name_), + 0, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + ~0u, + 1, + ~0u, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.number_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.full_name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.reserved_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions_Declaration, _impl_.repeated_), + 2, + 0, + 1, + 3, + 4, + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_.uninterpreted_option_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_.declaration_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _impl_.verification_), + ~0u, + ~0u, + 0, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.number_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.label_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.type_name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.extendee_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.default_value_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.oneof_index_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.json_name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _impl_.proto3_optional_), + 0, + 6, + 9, + 10, + 2, + 1, + 3, + 7, + 4, + 5, + 8, + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _impl_.options_), + 0, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _impl_.start_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _impl_.end_), + 0, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.value_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.reserved_range_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _impl_.reserved_name_), + 0, + ~0u, + 1, + ~0u, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _impl_.number_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _impl_.options_), + 0, + 2, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _impl_.method_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _impl_.options_), + 0, + ~0u, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.input_type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.output_type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.client_streaming_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _impl_.server_streaming_), + 0, + 1, + 2, + 3, + 4, + 5, + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_package_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_outer_classname_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_multiple_files_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_generate_equals_and_hash_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_string_check_utf8_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.optimize_for_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.go_package_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.cc_generic_services_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.java_generic_services_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.py_generic_services_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.php_generic_services_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.deprecated_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.cc_enable_arenas_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.objc_class_prefix_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.csharp_namespace_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.swift_prefix_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.php_class_prefix_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.php_namespace_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.php_metadata_namespace_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.ruby_package_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FileOptions, _impl_.uninterpreted_option_), + 0, + 1, + 11, + 12, + 13, + 19, + 2, + 14, + 15, + 16, + 17, + 18, + 20, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.message_set_wire_format_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.no_standard_descriptor_accessor_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.deprecated_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.map_entry_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.deprecated_legacy_json_field_conflicts_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MessageOptions, _impl_.uninterpreted_option_), + 1, + 2, + 3, + 4, + 5, + 0, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions_EditionDefault, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions_EditionDefault, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions_EditionDefault, _impl_.edition_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions_EditionDefault, _impl_.value_), + 1, + 0, + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.ctype_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.packed_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.jstype_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.lazy_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.unverified_lazy_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.deprecated_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.weak_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.debug_redact_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.retention_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.targets_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.edition_defaults_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldOptions, _impl_.uninterpreted_option_), + 1, + 3, + 2, + 4, + 5, + 6, + 7, + 8, + 9, + ~0u, + ~0u, + 0, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::OneofOptions, _impl_.uninterpreted_option_), + 0, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.allow_alias_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.deprecated_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.deprecated_legacy_json_field_conflicts_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumOptions, _impl_.uninterpreted_option_), + 1, + 2, + 3, + 0, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_.deprecated_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_.debug_redact_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _impl_.uninterpreted_option_), + 1, + 0, + 2, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_.deprecated_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::ServiceOptions, _impl_.uninterpreted_option_), + 0, + 1, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_.deprecated_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_.idempotency_level_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_.features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::MethodOptions, _impl_.uninterpreted_option_), + 1, + 2, + 0, + ~0u, + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _impl_.name_part_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _impl_.is_extension_), + 0, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.identifier_value_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.positive_int_value_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.negative_int_value_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.double_value_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.string_value_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _impl_.aggregate_value_), + ~0u, + 0, + 3, + 4, + 5, + 1, + 2, + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _internal_metadata_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_._extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.field_presence_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.enum_type_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.repeated_field_encoding_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.utf8_validation_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.message_encoding_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.json_format_), + 0, + 1, + 2, + 3, + 4, + 5, + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault, _impl_.edition_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault, _impl_.features_), + 1, + 0, + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _impl_.defaults_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _impl_.minimum_edition_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSetDefaults, _impl_.maximum_edition_), + ~0u, + 0, + 1, + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.path_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.span_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.leading_comments_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.trailing_comments_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_.leading_detached_comments_), + ~0u, + ~0u, + 0, + 1, + ~0u, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo, _impl_.location_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.path_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.source_file_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.begin_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.end_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _impl_.semantic_), + ~0u, + 0, + 1, + 2, + 3, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo, _impl_.annotation_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, -1, -1, sizeof(::google::protobuf::FileDescriptorSet)}, {9, 30, -1, sizeof(::google::protobuf::FileDescriptorProto)}, {43, 54, -1, sizeof(::google::protobuf::DescriptorProto_ExtensionRange)}, @@ -1658,7 +1659,8 @@ static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_GeneratedCodeInfo_Annotation_default_instance_._instance, &::google::protobuf::_GeneratedCodeInfo_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n google/protobuf/descriptor.proto\022\017goog" "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file" "\030\001 \003(\0132$.google.protobuf.FileDescriptorP" diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 511109e828..6367994ea9 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -799,7 +799,7 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -995,7 +995,7 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1269,7 +1269,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1533,7 +1533,7 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1729,7 +1729,7 @@ class PROTOBUF_EXPORT FeatureSet final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -2277,7 +2277,7 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -2518,7 +2518,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -2708,7 +2708,7 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -2898,7 +2898,7 @@ class PROTOBUF_EXPORT UninterpretedOption final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -3180,7 +3180,7 @@ class PROTOBUF_EXPORT SourceCodeInfo final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -3365,7 +3365,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -3550,7 +3550,7 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -3744,7 +3744,7 @@ class PROTOBUF_EXPORT ServiceOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -4137,7 +4137,7 @@ class PROTOBUF_EXPORT OneofOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -4517,7 +4517,7 @@ class PROTOBUF_EXPORT MethodOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -4944,7 +4944,7 @@ class PROTOBUF_EXPORT MessageOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -5389,7 +5389,7 @@ class PROTOBUF_EXPORT FileOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -6110,7 +6110,7 @@ class PROTOBUF_EXPORT FieldOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -6741,7 +6741,7 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -6953,7 +6953,7 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -7388,7 +7388,7 @@ class PROTOBUF_EXPORT EnumValueOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -7794,7 +7794,7 @@ class PROTOBUF_EXPORT EnumOptions final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -8213,7 +8213,7 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -8413,7 +8413,7 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -8677,7 +8677,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -9075,7 +9075,7 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -9288,7 +9288,7 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -9495,7 +9495,7 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -9715,7 +9715,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -9987,7 +9987,7 @@ class PROTOBUF_EXPORT DescriptorProto final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -10360,7 +10360,7 @@ class PROTOBUF_EXPORT FileDescriptorProto final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -10778,7 +10778,7 @@ class PROTOBUF_EXPORT FileDescriptorSet final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/endian.h b/src/google/protobuf/endian.h index 2c6e50cbe3..781954e499 100644 --- a/src/google/protobuf/endian.h +++ b/src/google/protobuf/endian.h @@ -65,7 +65,7 @@ inline uint16_t BSwap16(uint16_t host_int) { namespace little_endian { inline uint16_t FromHost(uint16_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return BSwap16(value); #else return value; @@ -73,7 +73,7 @@ inline uint16_t FromHost(uint16_t value) { } inline uint32_t FromHost(uint32_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return BSwap32(value); #else return value; @@ -81,7 +81,7 @@ inline uint32_t FromHost(uint32_t value) { } inline uint64_t FromHost(uint64_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return BSwap64(value); #else return value; @@ -89,7 +89,7 @@ inline uint64_t FromHost(uint64_t value) { } inline uint16_t ToHost(uint16_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return BSwap16(value); #else return value; @@ -97,7 +97,7 @@ inline uint16_t ToHost(uint16_t value) { } inline uint32_t ToHost(uint32_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return BSwap32(value); #else return value; @@ -105,7 +105,7 @@ inline uint32_t ToHost(uint32_t value) { } inline uint64_t ToHost(uint64_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return BSwap64(value); #else return value; @@ -117,7 +117,7 @@ inline uint64_t ToHost(uint64_t value) { namespace big_endian { inline uint16_t FromHost(uint16_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return value; #else return BSwap16(value); @@ -125,7 +125,7 @@ inline uint16_t FromHost(uint16_t value) { } inline uint32_t FromHost(uint32_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return value; #else return BSwap32(value); @@ -133,7 +133,7 @@ inline uint32_t FromHost(uint32_t value) { } inline uint64_t FromHost(uint64_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return value; #else return BSwap64(value); @@ -141,7 +141,7 @@ inline uint64_t FromHost(uint64_t value) { } inline uint16_t ToHost(uint16_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return value; #else return BSwap16(value); @@ -149,7 +149,7 @@ inline uint16_t ToHost(uint16_t value) { } inline uint32_t ToHost(uint32_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return value; #else return BSwap32(value); @@ -157,7 +157,7 @@ inline uint32_t ToHost(uint32_t value) { } inline uint64_t ToHost(uint64_t value) { -#if defined(PROTOBUF_BIG_ENDIAN) +#if defined(ABSL_IS_BIG_ENDIAN) return value; #else return BSwap64(value); diff --git a/src/google/protobuf/generated_message_bases.h b/src/google/protobuf/generated_message_bases.h index 7a3943f62b..0f5e398a53 100644 --- a/src/google/protobuf/generated_message_bases.h +++ b/src/google/protobuf/generated_message_bases.h @@ -29,7 +29,7 @@ namespace internal { // rather than Message. class PROTOBUF_EXPORT ZeroFieldsBase : public Message { public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final { return true; } size_t ByteSizeLong() const final; int GetCachedSize() const { return _cached_size_.Get(); } diff --git a/src/google/protobuf/generated_message_tctable_lite.cc b/src/google/protobuf/generated_message_tctable_lite.cc index 531d0556a7..bf5a97b7a5 100644 --- a/src/google/protobuf/generated_message_tctable_lite.cc +++ b/src/google/protobuf/generated_message_tctable_lite.cc @@ -166,7 +166,7 @@ const TcParseTableBase::FieldEntry* TcParser::FindFieldEntry( } const uint16_t* lookup_table = table->field_lookup_begin(); for (;;) { -#ifdef PROTOBUF_LITTLE_ENDIAN +#ifdef ABSL_IS_LITTLE_ENDIAN memcpy(&fstart, lookup_table, sizeof(fstart)); #else fstart = lookup_table[0] | (lookup_table[1] << 16); diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index fdfc2d096e..61f6393087 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -893,7 +893,7 @@ uint8_t* EpsCopyOutputStream::WriteAliasedRaw(const void* data, int size, } } -#ifndef PROTOBUF_LITTLE_ENDIAN +#ifndef ABSL_IS_LITTLE_ENDIAN uint8_t* EpsCopyOutputStream::WriteRawLittleEndian32(const void* data, int size, uint8_t* ptr) { auto p = static_cast(data); diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index 09c66aff38..ecb0f2ec57 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -912,7 +912,7 @@ class PROTOBUF_EXPORT EpsCopyOutputStream { template uint8_t* WriteRawLittleEndian(const void* data, int size, uint8_t* ptr); -#if !defined(PROTOBUF_LITTLE_ENDIAN) || \ +#if !defined(ABSL_IS_LITTLE_ENDIAN) || \ defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) uint8_t* WriteRawLittleEndian32(const void* data, int size, uint8_t* ptr); uint8_t* WriteRawLittleEndian64(const void* data, int size, uint8_t* ptr); @@ -960,7 +960,7 @@ template <> inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<4>(const void* data, int size, uint8_t* ptr) { -#if defined(PROTOBUF_LITTLE_ENDIAN) && \ +#if defined(ABSL_IS_LITTLE_ENDIAN) && \ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) return WriteRaw(data, size, ptr); #else @@ -971,7 +971,7 @@ template <> inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<8>(const void* data, int size, uint8_t* ptr) { -#if defined(PROTOBUF_LITTLE_ENDIAN) && \ +#if defined(ABSL_IS_LITTLE_ENDIAN) && \ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) return WriteRaw(data, size, ptr); #else @@ -1320,7 +1320,7 @@ inline bool CodedInputStream::ReadVarintSizeAsInt(int* value) { // static inline const uint8_t* CodedInputStream::ReadLittleEndian32FromArray( const uint8_t* buffer, uint32_t* value) { -#if defined(PROTOBUF_LITTLE_ENDIAN) && \ +#if defined(ABSL_IS_LITTLE_ENDIAN) && \ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) memcpy(value, buffer, sizeof(*value)); return buffer + sizeof(*value); @@ -1335,7 +1335,7 @@ inline const uint8_t* CodedInputStream::ReadLittleEndian32FromArray( // static inline const uint8_t* CodedInputStream::ReadLittleEndian64FromArray( const uint8_t* buffer, uint64_t* value) { -#if defined(PROTOBUF_LITTLE_ENDIAN) && \ +#if defined(ABSL_IS_LITTLE_ENDIAN) && \ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) memcpy(value, buffer, sizeof(*value)); return buffer + sizeof(*value); @@ -1354,7 +1354,7 @@ inline const uint8_t* CodedInputStream::ReadLittleEndian64FromArray( } inline bool CodedInputStream::ReadLittleEndian32(uint32_t* value) { -#if defined(PROTOBUF_LITTLE_ENDIAN) && \ +#if defined(ABSL_IS_LITTLE_ENDIAN) && \ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast(sizeof(*value)))) { buffer_ = ReadLittleEndian32FromArray(buffer_, value); @@ -1368,7 +1368,7 @@ inline bool CodedInputStream::ReadLittleEndian32(uint32_t* value) { } inline bool CodedInputStream::ReadLittleEndian64(uint64_t* value) { -#if defined(PROTOBUF_LITTLE_ENDIAN) && \ +#if defined(ABSL_IS_LITTLE_ENDIAN) && \ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast(sizeof(*value)))) { buffer_ = ReadLittleEndian64FromArray(buffer_, value); @@ -1646,7 +1646,7 @@ inline uint8_t* CodedOutputStream::WriteVarint32SignExtendedToArray( inline uint8_t* CodedOutputStream::WriteLittleEndian32ToArray(uint32_t value, uint8_t* target) { -#if defined(PROTOBUF_LITTLE_ENDIAN) && \ +#if defined(ABSL_IS_LITTLE_ENDIAN) && \ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) memcpy(target, &value, sizeof(value)); #else @@ -1660,7 +1660,7 @@ inline uint8_t* CodedOutputStream::WriteLittleEndian32ToArray(uint32_t value, inline uint8_t* CodedOutputStream::WriteLittleEndian64ToArray(uint64_t value, uint8_t* target) { -#if defined(PROTOBUF_LITTLE_ENDIAN) && \ +#if defined(ABSL_IS_LITTLE_ENDIAN) && \ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) memcpy(target, &value, sizeof(value)); #else diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc index 3dd4b7337e..752dff20fd 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -617,7 +617,7 @@ bool CordOutputStream::Next(void** data, int* size) { case State::kFull: assert(buffer_.length() > 0); cord_.Append(std::move(buffer_)); - PROTOBUF_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case State::kEmpty: assert(buffer_.length() == 0); buffer_ = absl::CordBuffer::CreateWithDefaultLimit(desired_size); diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 60bc923e02..f8e1167c34 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -273,34 +273,34 @@ class PROTOBUF_EXPORT MessageLite { // format. A successful return does not indicate the entire input is // consumed, ensure you call ConsumedEntireMessage() to check that if // applicable. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromCodedStream( + ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromCodedStream( io::CodedInputStream* input); // Like ParseFromCodedStream(), but accepts messages that are missing // required fields. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromCodedStream( + ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromCodedStream( io::CodedInputStream* input); // Read a protocol buffer from the given zero-copy input stream. If // successful, the entire input will be consumed. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromZeroCopyStream( + ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromZeroCopyStream( io::ZeroCopyInputStream* input); // Like ParseFromZeroCopyStream(), but accepts messages that are missing // required fields. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromZeroCopyStream( + ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromZeroCopyStream( io::ZeroCopyInputStream* input); // Parse a protocol buffer from a file descriptor. If successful, the entire // input will be consumed. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromFileDescriptor( + ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromFileDescriptor( int file_descriptor); // Like ParseFromFileDescriptor(), but accepts messages that are missing // required fields. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromFileDescriptor( + ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromFileDescriptor( int file_descriptor); // Parse a protocol buffer from a C++ istream. If successful, the entire // input will be consumed. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromIstream(std::istream* input); + ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromIstream(std::istream* input); // Like ParseFromIstream(), but accepts messages that are missing // required fields. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromIstream( + ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromIstream( std::istream* input); // Read a protocol buffer from the given zero-copy input stream, expecting // the message to be exactly "size" bytes long. If successful, exactly @@ -310,29 +310,28 @@ class PROTOBUF_EXPORT MessageLite { // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are // missing required fields. bool MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromBoundedZeroCopyStream( + ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromBoundedZeroCopyStream( io::ZeroCopyInputStream* input, int size); // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are // missing required fields. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromBoundedZeroCopyStream( + ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromBoundedZeroCopyStream( io::ZeroCopyInputStream* input, int size); // Parses a protocol buffer contained in a string. Returns true on success. // This function takes a string in the (non-human-readable) binary wire // format, matching the encoding output by MessageLite::SerializeToString(). // If you'd like to convert a human-readable string into a protocol buffer // object, see google::protobuf::TextFormat::ParseFromString(). - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromString(absl::string_view data); + ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromString(absl::string_view data); // Like ParseFromString(), but accepts messages that are missing // required fields. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromString( + ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromString( absl::string_view data); // Parse a protocol buffer contained in an array of bytes. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromArray(const void* data, - int size); + ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromArray(const void* data, int size); // Like ParseFromArray(), but accepts messages that are missing // required fields. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromArray(const void* data, - int size); + ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromArray(const void* data, + int size); // Reads a protocol buffer from the stream and merges it into this @@ -418,10 +417,10 @@ class PROTOBUF_EXPORT MessageLite { // required fields. bool MergePartialFromCord(const absl::Cord& cord); // Parse a protocol buffer contained in a Cord. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromCord(const absl::Cord& cord); + ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromCord(const absl::Cord& cord); // Like ParseFromCord(), but accepts messages that are missing // required fields. - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromCord( + ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromCord( const absl::Cord& cord); // Serialize the message and store it in the given Cord. All required diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h index df12ee1ab5..776773c5cb 100644 --- a/src/google/protobuf/parse_context.h +++ b/src/google/protobuf/parse_context.h @@ -883,7 +883,7 @@ static const char* VarintParseSlowArm(const char* p, uint64_t* out, template PROTOBUF_NODISCARD const char* VarintParse(const char* p, T* out) { -#if defined(__aarch64__) && defined(PROTOBUF_LITTLE_ENDIAN) +#if defined(__aarch64__) && defined(ABSL_IS_LITTLE_ENDIAN) // This optimization is not supported in big endian mode uint64_t first8; std::memcpy(&first8, p, sizeof(first8)); @@ -1178,7 +1178,7 @@ const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size, out->Reserve(old_entries + num); int block_size = num * sizeof(T); auto dst = out->AddNAlreadyReserved(num); -#ifdef PROTOBUF_LITTLE_ENDIAN +#ifdef ABSL_IS_LITTLE_ENDIAN std::memcpy(dst, ptr, block_size); #else for (int i = 0; i < num; i++) @@ -1197,7 +1197,7 @@ const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size, int old_entries = out->size(); out->Reserve(old_entries + num); auto dst = out->AddNAlreadyReserved(num); -#ifdef PROTOBUF_LITTLE_ENDIAN +#ifdef ABSL_IS_LITTLE_ENDIAN ABSL_CHECK(dst != nullptr) << out << "," << num; std::memcpy(dst, ptr, block_size); #else diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 063f60be15..86ed3ea7d7 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -311,64 +311,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #define PROTOBUF_TAILCALL false #endif -#ifdef PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED -#error PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED was previously defined -#endif -#if ABSL_HAVE_ATTRIBUTE(exclusive_locks_required) -#define PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED(...) \ - __attribute__((exclusive_locks_required(__VA_ARGS__))) -#else -#define PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED(...) -#endif - -#ifdef PROTOBUF_NO_THREAD_SAFETY_ANALYSIS -#error PROTOBUF_NO_THREAD_SAFETY_ANALYSIS was previously defined -#endif -#if ABSL_HAVE_ATTRIBUTE(no_thread_safety_analysis) -#define PROTOBUF_NO_THREAD_SAFETY_ANALYSIS \ - __attribute__((no_thread_safety_analysis)) -#else -#define PROTOBUF_NO_THREAD_SAFETY_ANALYSIS -#endif - -#ifdef PROTOBUF_GUARDED_BY -#error PROTOBUF_GUARDED_BY was previously defined -#endif -#if ABSL_HAVE_ATTRIBUTE(guarded_by) -#define PROTOBUF_GUARDED_BY(x) __attribute__((guarded_by(x))) -#else -#define PROTOBUF_GUARDED_BY(x) -#endif - -#ifdef PROTOBUF_LOCKS_EXCLUDED -#error PROTOBUF_LOCKS_EXCLUDED was previously defined -#endif -#if ABSL_HAVE_ATTRIBUTE(locks_excluded) -#define PROTOBUF_LOCKS_EXCLUDED(...) \ - __attribute__((locks_excluded(__VA_ARGS__))) -#else -#define PROTOBUF_LOCKS_EXCLUDED(...) -#endif - -#ifdef PROTOBUF_COLD -#error PROTOBUF_COLD was previously defined -#endif -#if ABSL_HAVE_ATTRIBUTE(cold) || defined(__GNUC__) -# define PROTOBUF_COLD __attribute__((cold)) -#else -# define PROTOBUF_COLD -#endif - -#ifdef PROTOBUF_SECTION_VARIABLE -#error PROTOBUF_SECTION_VARIABLE was previously defined -#endif -#if (ABSL_HAVE_ATTRIBUTE(section) || defined(__GNUC__)) && defined(__ELF__) -// Place a variable in the given ELF section. -# define PROTOBUF_SECTION_VARIABLE(x) __attribute__((section(#x))) -#else -# define PROTOBUF_SECTION_VARIABLE(x) -#endif - #if defined(__clang__) #define PROTOBUF_IGNORE_DEPRECATION_START \ _Pragma("clang diagnostic push") \ @@ -386,24 +328,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #define PROTOBUF_IGNORE_DEPRECATION_STOP #endif -#ifdef PROTOBUF_RETURNS_NONNULL -#error PROTOBUF_RETURNS_NONNULL was previously defined -#endif -#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) || defined(__GNUC__) -#define PROTOBUF_RETURNS_NONNULL __attribute__((returns_nonnull)) -#else -#define PROTOBUF_RETURNS_NONNULL -#endif - -#ifdef PROTOBUF_ATTRIBUTE_REINITIALIZES -#error PROTOBUF_ATTRIBUTE_REINITIALIZES was previously defined -#endif -#if ABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes) -#define PROTOBUF_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] -#else -#define PROTOBUF_ATTRIBUTE_REINITIALIZES -#endif - // The minimum library version which works with the current version of the // headers. #define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 4024000 @@ -576,20 +500,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #error PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION was previously defined #endif -#ifdef PROTOBUF_FALLTHROUGH_INTENDED -#error PROTOBUF_FALLTHROUGH_INTENDED was previously defined -#endif -#if ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) -#define PROTOBUF_FALLTHROUGH_INTENDED [[fallthrough]] -#elif ABSL_HAVE_FEATURE(cxx_attributes) && \ - __has_warning("-Wimplicit-fallthrough") -#define PROTOBUF_FALLTHROUGH_INTENDED [[clang::fallthrough]] -#elif defined(__GNUC__) -#define PROTOBUF_FALLTHROUGH_INTENDED [[gnu::fallthrough]] -#else -#define PROTOBUF_FALLTHROUGH_INTENDED -#endif - // Specify memory alignment for structs, classes, etc. // Use like: // class PROTOBUF_ALIGNAS(16) MyClass { ... } @@ -637,22 +547,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #define PROTOBUF_THREAD_LOCAL __thread #endif -// TODO: cleanup PROTOBUF_LITTLE_ENDIAN in various 3p forks. -#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ - __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define PROTOBUF_LITTLE_ENDIAN 1 -#ifdef PROTOBUF_BIG_ENDIAN -#error Conflicting PROTOBUF_BIG_ENDIAN was previously defined -#endif -#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ - __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define PROTOBUF_BIG_ENDIAN 1 -#elif defined(_WIN32) || defined(__x86_64__) || defined(__aarch64__) -#define PROTOBUF_LITTLE_ENDIAN 1 -#else -#error "endian detection failed for current compiler" -#endif - #ifdef PROTOBUF_CONSTINIT #error PROTOBUF_CONSTINIT was previously defined #endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 43cdc0088f..49aeb64865 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -31,13 +31,9 @@ #undef PROTOBUF_NDEBUG_INLINE #undef PROTOBUF_MUSTTAIL #undef PROTOBUF_TAILCALL -#undef PROTOBUF_COLD #undef PROTOBUF_NOINLINE -#undef PROTOBUF_SECTION_VARIABLE #undef PROTOBUF_IGNORE_DEPRECATION_START #undef PROTOBUF_IGNORE_DEPRECATION_STOP -#undef PROTOBUF_RETURNS_NONNULL -#undef PROTOBUF_ATTRIBUTE_REINITIALIZES #undef PROTOBUF_RTTI #undef PROTOBUF_VERSION #undef PROTOBUF_VERSION_SUFFIX @@ -48,7 +44,6 @@ #undef PROTOBUF_MIN_PROTOC_VERSION #undef PROTOBUF_PREDICT_TRUE #undef PROTOBUF_PREDICT_FALSE -#undef PROTOBUF_FALLTHROUGH_INTENDED #undef PROTOBUF_EXPORT #undef PROTOC_EXPORT #undef PROTOBUF_NODISCARD @@ -67,8 +62,6 @@ #undef PROTOBUF_ALIGNAS #undef PROTOBUF_FINAL #undef PROTOBUF_THREAD_LOCAL -#undef PROTOBUF_LITTLE_ENDIAN -#undef PROTOBUF_BIG_ENDIAN #undef PROTOBUF_CONSTINIT #undef PROTOBUF_CONSTEXPR #undef PROTOBUF_CONSTINIT_DEFAULT_INSTANCES @@ -88,10 +81,6 @@ #undef PROTOBUF_USE_TABLE_PARSER_ON_REFLECTION #undef PROTOBUF_BUILTIN_CONSTANT_P #undef PROTOBUF_TC_PARAM_DECL -#undef PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED -#undef PROTOBUF_LOCKS_EXCLUDED -#undef PROTOBUF_NO_THREAD_SAFETY_ANALYSIS -#undef PROTOBUF_GUARDED_BY #undef PROTOBUF_DEBUG #undef PROTO2_IS_OSS #undef PROTOBUF_NO_THREADLOCAL diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 7e3f8d2e36..bbce360899 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -204,13 +204,13 @@ class RepeatedField final // Calling this routine inside a loop can cause quadratic behavior. void ExtractSubrange(int start, int num, Element* elements); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear(); + ABSL_ATTRIBUTE_REINITIALIZES void Clear(); void MergeFrom(const RepeatedField& other); - PROTOBUF_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedField& other); + ABSL_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedField& other); // Replaces the contents with RepeatedField(begin, end). template - PROTOBUF_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end); + ABSL_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end); // Reserves space to expand the field to at least the given size. If the // array is grown, it will always be at least doubled in size. diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index 7a0c0989fe..08642b56c0 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -1097,13 +1097,13 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { // Calling this routine inside a loop can cause quadratic behavior. void DeleteSubrange(int start, int num); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear(); + ABSL_ATTRIBUTE_REINITIALIZES void Clear(); void MergeFrom(const RepeatedPtrField& other); - PROTOBUF_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedPtrField& other); + ABSL_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedPtrField& other); // Replaces the contents with RepeatedPtrField(begin, end). template - PROTOBUF_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end); + ABSL_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end); // Reserves space to expand the field to at least the given size. This only // resizes the pointer array; it doesn't allocate any objects. If the diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index a61cbd2404..faff493a4e 100644 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -120,10 +120,6 @@ void DoNothing() {} // =================================================================== // emulates google3/util/endian/endian.h -// -// TODO: PROTOBUF_LITTLE_ENDIAN is unfortunately defined in -// google/protobuf/io/coded_stream.h and therefore can not be used here. -// Maybe move that macro definition here in the future. uint32_t ghtonl(uint32_t x) { union { uint32_t result; diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index 4a38c372fa..cd4025f6ae 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -21,42 +21,6 @@ // Must be last. #include "google/protobuf/port_def.inc" // NOLINT -#undef PROTOBUF_LITTLE_ENDIAN -#ifdef _WIN32 - // Assuming windows is always little-endian. - // TODO: The PROTOBUF_LITTLE_ENDIAN is not only used for - // optimization but also for correctness. We should define an - // different macro to test the big-endian code path in coded_stream. - #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) - #define PROTOBUF_LITTLE_ENDIAN 1 - #endif -#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) -// If MSVC has "/RTCc" set, it will complain about truncating casts at -// runtime. This file contains some intentional truncating casts. -#pragma runtime_checks("c", off) -#endif -#else -#if (defined(__APPLE__) || defined(__NEWLIB__)) -#include // __BYTE_ORDER -#elif defined(__FreeBSD__) -#include // __BYTE_ORDER -#elif (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__)) -#include // __BYTE_ORDER -#elif defined(_AIX) || defined(__TOS_AIX__) -#include // BYTE_ORDER -#elif defined(__QNX__) -#include // BYTE_ORDER -#else -#include // __BYTE_ORDER -#endif -#if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ - (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ - (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN)) && \ - !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) -#define PROTOBUF_LITTLE_ENDIAN 1 -#endif -#endif - // These #includes are for the byte swap functions declared later on. #ifdef _MSC_VER #include // NOLINT(build/include) @@ -212,7 +176,7 @@ PROTOBUF_EXPORT uint32_t ghtonl(uint32_t x); class BigEndian { public: -#ifdef PROTOBUF_LITTLE_ENDIAN +#ifdef ABSL_IS_LITTLE_ENDIAN static uint16_t FromHost16(uint16_t x) { return bswap_16(x); } static uint16_t ToHost16(uint16_t x) { return bswap_16(x); } diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index 4526417192..bbd012d23c 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -960,7 +960,7 @@ const char* WireFormat::_InternalParseAndMergeField( case FieldDescriptor::TYPE_STRING: utf8_check = true; strict_utf8_check = field->requires_utf8_validation(); - PROTOBUF_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case FieldDescriptor::TYPE_BYTES: { int size = ReadSize(&ptr); if (ptr == nullptr) return nullptr; diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc index d3eb12bbca..2fd31426ce 100644 --- a/src/google/protobuf/wire_format_lite.cc +++ b/src/google/protobuf/wire_format_lite.cc @@ -303,7 +303,7 @@ bool WireFormatLite::ReadPackedEnumPreserveUnknowns( return true; } -#if !defined(PROTOBUF_LITTLE_ENDIAN) +#if !defined(ABSL_IS_LITTLE_ENDIAN) namespace { void EncodeFixedSizeValue(float v, uint8_t* dest) { @@ -335,11 +335,11 @@ void EncodeFixedSizeValue(bool v, uint8_t* dest) { } } // anonymous namespace -#endif // !defined(PROTOBUF_LITTLE_ENDIAN) +#endif // !defined(ABSL_IS_LITTLE_ENDIAN) template static void WriteArray(const CType* a, int n, io::CodedOutputStream* output) { -#if defined(PROTOBUF_LITTLE_ENDIAN) +#if defined(ABSL_IS_LITTLE_ENDIAN) output->WriteRaw(reinterpret_cast(a), n * sizeof(a[0])); #else const int kAtATime = 128; diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index ef368808c5..872c5ff02b 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -1206,7 +1206,7 @@ inline bool WireFormatLite::ReadPackedFixedSizePrimitive( } if (bytes_limit >= new_bytes) { // Fast-path that pre-allocates *values to the final size. -#if defined(PROTOBUF_LITTLE_ENDIAN) +#if defined(ABSL_IS_LITTLE_ENDIAN) values->Resize(old_entries + new_entries, 0); // values->mutable_data() may change after Resize(), so do this after: void* dest = reinterpret_cast(values->mutable_data() + old_entries); @@ -1476,7 +1476,7 @@ template inline uint8_t* WireFormatLite::WriteFixedNoTagToArray( const RepeatedField& value, uint8_t* (*Writer)(T, uint8_t*), uint8_t* target) { -#if defined(PROTOBUF_LITTLE_ENDIAN) +#if defined(ABSL_IS_LITTLE_ENDIAN) (void)Writer; const int n = value.size(); From e221e98e999c1ee63e6a5a147d985ff04e3f50c1 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 18 Oct 2023 17:25:08 +0000 Subject: [PATCH 26/95] Auto-generate files after cl/574510248 --- src/google/protobuf/any.pb.cc | 30 ++-- src/google/protobuf/any.pb.h | 2 +- src/google/protobuf/api.pb.cc | 104 +++++++------- src/google/protobuf/api.pb.h | 6 +- src/google/protobuf/duration.pb.cc | 30 ++-- src/google/protobuf/duration.pb.h | 2 +- src/google/protobuf/empty.pb.cc | 26 ++-- src/google/protobuf/field_mask.pb.cc | 28 ++-- src/google/protobuf/field_mask.pb.h | 2 +- src/google/protobuf/source_context.pb.cc | 28 ++-- src/google/protobuf/source_context.pb.h | 2 +- src/google/protobuf/struct.pb.cc | 100 ++++++------- src/google/protobuf/struct.pb.h | 6 +- src/google/protobuf/timestamp.pb.cc | 30 ++-- src/google/protobuf/timestamp.pb.h | 2 +- src/google/protobuf/type.pb.cc | 176 ++++++++++++----------- src/google/protobuf/type.pb.h | 10 +- src/google/protobuf/wrappers.pb.cc | 172 +++++++++++----------- src/google/protobuf/wrappers.pb.h | 18 +-- 19 files changed, 397 insertions(+), 377 deletions(-) diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 930ad77df0..e864f9d8d4 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -58,29 +58,31 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Any, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Any, _impl_.type_url_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Any, _impl_.value_), +const ::uint32_t + TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Any, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Any, _impl_.type_url_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Any, _impl_.value_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, -1, -1, sizeof(::google::protobuf::Any)}, }; static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_Any_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\031google/protobuf/any.proto\022\017google.prot" "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002" " \001(\014Bv\n\023com.google.protobufB\010AnyProtoP\001Z" diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index affeb7b6c8..0e1d77b3bd 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -203,7 +203,7 @@ class PROTOBUF_EXPORT Any final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 8823fd6e88..2a4e891c56 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -113,59 +113,60 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.methods_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.version_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.source_context_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.mixins_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.syntax_), - ~0u, - ~0u, - ~0u, - ~0u, - 0, - ~0u, - ~0u, - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.request_type_url_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.request_streaming_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.response_type_url_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.response_streaming_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.syntax_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Mixin, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Mixin, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Mixin, _impl_.root_), +const ::uint32_t + TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.methods_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.version_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.source_context_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.mixins_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.syntax_), + ~0u, + ~0u, + ~0u, + ~0u, + 0, + ~0u, + ~0u, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.request_type_url_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.request_streaming_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.response_type_url_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.response_streaming_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.syntax_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Mixin, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Mixin, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Mixin, _impl_.root_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 15, -1, sizeof(::google::protobuf::Api)}, {22, -1, -1, sizeof(::google::protobuf::Method)}, {37, -1, -1, sizeof(::google::protobuf::Mixin)}, @@ -176,7 +177,8 @@ static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_Method_default_instance_._instance, &::google::protobuf::_Mixin_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\031google/protobuf/api.proto\022\017google.prot" "obuf\032$google/protobuf/source_context.pro" "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014" diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 58eb072c74..92dbccec85 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -176,7 +176,7 @@ class PROTOBUF_EXPORT Mixin final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -375,7 +375,7 @@ class PROTOBUF_EXPORT Method final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -648,7 +648,7 @@ class PROTOBUF_EXPORT Api final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index 832aae80e1..90237e4cfe 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -49,29 +49,31 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fduration_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Duration, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Duration, _impl_.seconds_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Duration, _impl_.nanos_), +const ::uint32_t + TableStruct_google_2fprotobuf_2fduration_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Duration, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Duration, _impl_.seconds_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Duration, _impl_.nanos_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, -1, -1, sizeof(::google::protobuf::Duration)}, }; static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_Duration_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\036google/protobuf/duration.proto\022\017google" ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r" "\n\005nanos\030\002 \001(\005B\203\001\n\023com.google.protobufB\rD" diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index b3d14923b2..2f79454e5f 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -168,7 +168,7 @@ class PROTOBUF_EXPORT Duration final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index f561752542..0601bb4064 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -41,27 +41,29 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fempty_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Empty, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) +const ::uint32_t + TableStruct_google_2fprotobuf_2fempty_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Empty, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, -1, -1, sizeof(::google::protobuf::Empty)}, }; static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_Empty_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\033google/protobuf/empty.proto\022\017google.pr" "otobuf\"\007\n\005EmptyB}\n\023com.google.protobufB\n" "EmptyProtoP\001Z.google.golang.org/protobuf" diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index a897d8a2ab..0eeae84950 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -48,28 +48,30 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldMask, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldMask, _impl_.paths_), +const ::uint32_t + TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldMask, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FieldMask, _impl_.paths_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, -1, -1, sizeof(::google::protobuf::FieldMask)}, }; static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_FieldMask_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n google/protobuf/field_mask.proto\022\017goog" "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB" "\205\001\n\023com.google.protobufB\016FieldMaskProtoP" diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index a9c9868453..787e47152e 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -168,7 +168,7 @@ class PROTOBUF_EXPORT FieldMask final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index d22acee088..82c89ed22a 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -50,28 +50,30 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceContext, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceContext, _impl_.file_name_), +const ::uint32_t + TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceContext, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceContext, _impl_.file_name_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, -1, -1, sizeof(::google::protobuf::SourceContext)}, }; static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_SourceContext_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n$google/protobuf/source_context.proto\022\017" "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile" "_name\030\001 \001(\tB\212\001\n\023com.google.protobufB\022Sou" diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index e4127454df..51b0402123 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -168,7 +168,7 @@ class PROTOBUF_EXPORT SourceContext final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index 2a20dd6918..fe6ca61ca3 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -98,57 +98,58 @@ static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fstruct_2eproto[4] static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[1]; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, _has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, key_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, value_), - 0, - 1, - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct, _impl_.fields_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Value, _internal_metadata_), - ~0u, // no _extensions_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Value, _impl_._oneof_case_[0]), - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - ::_pbi::kInvalidFieldOffsetTag, - ::_pbi::kInvalidFieldOffsetTag, - ::_pbi::kInvalidFieldOffsetTag, - ::_pbi::kInvalidFieldOffsetTag, - ::_pbi::kInvalidFieldOffsetTag, - ::_pbi::kInvalidFieldOffsetTag, - PROTOBUF_FIELD_OFFSET(::google::protobuf::Value, _impl_.kind_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::ListValue, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::ListValue, _impl_.values_), +const ::uint32_t + TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, _has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, key_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, value_), + 0, + 1, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Struct, _impl_.fields_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Value, _internal_metadata_), + ~0u, // no _extensions_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Value, _impl_._oneof_case_[0]), + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + ::_pbi::kInvalidFieldOffsetTag, + ::_pbi::kInvalidFieldOffsetTag, + ::_pbi::kInvalidFieldOffsetTag, + ::_pbi::kInvalidFieldOffsetTag, + ::_pbi::kInvalidFieldOffsetTag, + ::_pbi::kInvalidFieldOffsetTag, + PROTOBUF_FIELD_OFFSET(::google::protobuf::Value, _impl_.kind_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::ListValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::ListValue, _impl_.values_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 10, -1, sizeof(::google::protobuf::Struct_FieldsEntry_DoNotUse)}, {12, -1, -1, sizeof(::google::protobuf::Struct)}, {21, -1, -1, sizeof(::google::protobuf::Value)}, @@ -161,7 +162,8 @@ static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_Value_default_instance_._instance, &::google::protobuf::_ListValue_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\034google/protobuf/struct.proto\022\017google.p" "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo" "gle.protobuf.Struct.FieldsEntry\032E\n\013Field" diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 70deb30046..40010b95ba 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -213,7 +213,7 @@ class PROTOBUF_EXPORT ListValue final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -396,7 +396,7 @@ class PROTOBUF_EXPORT Struct final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -618,7 +618,7 @@ class PROTOBUF_EXPORT Value final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 668dbf3ed7..4cb535e7b3 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -49,29 +49,31 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Timestamp, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Timestamp, _impl_.seconds_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Timestamp, _impl_.nanos_), +const ::uint32_t + TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Timestamp, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Timestamp, _impl_.seconds_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Timestamp, _impl_.nanos_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, -1, -1, sizeof(::google::protobuf::Timestamp)}, }; static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_Timestamp_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\037google/protobuf/timestamp.proto\022\017googl" "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003" "\022\r\n\005nanos\030\002 \001(\005B\205\001\n\023com.google.protobufB" diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index bb0b9dd972..aa31472f5f 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -168,7 +168,7 @@ class PROTOBUF_EXPORT Timestamp final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 2bcd7e1760..29bae8b957 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -166,95 +166,96 @@ static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2ftype_2eproto[5]; static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[3]; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2ftype_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.fields_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.oneofs_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.source_context_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.syntax_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.edition_), - ~0u, - ~0u, - ~0u, - ~0u, - 0, - ~0u, - ~0u, - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.kind_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.cardinality_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.number_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.type_url_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.oneof_index_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.packed_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.json_name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.default_value_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.enumvalue_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.source_context_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.syntax_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.edition_), - ~0u, - ~0u, - ~0u, - 0, - ~0u, - ~0u, - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValue, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValue, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValue, _impl_.number_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValue, _impl_.options_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Option, _impl_._has_bits_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Option, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Option, _impl_.name_), - PROTOBUF_FIELD_OFFSET(::google::protobuf::Option, _impl_.value_), - ~0u, - 0, +const ::uint32_t + TableStruct_google_2fprotobuf_2ftype_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.fields_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.oneofs_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.source_context_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.syntax_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Type, _impl_.edition_), + ~0u, + ~0u, + ~0u, + ~0u, + 0, + ~0u, + ~0u, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.kind_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.cardinality_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.number_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.type_url_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.oneof_index_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.packed_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.json_name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Field, _impl_.default_value_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.enumvalue_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.source_context_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.syntax_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Enum, _impl_.edition_), + ~0u, + ~0u, + ~0u, + 0, + ~0u, + ~0u, + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValue, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValue, _impl_.number_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::EnumValue, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Option, _impl_._has_bits_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Option, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Option, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::Option, _impl_.value_), + ~0u, + 0, }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 15, -1, sizeof(::google::protobuf::Type)}, {22, -1, -1, sizeof(::google::protobuf::Field)}, {40, 54, -1, sizeof(::google::protobuf::Enum)}, @@ -269,7 +270,8 @@ static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_EnumValue_default_instance_._instance, &::google::protobuf::_Option_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\032google/protobuf/type.proto\022\017google.pro" "tobuf\032\031google/protobuf/any.proto\032$google" "/protobuf/source_context.proto\"\350\001\n\004Type\022" diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index bbde59acd2..0ae554ccfb 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -302,7 +302,7 @@ class PROTOBUF_EXPORT Option final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -501,7 +501,7 @@ class PROTOBUF_EXPORT Field final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -875,7 +875,7 @@ class PROTOBUF_EXPORT EnumValue final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1088,7 +1088,7 @@ class PROTOBUF_EXPORT Type final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1387,7 +1387,7 @@ class PROTOBUF_EXPORT Enum final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index 18f64b7eda..95244fc650 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -204,93 +204,94 @@ static constexpr const ::_pb::EnumDescriptor** file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr; static constexpr const ::_pb::ServiceDescriptor** file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr; -const ::uint32_t TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( - protodesc_cold) = { - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::DoubleValue, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::DoubleValue, _impl_.value_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::FloatValue, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::FloatValue, _impl_.value_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Int64Value, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Int64Value, _impl_.value_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::UInt64Value, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::UInt64Value, _impl_.value_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::Int32Value, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::Int32Value, _impl_.value_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::UInt32Value, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::UInt32Value, _impl_.value_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::BoolValue, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::BoolValue, _impl_.value_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::StringValue, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::StringValue, _impl_.value_), - ~0u, // no _has_bits_ - PROTOBUF_FIELD_OFFSET(::google::protobuf::BytesValue, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - ~0u, // no _inlined_string_donated_ - ~0u, // no _split_ - ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::google::protobuf::BytesValue, _impl_.value_), +const ::uint32_t + TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::DoubleValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::DoubleValue, _impl_.value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::FloatValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::FloatValue, _impl_.value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Int64Value, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Int64Value, _impl_.value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::UInt64Value, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::UInt64Value, _impl_.value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::Int32Value, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::Int32Value, _impl_.value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::UInt32Value, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::UInt32Value, _impl_.value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::BoolValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::BoolValue, _impl_.value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::StringValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::StringValue, _impl_.value_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::protobuf::BytesValue, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ~0u, // no _split_ + ~0u, // no sizeof(Split) + PROTOBUF_FIELD_OFFSET(::google::protobuf::BytesValue, _impl_.value_), }; static const ::_pbi::MigrationSchema - schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, -1, -1, sizeof(::google::protobuf::DoubleValue)}, {9, -1, -1, sizeof(::google::protobuf::FloatValue)}, {18, -1, -1, sizeof(::google::protobuf::Int64Value)}, @@ -313,7 +314,8 @@ static const ::_pb::Message* const file_default_instances[] = { &::google::protobuf::_StringValue_default_instance_._instance, &::google::protobuf::_BytesValue_default_instance_._instance, }; -const char descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +const char descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( + protodesc_cold) = { "\n\036google/protobuf/wrappers.proto\022\017google" ".protobuf\"\034\n\013DoubleValue\022\r\n\005value\030\001 \001(\001\"" "\033\n\nFloatValue\022\r\n\005value\030\001 \001(\002\"\033\n\nInt64Val" diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 122972a547..4491ed9874 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -192,7 +192,7 @@ class PROTOBUF_EXPORT UInt64Value final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -367,7 +367,7 @@ class PROTOBUF_EXPORT UInt32Value final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -542,7 +542,7 @@ class PROTOBUF_EXPORT StringValue final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -723,7 +723,7 @@ class PROTOBUF_EXPORT Int64Value final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -898,7 +898,7 @@ class PROTOBUF_EXPORT Int32Value final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1073,7 +1073,7 @@ class PROTOBUF_EXPORT FloatValue final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1248,7 +1248,7 @@ class PROTOBUF_EXPORT DoubleValue final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1423,7 +1423,7 @@ class PROTOBUF_EXPORT BytesValue final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; @@ -1604,7 +1604,7 @@ class PROTOBUF_EXPORT BoolValue final : private: static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; ::size_t ByteSizeLong() const final; From 7f0787829fd677a5d0bbaf0cdaf10c29b76c9b2b Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 18 Oct 2023 11:29:11 -0700 Subject: [PATCH 27/95] Clarify the preconditions of AddXXX functions. Also, add a debug check to verify this precondition. PiperOrigin-RevId: 574538974 --- src/google/protobuf/repeated_field_unittest.cc | 8 ++++++++ src/google/protobuf/repeated_ptr_field.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index f5529ed784..529d872284 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -1677,6 +1677,14 @@ TEST(RepeatedPtrField, AddAllocated) { EXPECT_EQ(moo, &field.Get(index)); } +TEST(RepeatedPtrField, AddMethodsDontAcceptNull) { +#if !defined(NDEBUG) + RepeatedPtrField field; + EXPECT_DEATH(field.AddAllocated(nullptr), "nullptr"); + EXPECT_DEATH(field.UnsafeArenaAddAllocated(nullptr), "nullptr"); +#endif +} + TEST(RepeatedPtrField, AddAllocatedDifferentArena) { RepeatedPtrField field; Arena arena; diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index 08642b56c0..72beb1c2f5 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -443,11 +443,13 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { template void AddAllocated(Value* value) { typename TypeImplementsMergeBehavior>::type t; + ABSL_DCHECK_NE(value, nullptr); AddAllocatedInternal(value, t); } template void UnsafeArenaAddAllocated(Value* value) { + ABSL_DCHECK_NE(value, nullptr); // Make room for the new pointer. if (current_size_ == total_size_) { // The array is completely full with no cleared objects, so grow it. @@ -1179,6 +1181,7 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { // (ii) if this field holds strings, the passed-in string *must* be // heap-allocated, not arena-allocated. There is no way to dynamically check // this at runtime, so User Beware. + // Requires: value != nullptr void AddAllocated(Element* value); // Removes and returns the last element, passing ownership to the caller. @@ -1201,6 +1204,7 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { // If you put temp_field on the arena this fails, because the ownership // transfers to the arena at the "AddAllocated" call and is not released // anymore, causing a double delete. UnsafeArenaAddAllocated prevents this. + // Requires: value != nullptr void UnsafeArenaAddAllocated(Element* value); // Removes and returns the last element. Unlike ReleaseLast, the returned From eccbf14f11c0fe17f7437f61a93d1883b4a98393 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 18 Oct 2023 11:49:28 -0700 Subject: [PATCH 28/95] Use GetArena() instead of GetOwningArena() #4. PiperOrigin-RevId: 574544964 --- src/google/protobuf/arena.h | 2 +- src/google/protobuf/arena_unittest.cc | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index ffc9cb1608..0e5d6a9e00 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -261,7 +261,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // again. template PROTOBUF_ALWAYS_INLINE static void Destroy(T* obj) { - if (InternalGetOwningArena(obj) == nullptr) delete obj; + if (InternalGetArena(obj) == nullptr) delete obj; } // Allocates memory with the specific size and alignment. diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 4a2d502cc1..21041129fb 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -561,16 +561,6 @@ TEST(ArenaTest, UnsafeArenaSwap) { TestUtil::ExpectAllFieldsSet(*message2); } -TEST(ArenaTest, GetOwningArena) { - Arena arena; - auto* m1 = Arena::CreateMessage(&arena); - EXPECT_EQ(Arena::InternalGetOwningArena(m1), &arena); - EXPECT_EQ(&arena, Arena::InternalGetOwningArena( - m1->mutable_repeated_foreign_message())); - EXPECT_EQ(&arena, - Arena::InternalGetOwningArena(m1->mutable_repeated_int32())); -} - TEST(ArenaTest, SwapBetweenArenasUsingReflection) { Arena arena1; TestAllTypes* arena1_message = Arena::CreateMessage(&arena1); From aa612739aba01fad33728ed5eb0b1bb4bc74b228 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 18 Oct 2023 11:55:28 -0700 Subject: [PATCH 29/95] Internal changes. PiperOrigin-RevId: 574546719 --- .../protobuf/compiler/allowlists/BUILD.bazel | 2 +- .../protobuf/compiler/allowlists/allowlist.h | 4 + .../compiler/allowlists/weak_imports.cc | 29 -- .../compiler/command_line_interface.cc | 4 +- .../cpp/tools/analyze_profile_proto.cc | 332 ++++++++++++++++++ .../cpp/tools/analyze_profile_proto.h | 42 +++ .../cpp/tools/analyze_profile_proto_main.cc | 42 +++ .../cpp/tools/analyze_profile_proto_test.cc | 145 ++++++++ .../tools/analyze_profile_proto_test.proto | 21 ++ 9 files changed, 590 insertions(+), 31 deletions(-) delete mode 100644 src/google/protobuf/compiler/allowlists/weak_imports.cc create mode 100644 src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc create mode 100644 src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.h create mode 100644 src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_main.cc create mode 100644 src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc create mode 100644 src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.proto diff --git a/src/google/protobuf/compiler/allowlists/BUILD.bazel b/src/google/protobuf/compiler/allowlists/BUILD.bazel index ebedfadf91..470181fd6d 100644 --- a/src/google/protobuf/compiler/allowlists/BUILD.bazel +++ b/src/google/protobuf/compiler/allowlists/BUILD.bazel @@ -12,6 +12,7 @@ cc_library( "//src/google/protobuf/stubs", "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/strings", "@com_google_absl//absl/types:span", ], @@ -24,7 +25,6 @@ cc_library( "empty_package.cc", "open_enum.cc", "unused_imports.cc", - "weak_imports.cc", ], hdrs = ["allowlists.h"], copts = COPTS, diff --git a/src/google/protobuf/compiler/allowlists/allowlist.h b/src/google/protobuf/compiler/allowlists/allowlist.h index 7a7a97d88c..71034db07e 100644 --- a/src/google/protobuf/compiler/allowlists/allowlist.h +++ b/src/google/protobuf/compiler/allowlists/allowlist.h @@ -10,10 +10,12 @@ #include #include +#include #include #include "absl/algorithm/container.h" #include "google/protobuf/stubs/common.h" +#include "absl/container/flat_hash_set.h" #include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" @@ -29,8 +31,10 @@ enum AllowlistFlags : unsigned int { kNone = 0, kMatchPrefix = 1 << 1, kAllowAllInOss = 1 << 2, + kAllowAllWhenEmpty = 1 << 3, }; + #if !defined(__GNUC__) || defined(__clang__) || PROTOBUF_GNUC_MIN(9, 1) using maybe_string_view = absl::string_view; #else diff --git a/src/google/protobuf/compiler/allowlists/weak_imports.cc b/src/google/protobuf/compiler/allowlists/weak_imports.cc deleted file mode 100644 index 5fca2d6793..0000000000 --- a/src/google/protobuf/compiler/allowlists/weak_imports.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -#include "google/protobuf/compiler/allowlists/allowlists.h" - -#include "absl/strings/string_view.h" -#include "google/protobuf/compiler/allowlists/allowlist.h" - -namespace google { -namespace protobuf { -namespace compiler { - -// NOTE: Allowlists in this file are not accepting new entries unless otherwise -// specified. - -static constexpr auto kWeakImports = internal::MakeAllowlist({ -// Intentionally left blank. -}); - -bool IsWeakImportFile(absl::string_view file) { - return kWeakImports.Allows(file); -} -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 1f34645e26..2e12765533 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -2211,7 +2211,9 @@ CommandLineInterface::InterpretArgument(const std::string& name, if (!version_info_.empty()) { std::cout << version_info_ << std::endl; } - std::cout << "libprotoc " << internal::ProtocVersionString(PROTOBUF_VERSION) + std::cout << "libprotoc " + << ::google::protobuf::internal::ProtocVersionString( + PROTOBUF_VERSION) << PROTOBUF_VERSION_SUFFIX << std::endl; return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler. diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc new file mode 100644 index 0000000000..f5042371b1 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc @@ -0,0 +1,332 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "google/protobuf/compiler/cpp/tools/analyze_profile_proto.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "google/protobuf/testing/file.h" +#include "google/protobuf/testing/file.h" +#include "google/protobuf/compiler/access_info_map.h" +#include "google/protobuf/compiler/profile_bootstrap.pb.h" +#include "absl/log/absl_log.h" +#include "absl/log/log.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/cord.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/cpp/cpp_access_info_parse_helper.h" +#include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor.pb.h" +#include "third_party/re2/re2.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace tools { + +namespace { + +enum PDProtoScale { kNever, kRarely, kDefault, kLikely }; + +struct PDProtoAnalysis { + PDProtoScale presence = PDProtoScale::kDefault; + PDProtoScale usage = PDProtoScale::kDefault; +}; + +std::ostream& operator<<(std::ostream& s, PDProtoScale scale) { + switch (scale) { + case PDProtoScale::kNever: + return s << "NEVER"; + case PDProtoScale::kRarely: + return s << "RARELY"; + case PDProtoScale::kDefault: + return s << "DEFAULT"; + case PDProtoScale::kLikely: + return s << "LIKELY"; + } + return s; +} + +enum PDProtoOptimization { kNone, kLazy, kInline, kSplit }; + +std::ostream& operator<<(std::ostream& s, PDProtoOptimization optimization) { + switch (optimization) { + case PDProtoOptimization::kNone: + return s << "NONE"; + case PDProtoOptimization::kLazy: + return s << "LAZY"; + case PDProtoOptimization::kInline: + return s << "INLINE"; + case PDProtoOptimization::kSplit: + return s << "SPLIT"; + } + return s; +} + +class PDProtoAnalyzer { + public: + explicit PDProtoAnalyzer(const AccessInfo& access_info) + : info_map_(access_info) { + info_map_.SetAccessInfoParseHelper( + std::make_unique()); + } + + bool HasProfile(const Descriptor* descriptor) const { + return info_map_.HasProfile(descriptor); + } + + PDProtoAnalysis AnalyzeField(const FieldDescriptor* field) { + PDProtoAnalysis analysis; + + if (info_map_.InProfile(field)) { + if (IsLikelyPresent(field)) { + analysis.presence = PDProtoScale::kLikely; + } else if (IsRarelyPresent(field)) { + analysis.presence = PDProtoScale::kRarely; + } + } + + if (info_map_.InProfile(field) && + info_map_.AccessCount(field, AccessInfoMap::kReadWriteOther) <= + info_map_.GetUnlikelyUsedThreshold()) { + analysis.usage = PDProtoScale::kRarely; + } + + return analysis; + } + + PDProtoOptimization OptimizeField(const FieldDescriptor* field) { + PDProtoAnalysis analysis = AnalyzeField(field); + if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + if (analysis.presence >= PDProtoScale::kLikely) { + if (cpp::CanStringBeInlined(field)) { + return PDProtoOptimization::kInline; + } + } + } + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (analysis.presence > PDProtoScale::kRarely) { + // Exclude 'never' as that may simply mean we have no data. + if (analysis.usage == PDProtoScale::kRarely) { + if (!field->is_repeated()) { + return PDProtoOptimization::kLazy; + } + } + } + } + return PDProtoOptimization::kNone; + } + + uint64_t UnlikelyUsedThreshold() const { + return info_map_.GetUnlikelyUsedThreshold(); + } + + private: + bool IsLikelyPresent(const FieldDescriptor* field) const { + // This threshold was arbitrarily chosen based on a few macrobenchmark + // results. + constexpr double kHotRatio = 0.90; + + return (info_map_.IsHot(field, AccessInfoMap::kRead, kHotRatio) || + info_map_.IsHot(field, AccessInfoMap::kWrite, kHotRatio)); + } + + bool IsRarelyPresent(const FieldDescriptor* field) const { + // This threshold was arbitrarily chosen based on a few macrobenchmark + // results. Since most cold fields have zero presence count, PDProto + // optimization hasn't been sensitive to the threshold. + constexpr double kColdRatio = 0.005; + + return info_map_.IsCold(field, AccessInfoMap::kRead, kColdRatio) && + info_map_.IsCold(field, AccessInfoMap::kWrite, kColdRatio); + } + + AccessInfoMap info_map_; +}; + +size_t GetLongestName(const DescriptorPool& pool, absl::string_view name, + size_t min_length) { + size_t pos = name.length(); + while (pos > min_length) { + if (name[--pos] == '_') { + if (pool.FindMessageTypeByName(name.substr(0, pos))) { + return pos; + } + } + } + return 0; +} + +const Descriptor* FindMessageTypeByCppName(const DescriptorPool& pool, + absl::string_view name) { + std::string s = absl::StrReplaceAll(name, {{"::", "."}}); + const Descriptor* descriptor = pool.FindMessageTypeByName(s); + if (descriptor) return descriptor; + + size_t min_length = 1; + while (size_t pos = GetLongestName(pool, s, min_length)) { + s[pos] = '.'; + descriptor = pool.FindMessageTypeByName(s); + if (descriptor) return descriptor; + min_length = pos + 1; + } + + ABSL_LOG(WARNING) << "Unknown c++ message name '" << name << "'"; + return nullptr; +} + +std::string TypeName(const FieldDescriptor* descriptor) { + if (descriptor == nullptr) return "UNKNOWN"; + std::string s; + switch (descriptor->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + s = "int32"; + break; + case FieldDescriptor::CPPTYPE_INT64: + s = "int64"; + break; + case FieldDescriptor::CPPTYPE_UINT32: + s = "uint32"; + break; + case FieldDescriptor::CPPTYPE_UINT64: + s = "uint64"; + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + s = "double"; + break; + case FieldDescriptor::CPPTYPE_FLOAT: + s = "float"; + break; + case FieldDescriptor::CPPTYPE_BOOL: + s = "bool"; + break; + case FieldDescriptor::CPPTYPE_ENUM: + s = "enum"; + break; + case FieldDescriptor::CPPTYPE_STRING: + s = "string"; + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + s = descriptor->message_type()->name(); + break; + default: + s = "UNKNOWN"; + break; + } + if (descriptor->is_repeated()) s += "[]"; + return s; +} + +absl::StatusOr AccessInfoFromFile(absl::string_view profile) { + absl::Cord cord; + absl::Status status = GetContents(profile, &cord, true); + if (!status.ok()) { + return status; + } + + AccessInfo access_info_proto; + if (!access_info_proto.ParseFromCord(cord)) { + return absl::DataLossError("Failed to parse AccessInfo"); + } + + return access_info_proto; +} + +std::vector SortMessages( + const AccessInfo& access_info) { + std::vector sorted; + for (const MessageAccessInfo& info : access_info.message()) { + sorted.push_back(&info); + } + std::sort(sorted.begin(), sorted.end(), + [](const MessageAccessInfo* lhs, const MessageAccessInfo* rhs) { + return lhs->name() < rhs->name(); + }); + return sorted; +} + +} // namespace + +absl::Status AnalyzeProfileProtoToText( + std::ostream& stream, absl::string_view proto_profile, + const AnalyzeProfileProtoOptions& options) { + if (options.pool == nullptr) { + return absl::InvalidArgumentError("pool must not be null"); + } + const DescriptorPool& pool = *options.pool; + RE2 regex(options.message_filter.empty() ? ".*" : options.message_filter); + if (!regex.ok()) { + return absl::InvalidArgumentError("Invalid regular expression"); + } + + absl::StatusOr access_info = AccessInfoFromFile(proto_profile); + if (!access_info.ok()) { + return access_info.status(); + } + PDProtoAnalyzer analyzer(*access_info); + + if (options.print_unused_threshold) { + stream << "Unlikely Used Threshold = " << analyzer.UnlikelyUsedThreshold() + << "\n" + << "See http://go/pdlazy for more information\n" + << "-----------------------------------------\n"; + } + + for (const MessageAccessInfo* message : SortMessages(*access_info)) { + if (RE2::PartialMatch(message->name(), regex)) { + if (const Descriptor* descriptor = + FindMessageTypeByCppName(pool, message->name())) { + if (analyzer.HasProfile(descriptor)) { + bool message_header = false; + for (int i = 0; i < descriptor->field_count(); ++i) { + const FieldDescriptor* field = descriptor->field(i); + PDProtoAnalysis analysis = analyzer.AnalyzeField(field); + PDProtoOptimization optimized = analyzer.OptimizeField(field); + if (options.print_all_fields || options.print_analysis || + optimized != PDProtoOptimization::kNone) { + if (!message_header) { + message_header = true; + stream << "Message " << descriptor->full_name() << "\n"; + } + stream << " " << TypeName(field) << " " << field->name() << ":"; + + if (options.print_analysis) { + if (analysis.presence != PDProtoScale::kDefault) { + stream << " " << analysis.presence << "_PRESENT"; + } + if (analysis.usage != PDProtoScale::kDefault) { + stream << " " << analysis.usage << "_USED"; + } + } + if (optimized != PDProtoOptimization::kNone) { + stream << " " << optimized; + } + stream << "\n"; + } + } + } + } + } + } + return absl::OkStatus(); +} + +} // namespace tools +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.h b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.h new file mode 100644 index 0000000000..f80bf5c9eb --- /dev/null +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.h @@ -0,0 +1,42 @@ +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_TOOLS_ANALYZE_PROFILE_PROTO_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_TOOLS_ANALYZE_PROFILE_PROTO_H__ + +#include +#include + +#include "absl/status/status.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/descriptor.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace tools { + +struct AnalyzeProfileProtoOptions { + // true to print the 'unlikely used' threshold. + bool print_unused_threshold = true; + + // true to print all fields instead of optimized fields only. + bool print_all_fields = false; + + // true to include presence and usage info instead of only optimization info + bool print_analysis = false; + + // Descriptor pool to use. Must not be null. + const DescriptorPool* pool = nullptr; + + // Regular expression for message name matching, empty to include all. + std::string message_filter; +}; + +absl::Status AnalyzeProfileProtoToText( + std::ostream& stream, absl::string_view proto_profile, + const AnalyzeProfileProtoOptions& options); + +} // namespace tools +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_TOOLS_ANALYZE_PROFILE_PROTO_H__ diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_main.cc b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_main.cc new file mode 100644 index 0000000000..4b9035abfe --- /dev/null +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_main.cc @@ -0,0 +1,42 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include +#include + +#include "base/init_google.h" +#include "google/protobuf/util/globaldb/global_descriptor_database.h" +#include "absl/flags/flag.h" +#include "absl/log/absl_log.h" +#include "absl/status/status.h" +#include "google/protobuf/compiler/cpp/tools/analyze_profile_proto.h" +#include "google/protobuf/descriptor.h" + +ABSL_FLAG(bool, all, false, "Print all fields"); +ABSL_FLAG(bool, analysis, false, "Print field analysis"); +ABSL_FLAG(std::string, message_filter, "", "Regex match for message name"); + +int main(int argc, char* argv[]) { + using google::protobuf::compiler::tools::AnalyzeProfileProtoOptions; + using google::protobuf::compiler::tools::AnalyzeProfileProtoToText; + + InitGoogle(argv[0], &argc, &argv, true); + if (argc < 2) return 1; + + google::protobuf::DescriptorPool pool(google::protobuf::util::globaldb::global()); + AnalyzeProfileProtoOptions options; + options.pool = &pool; + options.print_all_fields = absl::GetFlag(FLAGS_all); + options.print_analysis = absl::GetFlag(FLAGS_analysis); + options.message_filter = absl::GetFlag(FLAGS_message_filter); + absl::Status status = AnalyzeProfileProtoToText(std::cout, argv[1], options); + if (!status.ok()) { + ABSL_LOG(ERROR) << status; + return 2; + } + return 0; +} diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc new file mode 100644 index 0000000000..8b13cf06a4 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc @@ -0,0 +1,145 @@ +#include "google/protobuf/compiler/cpp/tools/analyze_profile_proto.h" + +#include +#include + +#include "google/protobuf/testing/file.h" +#include "google/protobuf/testing/file.h" +#include "google/protobuf/testing/path.h" +#include "google/protobuf/compiler/profile.pb.h" +#include "google/protobuf/testing/googletest.h" +#include +#include "absl/log/absl_check.h" +#include "google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.pb.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/test_textproto.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace tools { +namespace { + +std::string AnalyzeToText(const AccessInfo& info, + AnalyzeProfileProtoOptions options) { + std::string filename = file::JoinPath(TestTempDir(), "profile.proto"); + ABSL_CHECK_OK(file::SetBinaryProto(filename, info, true)); + std::stringstream str; + ABSL_CHECK_OK(AnalyzeProfileProtoToText(str, filename, options)); + return str.str(); +} + +TEST(AnalyzeProfileProtoTest, EmptyProfileToText) { + AccessInfo info; + AnalyzeProfileProtoOptions options; + options.pool = DescriptorPool::generated_pool(); + EXPECT_STREQ(AnalyzeToText(info, options).c_str(), + "Unlikely Used Threshold = 0\n" + "See http://go/pdlazy for more information\n" + "-----------------------------------------\n"); +} + +TEST(AnalyzeProfileProtoTest, UnlikelyStringPresence) { + AccessInfo info = ParseTextOrDie(R"pb( + language: "cpp" + message { + name: "google::protobuf::compiler::tools::AnalyzeThis" + count: 100 + field { name: "optional_string" getters_count: 1 } + } + )pb"); + AnalyzeProfileProtoOptions options; + options.print_unused_threshold = false; + options.pool = DescriptorPool::generated_pool(); + EXPECT_STREQ(AnalyzeToText(info, options).c_str(), ""); +} + +TEST(AnalyzeProfileProtoTest, LikelyStringPresence) { + AccessInfo info = ParseTextOrDie(R"pb( + language: "cpp" + message { + name: "google::protobuf::compiler::tools::AnalyzeThis" + count: 100 + field { name: "optional_string" getters_count: 99 } + } + )pb"); + AnalyzeProfileProtoOptions options; + options.print_unused_threshold = false; + options.pool = DescriptorPool::generated_pool(); + EXPECT_STREQ(AnalyzeToText(info, options).c_str(), + "Message google.protobuf.compiler.tools.AnalyzeThis\n" + " string optional_string: INLINE\n"); +} + +TEST(AnalyzeProfileProtoTest, ChildLikelyPresentAndUsed) { + // Note that the logic pics a 50th percentile threshold which we need to + // exceed, making testing slightly awkward + AccessInfo info = ParseTextOrDie(R"pb( + language: "cpp" + message { + name: "google::protobuf::compiler::tools::AnalyzeThis" + count: 100 + field { name: "id" getters_count: 0 configs_count: 100 } + field { name: "optional_string" getters_count: 100 configs_count: 100 } + field { name: "optional_child" getters_count: 100 configs_count: 102 } + field { name: "repeated_string" getters_count: 100 configs_count: 1 } + field { name: "repeated_child" getters_count: 100 configs_count: 1 } + field { name: "nested" getters_count: 0 configs_count: 1 } + } + )pb"); + AnalyzeProfileProtoOptions options; + options.print_unused_threshold = false; + options.pool = DescriptorPool::generated_pool(); + EXPECT_STREQ(AnalyzeToText(info, options).c_str(), + "Message google.protobuf.compiler.tools.AnalyzeThis\n" + " string optional_string: INLINE\n"); +} + +TEST(AnalyzeProfileProtoTest, ChildLikelyPresentAndRarelyUsed) { + // Note that the logic pics a 50th percentile threshold which we need to + // exceed, making testing slightly awkward + AccessInfo info = ParseTextOrDie(R"pb( + language: "cpp" + message { + name: "google::protobuf::compiler::tools::AnalyzeThis" + count: 100 + field { name: "id" getters_count: 0 configs_count: 100 } + field { name: "optional_string" getters_count: 100 configs_count: 100 } + field { name: "optional_child" getters_count: 100 configs_count: 1 } + field { name: "repeated_string" getters_count: 100 configs_count: 1 } + field { name: "repeated_child" getters_count: 100 configs_count: 1 } + field { name: "nested" getters_count: 0 configs_count: 1 } + } + )pb"); + AnalyzeProfileProtoOptions options; + options.print_unused_threshold = false; + options.pool = DescriptorPool::generated_pool(); + EXPECT_STREQ(AnalyzeToText(info, options).c_str(), + "Message google.protobuf.compiler.tools.AnalyzeThis\n" + " string optional_string: INLINE\n" + " AnalyzeChild optional_child: LAZY\n"); +} + +TEST(AnalyzeProfileProtoTest, NestedCppNameMatchedToPoolName) { + AccessInfo info = ParseTextOrDie(R"pb( + language: "cpp" + message { + name: "google::protobuf::compiler::tools::AnalyzeThis_Nested" + count: 100 + field { name: "id" getters_count: 100 } + field { name: "optional_string" getters_count: 100 } + } + )pb"); + AnalyzeProfileProtoOptions options; + options.print_unused_threshold = false; + options.pool = DescriptorPool::generated_pool(); + EXPECT_STREQ(AnalyzeToText(info, options).c_str(), + "Message google.protobuf.compiler.tools.AnalyzeThis.Nested\n" + " string optional_string: INLINE\n"); +} + +} // namespace +} // namespace tools +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.proto b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.proto new file mode 100644 index 0000000000..d689886b31 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.proto @@ -0,0 +1,21 @@ +syntax = "proto2"; + +package google.protobuf.compiler.tools; + +message AnalyzeChild { + optional int32 child_id = 1; +} + +message AnalyzeThis { + message Nested { + optional int32 nexted_id = 1; + optional string optional_string = 2; + } + + optional int32 id = 1; + optional string optional_string = 2; + repeated string repeated_string = 3; + optional AnalyzeChild optional_child = 4; + repeated AnalyzeChild repeated_child = 5; + optional Nested nested = 6; +} From 536066eb52da32f262b2d4e5933f89b937fb176e Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 18 Oct 2023 19:18:04 +0000 Subject: [PATCH 30/95] Auto-generate files after cl/574546719 --- src/file_lists.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/src/file_lists.cmake b/src/file_lists.cmake index 70df9b057e..e4718cf8a3 100644 --- a/src/file_lists.cmake +++ b/src/file_lists.cmake @@ -289,7 +289,6 @@ set(libprotoc_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/empty_package.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/open_enum.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/unused_imports.cc - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/weak_imports.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/enum.cc From 898d8fa1fd6ff07149b283b3bbff00a6a3d8c52b Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 18 Oct 2023 12:21:32 -0700 Subject: [PATCH 31/95] Open-source editions Bazel rules for embedding defaults. These utilities provide a way to embed a FeatureSetDefaults message into generators or runtimes that need to implement feature resolution. They use protoc to handle the tricky reflection-based algorithm over feature protos, leaving only simple merges to be implemented in other languages. See docs/design/editions/editions-life-of-a-featureset.md for more information. PiperOrigin-RevId: 574554333 --- BUILD.bazel | 1 - cmake/tests.cmake | 1 + src/google/protobuf/BUILD.bazel | 46 ++++-- src/google/protobuf/compiler/BUILD.bazel | 28 +++- .../protobuf/compiler/allowlists/BUILD.bazel | 4 +- src/google/protobuf/compiler/cpp/BUILD.bazel | 6 +- .../protobuf/compiler/csharp/BUILD.bazel | 4 +- src/google/protobuf/compiler/java/BUILD.bazel | 8 +- .../protobuf/compiler/main_no_generators.cc | 36 +++++ .../protobuf/compiler/objectivec/BUILD.bazel | 8 +- src/google/protobuf/compiler/php/BUILD.bazel | 4 +- .../protobuf/compiler/python/BUILD.bazel | 2 +- src/google/protobuf/compiler/ruby/BUILD.bazel | 2 +- src/google/protobuf/compiler/rust/BUILD.bazel | 14 +- src/google/protobuf/editions/BUILD | 84 ++++++++++ src/google/protobuf/editions/defaults.bzl | 112 ++++++++++++++ src/google/protobuf/editions/defaults_test.cc | 145 ++++++++++++++++++ .../editions/internal_defaults_escape.cc | 35 +++++ src/google/protobuf/io/BUILD.bazel | 12 +- src/google/protobuf/stubs/BUILD.bazel | 4 +- src/google/protobuf/testing/BUILD.bazel | 2 +- 21 files changed, 503 insertions(+), 55 deletions(-) create mode 100644 src/google/protobuf/compiler/main_no_generators.cc create mode 100644 src/google/protobuf/editions/defaults.bzl create mode 100644 src/google/protobuf/editions/defaults_test.cc create mode 100644 src/google/protobuf/editions/internal_defaults_escape.cc diff --git a/BUILD.bazel b/BUILD.bazel index 23efee4a31..5951297816 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -224,7 +224,6 @@ alias( cc_library( name = "protobuf", copts = COPTS, - include_prefix = "google/protobuf/io", linkopts = LINK_OPTS, visibility = ["//visibility:public"], deps = [ diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 489ca65c2a..044af4835f 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -62,6 +62,7 @@ set(tests_files ${protobuf_test_files} ${compiler_test_files} ${annotation_test_util_srcs} + ${editions_test_files} ${io_test_files} ${util_test_files} ${stubs_test_files} diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index 8961ca6af1..f85e88b16c 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -162,6 +162,7 @@ cc_library( copts = COPTS, includes = ["wkt"], linkopts = LINK_OPTS, + strip_include_prefix = "/src", visibility = ["//pkg:__pkg__"], deps = [":protobuf_nowkt"], ) @@ -198,7 +199,7 @@ cc_library( "port_def.inc", "port_undef.inc", ], - include_prefix = "google/protobuf", + strip_include_prefix = "/src", visibility = [ "//:__subpackages__", "//src/google/protobuf:__subpackages__", @@ -212,7 +213,7 @@ cc_library( name = "varint_shuffle", hdrs = ["varint_shuffle.h"], copts = COPTS, - include_prefix = "google/protobuf", + strip_include_prefix = "/src", visibility = [ "//:__subpackages__", "//src/google/protobuf:__subpackages__", @@ -248,7 +249,7 @@ cc_library( name = "arena_align", srcs = ["arena_align.cc"], hdrs = ["arena_align.h"], - include_prefix = "google/protobuf", + strip_include_prefix = "/src", visibility = [ "//:__subpackages__", "//src/google/protobuf:__subpackages__", @@ -264,7 +265,7 @@ cc_library( cc_library( name = "arena_cleanup", hdrs = ["arena_cleanup.h"], - include_prefix = "google/protobuf", + strip_include_prefix = "/src", visibility = [ "//:__subpackages__", "//src/google/protobuf:__subpackages__", @@ -278,7 +279,7 @@ cc_library( cc_library( name = "arena_allocation_policy", hdrs = ["arena_allocation_policy.h"], - include_prefix = "google/protobuf", + strip_include_prefix = "/src", visibility = [ "//:__subpackages__", "//src/google/protobuf:__subpackages__", @@ -291,7 +292,7 @@ cc_library( cc_library( name = "string_block", hdrs = ["string_block.h"], - include_prefix = "google/protobuf", + strip_include_prefix = "/src", deps = [ ":arena_align", "@com_google_absl//absl/base:core_headers", @@ -320,7 +321,7 @@ cc_library( "serial_arena.h", "thread_safe_arena.h", ], - include_prefix = "google/protobuf", + strip_include_prefix = "/src", visibility = [ "//:__subpackages__", "//src/google/protobuf:__subpackages__", @@ -343,7 +344,7 @@ cc_library( name = "internal_visibility", hdrs = ["internal_visibility.h"], copts = COPTS, - include_prefix = "google/protobuf", + strip_include_prefix = "/src", visibility = [ "//:__subpackages__", "//src/google/protobuf:__subpackages__", @@ -355,7 +356,7 @@ cc_library( testonly = 1, hdrs = ["internal_visibility_for_testing.h"], copts = COPTS, - include_prefix = "google/protobuf", + strip_include_prefix = "/src", visibility = [ "//:__subpackages__", "//src/google/protobuf:__subpackages__", @@ -419,8 +420,8 @@ cc_library( "-Wno-error", ], }), - include_prefix = "google/protobuf", linkopts = LINK_OPTS, + strip_include_prefix = "/src", visibility = [ "//:__pkg__", "//pkg:__pkg__", @@ -506,8 +507,8 @@ cc_library( "wire_format.h", ], copts = COPTS, - include_prefix = "google/protobuf", linkopts = LINK_OPTS, + strip_include_prefix = "/src", visibility = [ "//:__pkg__", "//pkg:__pkg__", @@ -549,8 +550,8 @@ cc_test( cc_library( name = "protobuf", copts = COPTS, - include_prefix = "google/protobuf", linkopts = LINK_OPTS, + strip_include_prefix = "/src", visibility = [ "//:__pkg__", "//pkg:__pkg__", @@ -573,14 +574,15 @@ cc_library( "**/*.h", "**/*.inc", ]), + strip_include_prefix = "/src", ) cc_library( name = "descriptor_legacy", hdrs = ["descriptor_legacy.h"], copts = COPTS, - include_prefix = "google/protobuf", linkopts = LINK_OPTS, + strip_include_prefix = "/src", visibility = ["//:__subpackages__"], deps = [ ":port_def", @@ -593,8 +595,8 @@ cc_library( name = "descriptor_visitor", hdrs = ["descriptor_visitor.h"], copts = COPTS, - include_prefix = "google/protobuf", linkopts = LINK_OPTS, + strip_include_prefix = "/src", visibility = ["//:__subpackages__"], deps = [ ":port_def", @@ -749,6 +751,22 @@ proto_library( ], ) +proto_library( + name = "unittest_features_proto", + srcs = ["unittest_features.proto"], + strip_import_prefix = "/src", + visibility = ["//src/google/protobuf:__subpackages__"], + deps = [ + ":descriptor_proto", + ], +) + +cc_proto_library( + name = "unittest_features_cc_proto", + visibility = ["//src/google/protobuf:__subpackages__"], + deps = [":unittest_features_proto"], +) + proto_library( name = "generic_test_protos", srcs = [":test_proto_srcs"], diff --git a/src/google/protobuf/compiler/BUILD.bazel b/src/google/protobuf/compiler/BUILD.bazel index 273dae00b4..f98c31785b 100644 --- a/src/google/protobuf/compiler/BUILD.bazel +++ b/src/google/protobuf/compiler/BUILD.bazel @@ -42,7 +42,7 @@ cc_library( "parser.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler", + strip_include_prefix = "/src", visibility = ["//visibility:public"], deps = [ "//src/google/protobuf:protobuf_nowkt", @@ -66,7 +66,7 @@ cc_library( "scc.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler", + strip_include_prefix = "/src", visibility = ["//visibility:public"], deps = [ "//src/google/protobuf:protobuf_nowkt", @@ -87,7 +87,7 @@ cc_library( "versions_suffix.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler", + strip_include_prefix = "/src", visibility = [ "//src/google/protobuf/compiler:__subpackages__", ], @@ -107,7 +107,7 @@ cc_library( "zip_writer.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler", + strip_include_prefix = "/src", visibility = ["//visibility:public"], deps = [ ":code_generator", @@ -133,6 +133,7 @@ cc_library( "main.cc", ], copts = COPTS, + strip_include_prefix = "/src", visibility = [ "//:__pkg__", "//pkg:__pkg__", @@ -154,6 +155,23 @@ cc_library( ], ) +# This is a build of the protobuf compiler without code generators. +cc_binary( + name = "protoc_minimal", + srcs = [ + "main_no_generators.cc", + ], + copts = COPTS, + visibility = [ + "//src/google/protobuf:__subpackages__", + ], + deps = [ + ":command_line_interface", + "//src/google/protobuf:port_def", + "@com_google_absl//absl/log:initialize", + ], +) + # Note: this is an alias for now. In the future, this rule will become the # cc_binary for protoc, and //:protoc will become an alias. alias( @@ -397,7 +415,7 @@ cc_library( name = "retention", srcs = ["retention.cc"], hdrs = ["retention.h"], - include_prefix = "google/protobuf/compiler", + strip_include_prefix = "/src", visibility = ["//src/google/protobuf:__subpackages__"], deps = [ "//src/google/protobuf:protobuf_nowkt", diff --git a/src/google/protobuf/compiler/allowlists/BUILD.bazel b/src/google/protobuf/compiler/allowlists/BUILD.bazel index 470181fd6d..e6671c05c1 100644 --- a/src/google/protobuf/compiler/allowlists/BUILD.bazel +++ b/src/google/protobuf/compiler/allowlists/BUILD.bazel @@ -7,7 +7,7 @@ cc_library( name = "allowlist", hdrs = ["allowlist.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/allowlists", + strip_include_prefix = "/src", deps = [ "//src/google/protobuf/stubs", "@com_google_absl//absl/algorithm:container", @@ -28,7 +28,7 @@ cc_library( ], hdrs = ["allowlists.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/allowlists", + strip_include_prefix = "/src", visibility = ["//src/google/protobuf:__subpackages__"], deps = [ ":allowlist", diff --git a/src/google/protobuf/compiler/cpp/BUILD.bazel b/src/google/protobuf/compiler/cpp/BUILD.bazel index 8ca37b4b67..fb168b03db 100644 --- a/src/google/protobuf/compiler/cpp/BUILD.bazel +++ b/src/google/protobuf/compiler/cpp/BUILD.bazel @@ -11,7 +11,7 @@ cc_library( name = "names", hdrs = ["names.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/cpp", + strip_include_prefix = "/src", visibility = ["//visibility:public"], deps = [ ":names_internal", @@ -32,7 +32,7 @@ cc_library( "options.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler/cpp", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler/rust:__subpackages__", @@ -79,7 +79,7 @@ cc_library( "tracker.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler/cpp", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", diff --git a/src/google/protobuf/compiler/csharp/BUILD.bazel b/src/google/protobuf/compiler/csharp/BUILD.bazel index 414dd0ffd6..a182bc2a30 100644 --- a/src/google/protobuf/compiler/csharp/BUILD.bazel +++ b/src/google/protobuf/compiler/csharp/BUILD.bazel @@ -11,7 +11,7 @@ cc_library( srcs = ["names.cc"], hdrs = ["names.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/csharp", + strip_include_prefix = "/src", visibility = ["//visibility:public"], deps = [ "//src/google/protobuf:protobuf_nowkt", @@ -62,7 +62,7 @@ cc_library( "//build_defs:config_msvc": [], "//conditions:default": ["-Wno-overloaded-virtual"], }), - include_prefix = "google/protobuf/compiler/csharp", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", diff --git a/src/google/protobuf/compiler/java/BUILD.bazel b/src/google/protobuf/compiler/java/BUILD.bazel index a9461d0901..8ca67c1bbb 100644 --- a/src/google/protobuf/compiler/java/BUILD.bazel +++ b/src/google/protobuf/compiler/java/BUILD.bazel @@ -10,7 +10,7 @@ cc_library( name = "names", hdrs = ["names.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/java", + strip_include_prefix = "/src", visibility = ["//visibility:public"], deps = [ ":names_internal", @@ -33,7 +33,7 @@ cc_library( "options.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler/java", + strip_include_prefix = "/src", visibility = ["//pkg:__pkg__"], deps = [ ":java_features_bootstrap", @@ -48,7 +48,7 @@ cc_library( name = "java_features_bootstrap", srcs = ["java_features.pb.cc"], hdrs = ["java_features.pb.h"], - include_prefix = "google/protobuf/compiler/java", + strip_include_prefix = "/src", deps = [ "//src/google/protobuf:arena", "//src/google/protobuf:protobuf_nowkt", @@ -119,7 +119,7 @@ cc_library( "string_field_lite.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler/java", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", diff --git a/src/google/protobuf/compiler/main_no_generators.cc b/src/google/protobuf/compiler/main_no_generators.cc new file mode 100644 index 0000000000..83a44e8b4c --- /dev/null +++ b/src/google/protobuf/compiler/main_no_generators.cc @@ -0,0 +1,36 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "google/protobuf/compiler/command_line_interface.h" + +#include "absl/log/initialize.h" + +// Must be included last. +#include "google/protobuf/port_def.inc" + +namespace google { +namespace protobuf { +namespace compiler { + +// This is a version of protoc that has no built-in code generators. +// See go/protobuf-toolchain-protoc +int ProtocMain(int argc, char* argv[]) { + absl::InitializeLog(); + + CommandLineInterface cli; + cli.AllowPlugins("protoc-"); + + return cli.Run(argc, argv); +} + +} // namespace compiler +} // namespace protobuf +} // namespace google + +int main(int argc, char* argv[]) { + return google::protobuf::compiler::ProtocMain(argc, argv); +} diff --git a/src/google/protobuf/compiler/objectivec/BUILD.bazel b/src/google/protobuf/compiler/objectivec/BUILD.bazel index 5ab3381afa..a3a6fcfec0 100644 --- a/src/google/protobuf/compiler/objectivec/BUILD.bazel +++ b/src/google/protobuf/compiler/objectivec/BUILD.bazel @@ -10,7 +10,7 @@ cc_library( name = "names", hdrs = ["names.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/objectivec", + strip_include_prefix = "/src", visibility = ["//visibility:public"], deps = [ ":names_internal", @@ -27,7 +27,7 @@ cc_library( "nsobject_methods.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler/objectivec", + strip_include_prefix = "/src", visibility = ["//pkg:__pkg__"], deps = [ ":line_consumer", @@ -43,7 +43,7 @@ cc_library( srcs = ["line_consumer.cc"], hdrs = ["line_consumer.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/objectivec", + strip_include_prefix = "/src", visibility = ["//pkg:__pkg__"], deps = [ "//src/google/protobuf:protobuf_nowkt", @@ -87,7 +87,7 @@ cc_library( "text_format_decode_data.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler/objectivec", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", diff --git a/src/google/protobuf/compiler/php/BUILD.bazel b/src/google/protobuf/compiler/php/BUILD.bazel index f814a03a74..2a9746d808 100644 --- a/src/google/protobuf/compiler/php/BUILD.bazel +++ b/src/google/protobuf/compiler/php/BUILD.bazel @@ -11,7 +11,7 @@ cc_library( srcs = ["names.cc"], hdrs = ["names.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/php", + strip_include_prefix = "/src", visibility = ["//visibility:public"], deps = [ "//src/google/protobuf:protobuf_nowkt", @@ -25,7 +25,7 @@ cc_library( srcs = ["php_generator.cc"], hdrs = ["php_generator.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/php", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", diff --git a/src/google/protobuf/compiler/python/BUILD.bazel b/src/google/protobuf/compiler/python/BUILD.bazel index 64b5808cb6..e9501f2b56 100644 --- a/src/google/protobuf/compiler/python/BUILD.bazel +++ b/src/google/protobuf/compiler/python/BUILD.bazel @@ -19,7 +19,7 @@ cc_library( "pyi_generator.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler/python", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", diff --git a/src/google/protobuf/compiler/ruby/BUILD.bazel b/src/google/protobuf/compiler/ruby/BUILD.bazel index d01764c2ff..62afc3c35a 100644 --- a/src/google/protobuf/compiler/ruby/BUILD.bazel +++ b/src/google/protobuf/compiler/ruby/BUILD.bazel @@ -11,7 +11,7 @@ cc_library( srcs = ["ruby_generator.cc"], hdrs = ["ruby_generator.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/ruby", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", diff --git a/src/google/protobuf/compiler/rust/BUILD.bazel b/src/google/protobuf/compiler/rust/BUILD.bazel index 1429b9bff1..9939c2ca21 100644 --- a/src/google/protobuf/compiler/rust/BUILD.bazel +++ b/src/google/protobuf/compiler/rust/BUILD.bazel @@ -10,7 +10,7 @@ cc_library( srcs = ["generator.cc"], hdrs = ["generator.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/rust", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", @@ -34,7 +34,7 @@ cc_library( srcs = ["message.cc"], hdrs = ["message.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/rust", + strip_include_prefix = "/src", deps = [ ":accessors", ":context", @@ -62,7 +62,7 @@ cc_library( "accessors/accessors.h", ], copts = COPTS, - include_prefix = "google/protobuf/compiler/rust", + strip_include_prefix = "/src", deps = [ ":context", ":naming", @@ -78,7 +78,7 @@ cc_library( srcs = ["context.cc"], hdrs = ["context.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/rust", + strip_include_prefix = "/src", deps = [ "//src/google/protobuf/compiler:code_generator", "//src/google/protobuf/io:printer", @@ -96,7 +96,7 @@ cc_library( srcs = ["naming.cc"], hdrs = ["naming.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/rust", + strip_include_prefix = "/src", deps = [ ":context", "//src/google/protobuf:protobuf_nowkt", @@ -110,7 +110,7 @@ cc_library( srcs = ["oneof.cc"], hdrs = ["oneof.h"], copts = COPTS, - include_prefix = "google/protobuf/compiler/rust", + strip_include_prefix = "/src", deps = [ ":context", ":naming", @@ -124,7 +124,7 @@ cc_library( name = "relative_path", srcs = ["relative_path.cc"], hdrs = ["relative_path.h"], - include_prefix = "google/protobuf/compiler/rust", + strip_include_prefix = "/src", deps = [ "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/log:absl_check", diff --git a/src/google/protobuf/editions/BUILD b/src/google/protobuf/editions/BUILD index 04e1967ac1..0fa11a8453 100644 --- a/src/google/protobuf/editions/BUILD +++ b/src/google/protobuf/editions/BUILD @@ -1,4 +1,88 @@ load("@rules_cc//cc:defs.bzl", "cc_proto_library") +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load(":defaults.bzl", "compile_edition_defaults", "embed_edition_defaults") + +bzl_library( + name = "defaults", + srcs = ["defaults.bzl"], + visibility = ["//visibility:public"], +) + +compile_edition_defaults( + name = "test_defaults_2023", + testonly = True, + srcs = ["//src/google/protobuf:unittest_features_proto"], + maximum_edition = "2023", + minimum_edition = "2023", +) + +compile_edition_defaults( + name = "test_defaults_future", + testonly = True, + srcs = ["//src/google/protobuf:unittest_features_proto"], + maximum_edition = "99997_TEST_ONLY", + minimum_edition = "2023", +) + +compile_edition_defaults( + name = "test_defaults_far_future", + testonly = True, + srcs = ["//src/google/protobuf:unittest_features_proto"], + maximum_edition = "99999_TEST_ONLY", + minimum_edition = "99997_TEST_ONLY", +) + +embed_edition_defaults( + name = "embed_test_defaults", + testonly = True, + defaults = ":test_defaults_2023", + output = "defaults_test_embedded.h", + placeholder = "DEFAULTS_VALUE", + template = "defaults_test_embedded.h.template", +) + +cc_binary( + name = "internal_defaults_escape", + srcs = ["internal_defaults_escape.cc"], + # This needs to be public for users of embed_edition_defaults. + visibility = ["//visibility:public"], + deps = [ + "//src/google/protobuf", + "@com_google_absl//absl/strings", + ], +) + +cc_library( + name = "defaults_test_embedded", + hdrs = [ + "defaults_test_embedded.h", + ], + strip_include_prefix = "/src", +) + +cc_test( + name = "defaults_test", + srcs = ["defaults_test.cc"], + data = [ + ":test_defaults_2023", + ":test_defaults_far_future", + ":test_defaults_future", + ], + deps = [ + ":defaults_test_embedded", + "//src/google/protobuf", + "//src/google/protobuf:unittest_features_cc_proto", + "//src/google/protobuf/stubs", + "//src/google/protobuf/testing", + "@bazel_tools//tools/cpp/runfiles", + "@com_google_absl//absl/memory", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:string_view", + "@com_google_googletest//:gtest_main", + ], +) proto_library( name = "test_messages_proto2_proto", diff --git a/src/google/protobuf/editions/defaults.bzl b/src/google/protobuf/editions/defaults.bzl new file mode 100644 index 0000000000..865efaf705 --- /dev/null +++ b/src/google/protobuf/editions/defaults.bzl @@ -0,0 +1,112 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2023 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +""" +Provide a rule for generating the intermediate feature set defaults used for feature resolution. + +See go/life-of-a-featureset for more information. +""" + +def _compile_edition_defaults_impl(ctx): + out_file = ctx.actions.declare_file(ctx.outputs.output.basename) + sources = [] + paths = [] + for src in ctx.attr.srcs: + sources.extend(src[ProtoInfo].transitive_sources.to_list()) + paths.extend(src[ProtoInfo].transitive_proto_path.to_list()) + + args = ctx.actions.args() + args.add("--experimental_edition_defaults_out", out_file) + + args.add("--experimental_edition_defaults_minimum", ctx.attr.minimum_edition) + args.add("--experimental_edition_defaults_maximum", ctx.attr.maximum_edition) + for p in paths: + args.add("--proto_path", p) + for source in sources: + args.add(source) + ctx.actions.run( + outputs = [out_file], + inputs = sources, + executable = ctx.executable._protoc, + arguments = [args], + progress_message = "Generating edition defaults", + ) + +compile_edition_defaults = rule( + attrs = { + "srcs": attr.label_list( + mandatory = True, + allow_rules = ["proto_library"], + providers = [ProtoInfo], + ), + "minimum_edition": attr.string(mandatory = True), + "maximum_edition": attr.string(mandatory = True), + "_protoc": attr.label( + default = "//src/google/protobuf/compiler:protoc_minimal", + executable = True, + cfg = "exec", + ), + }, + implementation = _compile_edition_defaults_impl, + outputs = { + "output": "%{name}.binpb", + }, +) + +def _embed_edition_defaults_impl(ctx): + ctx.actions.run_shell( + outputs = [ctx.outputs.output], + inputs = [ctx.file.defaults, ctx.file.template], + tools = [ctx.executable._escape], + command = """ + DEFAULTS_RAW=$({escape} < {defaults}) + # Windows requires extra escaping. + DEFAULTS_ESCAPED=$(echo $DEFAULTS_RAW | sed 's/\\\\/\\\\\\\\/g' || + echo $DEFAULTS_RAW | sed 's/\\\\\\\\/\\\\\\\\\\\\\\\\/g') + cp -f {template} {output} + # MacOS requires a backup file. + sed -i.bak \"s|{placeholder}|$DEFAULTS_ESCAPED|g\" {output} + """.format( + escape = ctx.executable._escape.path, + defaults = ctx.file.defaults.path, + template = ctx.file.template.path, + output = ctx.outputs.output.path, + placeholder = ctx.attr.placeholder, + ), + ) + +embed_edition_defaults = rule( + doc = "genrule to embed edition defaults binary data into a template file using octal C-style escaping.", + attrs = { + "defaults": attr.label( + mandatory = True, + allow_single_file = True, + allow_rules = ["compile_edition_defaults"], + providers = [ProtoInfo], + doc = "The compile_edition_defaults rule to embed", + ), + "output": attr.output( + mandatory = True, + doc = "The name of the output file", + ), + "template": attr.label( + mandatory = True, + allow_single_file = True, + doc = "The template to use for generating the output file", + ), + "placeholder": attr.string( + mandatory = True, + doc = "The placeholder to replace with a serialized string in the template", + ), + "_escape": attr.label( + default = "//src/google/protobuf/editions:internal_defaults_escape", + executable = True, + cfg = "exec", + ), + }, + implementation = _embed_edition_defaults_impl, +) diff --git a/src/google/protobuf/editions/defaults_test.cc b/src/google/protobuf/editions/defaults_test.cc new file mode 100644 index 0000000000..24c66ec6e9 --- /dev/null +++ b/src/google/protobuf/editions/defaults_test.cc @@ -0,0 +1,145 @@ +#include + +#include "tools/cpp/runfiles/runfiles.h" +#include "google/protobuf/testing/file.h" +#include "google/protobuf/testing/file.h" +#include "google/protobuf/descriptor.pb.h" +#include +#include +#include "absl/memory/memory.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/editions/defaults_test_embedded.h" +#include "google/protobuf/unittest_features.pb.h" +#include "google/protobuf/stubs/status_macros.h" + +// Must be included last. +#include "google/protobuf/port_def.inc" + +#define ASSERT_OK(x) ASSERT_TRUE(x.ok()) << x.status().message(); + +namespace google { +namespace protobuf { +namespace { + +absl::StatusOr ReadDefaults(absl::string_view name) { + auto runfiles = absl::WrapUnique(bazel::tools::cpp::runfiles::Runfiles::CreateForTest()); + std::string file = runfiles->Rlocation(absl::StrCat( + "com_google_protobuf/src/google/protobuf/editions/", + name, ".binpb")); + std::string data; + RETURN_IF_ERROR(File::GetContents(file, &data, true)); + FeatureSetDefaults defaults; + if (!defaults.ParseFromString(data)) { + return absl::InternalError("Could not parse edition defaults!"); + } + return defaults; +} + +TEST(DefaultsTest, Check2023) { + auto defaults = ReadDefaults("test_defaults_2023"); + ASSERT_OK(defaults); + ASSERT_EQ(defaults->defaults().size(), 3); + ASSERT_EQ(defaults->minimum_edition(), EDITION_2023); + ASSERT_EQ(defaults->maximum_edition(), EDITION_2023); + + EXPECT_EQ(defaults->defaults()[0].edition(), EDITION_PROTO2); + EXPECT_EQ(defaults->defaults()[1].edition(), EDITION_PROTO3); + EXPECT_EQ(defaults->defaults()[2].edition(), EDITION_2023); + EXPECT_EQ(defaults->defaults()[2].features().field_presence(), + FeatureSet::EXPLICIT); + EXPECT_EQ(defaults->defaults()[2] + .features() + .GetExtension(pb::test) + .int_file_feature(), + 1); +} + +TEST(DefaultsTest, CheckFuture) { + auto defaults = ReadDefaults("test_defaults_future"); + ASSERT_OK(defaults); + ASSERT_EQ(defaults->defaults().size(), 4); + ASSERT_EQ(defaults->minimum_edition(), EDITION_2023); + ASSERT_EQ(defaults->maximum_edition(), EDITION_99997_TEST_ONLY); + + EXPECT_EQ(defaults->defaults()[0].edition(), EDITION_PROTO2); + EXPECT_EQ(defaults->defaults()[1].edition(), EDITION_PROTO3); + EXPECT_EQ(defaults->defaults()[2].edition(), EDITION_2023); + EXPECT_EQ(defaults->defaults()[2].features().field_presence(), + FeatureSet::EXPLICIT); + EXPECT_EQ(defaults->defaults()[2] + .features() + .GetExtension(pb::test) + .int_file_feature(), + 1); + EXPECT_EQ(defaults->defaults()[3].edition(), EDITION_99997_TEST_ONLY); + EXPECT_EQ(defaults->defaults()[3].features().field_presence(), + FeatureSet::EXPLICIT); + EXPECT_EQ(defaults->defaults()[3] + .features() + .GetExtension(pb::test) + .int_file_feature(), + 2); +} + +TEST(DefaultsTest, CheckFarFuture) { + auto defaults = ReadDefaults("test_defaults_far_future"); + ASSERT_OK(defaults); + ASSERT_EQ(defaults->defaults().size(), 5); + ASSERT_EQ(defaults->minimum_edition(), EDITION_99997_TEST_ONLY); + ASSERT_EQ(defaults->maximum_edition(), EDITION_99999_TEST_ONLY); + + EXPECT_EQ(defaults->defaults()[0].edition(), EDITION_PROTO2); + EXPECT_EQ(defaults->defaults()[1].edition(), EDITION_PROTO3); + EXPECT_EQ(defaults->defaults()[2].edition(), EDITION_2023); + EXPECT_EQ(defaults->defaults()[2].features().field_presence(), + FeatureSet::EXPLICIT); + EXPECT_EQ(defaults->defaults()[2] + .features() + .GetExtension(pb::test) + .int_file_feature(), + 1); + EXPECT_EQ(defaults->defaults()[3].edition(), EDITION_99997_TEST_ONLY); + EXPECT_EQ(defaults->defaults()[3].features().field_presence(), + FeatureSet::EXPLICIT); + EXPECT_EQ(defaults->defaults()[3] + .features() + .GetExtension(pb::test) + .int_file_feature(), + 2); + EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_99998_TEST_ONLY); + EXPECT_EQ(defaults->defaults()[4].features().field_presence(), + FeatureSet::EXPLICIT); + EXPECT_EQ(defaults->defaults()[4] + .features() + .GetExtension(pb::test) + .int_file_feature(), + 3); +} + +TEST(DefaultsTest, Embedded) { + FeatureSetDefaults defaults; + ASSERT_TRUE(defaults.ParseFromArray(DEFAULTS_TEST_EMBEDDED, + sizeof(DEFAULTS_TEST_EMBEDDED) - 1)) + << "Could not parse embedded data"; + ASSERT_EQ(defaults.defaults().size(), 3); + ASSERT_EQ(defaults.minimum_edition(), EDITION_2023); + ASSERT_EQ(defaults.maximum_edition(), EDITION_2023); + + EXPECT_EQ(defaults.defaults()[0].edition(), EDITION_PROTO2); + EXPECT_EQ(defaults.defaults()[1].edition(), EDITION_PROTO3); + EXPECT_EQ(defaults.defaults()[2].edition(), EDITION_2023); + EXPECT_EQ(defaults.defaults()[2].features().field_presence(), + FeatureSet::EXPLICIT); + EXPECT_EQ(defaults.defaults()[2] + .features() + .GetExtension(pb::test) + .int_file_feature(), + 1); +} + +} // namespace +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/editions/internal_defaults_escape.cc b/src/google/protobuf/editions/internal_defaults_escape.cc new file mode 100644 index 0000000000..4c1aa469ec --- /dev/null +++ b/src/google/protobuf/editions/internal_defaults_escape.cc @@ -0,0 +1,35 @@ +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "google/protobuf/descriptor.pb.h" +#include "absl/strings/escaping.h" + +#if defined(_WIN32) +#include "google/protobuf/io/io_win32.h" + +// DO NOT include , instead create functions in io_win32.{h,cc} and import +// them like we do below. +using google::protobuf::io::win32::setmode; +#endif + +int main(int argc, char *argv[]) { +#ifdef _WIN32 + setmode(STDIN_FILENO, _O_BINARY); + setmode(STDOUT_FILENO, _O_BINARY); +#endif + google::protobuf::FeatureSetDefaults defaults; + if (!defaults.ParseFromFileDescriptor(STDIN_FILENO)) { + std::cerr << argv[0] << ": unable to parse edition defaults." << std::endl; + return 1; + } + std::string output; + defaults.SerializeToString(&output); + std::cout << absl::CEscape(output); + return 0; +} diff --git a/src/google/protobuf/io/BUILD.bazel b/src/google/protobuf/io/BUILD.bazel index 0578742d62..a5c44e2aad 100644 --- a/src/google/protobuf/io/BUILD.bazel +++ b/src/google/protobuf/io/BUILD.bazel @@ -23,7 +23,7 @@ cc_library( "zero_copy_stream_impl_lite.h", ], copts = COPTS, - include_prefix = "google/protobuf/io", + strip_include_prefix = "/src", deps = [ ":io_win32", "//src/google/protobuf:arena", @@ -39,7 +39,7 @@ cc_library( testonly = 1, hdrs = ["test_zero_copy_stream.h"], copts = COPTS, - include_prefix = "google/protobuf/io", + strip_include_prefix = "/src", deps = [ ":io", "//src/google/protobuf/stubs", @@ -90,7 +90,7 @@ cc_library( srcs = ["printer.cc"], hdrs = ["printer.h"], copts = COPTS, - include_prefix = "google/protobuf/io", + strip_include_prefix = "/src", deps = [ ":zero_copy_sink", "//src/google/protobuf/stubs", @@ -119,7 +119,7 @@ cc_library( "tokenizer.h", ], copts = COPTS, - include_prefix = "google/protobuf/io", + strip_include_prefix = "/src", deps = [ ":io", "//src/google/protobuf/stubs", @@ -134,7 +134,7 @@ cc_library( srcs = ["gzip_stream.cc"], hdrs = ["gzip_stream.h"], copts = COPTS, - include_prefix = "google/protobuf/io", + strip_include_prefix = "/src", deps = [ ":io", "//src/google/protobuf/stubs", @@ -151,7 +151,7 @@ cc_library( srcs = ["io_win32.cc"], hdrs = ["io_win32.h"], copts = COPTS, - include_prefix = "google/protobuf/io", + strip_include_prefix = "/src", visibility = [ "//pkg:__pkg__", "//src/google/protobuf/compiler:__pkg__", diff --git a/src/google/protobuf/stubs/BUILD.bazel b/src/google/protobuf/stubs/BUILD.bazel index 740e43e815..f89f34a004 100644 --- a/src/google/protobuf/stubs/BUILD.bazel +++ b/src/google/protobuf/stubs/BUILD.bazel @@ -22,8 +22,8 @@ cc_library( "status_macros.h", ], copts = COPTS, - include_prefix = "google/protobuf/stubs", linkopts = LINK_OPTS, + strip_include_prefix = "/src", deps = [ "//src/google/protobuf:port_def", "@com_google_absl//absl/log:absl_log", @@ -40,7 +40,7 @@ cc_library( hdrs = [ ], copts = COPTS, - include_prefix = "google/protobuf/stubs", + strip_include_prefix = "/src", textual_hdrs = [ "callback.h", "common.h", diff --git a/src/google/protobuf/testing/BUILD.bazel b/src/google/protobuf/testing/BUILD.bazel index 572c1f9f46..ab3e979d91 100644 --- a/src/google/protobuf/testing/BUILD.bazel +++ b/src/google/protobuf/testing/BUILD.bazel @@ -19,8 +19,8 @@ cc_library( "googletest.h", ], copts = COPTS, - include_prefix = "google/protobuf/testing", linkopts = LINK_OPTS, + strip_include_prefix = "/src", deps = [ "//:protobuf_lite", # for ShutdownProtobufLibrary "//src/google/protobuf/io", From a2ba8bc78e49b8b9053654030f5254fc38a7da93 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 18 Oct 2023 13:12:07 -0700 Subject: [PATCH 32/95] Enable conformance tests over editions protos We transformed the proto2/proto3 protos to editions, and then run the same set of tests over both. This will verify that migrating to editions preserves the same proto2/proto3 behavior. These will not be enabled by default, and require a flag `--maximum_edition=2023`. Future changes will: - add more targeted editions-specific tests - clean up our conformance test framework to allow for more targeted tests - add wildcards to failure lists in limited cases to reduce noise - add feature resolution conformance tests PiperOrigin-RevId: 574570607 --- cmake/conformance.cmake | 27 +++- conformance/BUILD.bazel | 10 ++ conformance/bazel_conformance_test_runner.sh | 12 +- conformance/binary_json_conformance_suite.cc | 121 +++++++++++------- conformance/binary_json_conformance_suite.h | 11 +- conformance/conformance_cpp.cc | 8 ++ conformance/conformance_test.cc | 10 ++ conformance/conformance_test.h | 5 + conformance/conformance_test_runner.cc | 16 +++ conformance/defs.bzl | 3 + conformance/failure_list_cpp.txt | 33 ++++- conformance/failure_list_csharp.txt | 4 +- conformance/failure_list_java.txt | 6 +- conformance/failure_list_jruby.txt | 6 +- conformance/text_format_conformance_suite.cc | 10 ++ conformance/text_format_failure_list_cpp.txt | 20 +++ src/BUILD.bazel | 1 + src/google/protobuf/editions/BUILD | 24 ++-- .../protobuf/editions/generated_files_test.cc | 10 +- .../editions/generated_reflection_test.cc | 4 +- ...to => test_messages_proto2_editions.proto} | 4 +- ...to => test_messages_proto3_editions.proto} | 4 +- 22 files changed, 257 insertions(+), 92 deletions(-) rename src/google/protobuf/editions/golden/{test_messages_proto2.proto => test_messages_proto2_editions.proto} (99%) rename src/google/protobuf/editions/golden/{test_messages_proto3.proto => test_messages_proto3_editions.proto} (98%) diff --git a/cmake/conformance.cmake b/cmake/conformance.cmake index 7bebadee1c..bfded7763a 100644 --- a/cmake/conformance.cmake +++ b/cmake/conformance.cmake @@ -33,12 +33,22 @@ add_custom_command( ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc - DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto - ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto - COMMAND ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto - --proto_path=${protobuf_SOURCE_DIR}/src - --cpp_out=${protoc_cpp_args}${protobuf_SOURCE_DIR}/src + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto3_editions.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto3_editions.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto2_editions.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto2_editions.pb.cc + DEPENDS ${protobuf_PROTOC_EXE} + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto3_editions.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto + COMMAND ${protobuf_PROTOC_EXE} + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto3_editions.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto + --proto_path=${protobuf_SOURCE_DIR}/src + --cpp_out=${protoc_cpp_args}${protobuf_SOURCE_DIR}/src ) add_library(libconformance_common ${protobuf_SHARED_OR_STATIC} @@ -48,6 +58,10 @@ add_library(libconformance_common ${protobuf_SHARED_OR_STATIC} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto3_editions.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto3_editions.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto2_editions.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/editions/golden/test_messages_proto2_editions.pb.cc ) target_link_libraries(libconformance_common ${protobuf_LIB_PROTOBUF} @@ -100,6 +114,7 @@ add_test(NAME conformance_cpp_test --failure_list ${protobuf_SOURCE_DIR}/conformance/failure_list_cpp.txt --text_format_failure_list ${protobuf_SOURCE_DIR}/conformance/text_format_failure_list_cpp.txt --output_dir ${protobuf_TEST_XML_OUTDIR} + --maximum_edition 2023 ${CMAKE_CURRENT_BINARY_DIR}/conformance_cpp DEPENDS conformance_test_runner conformance_cpp) diff --git a/conformance/BUILD.bazel b/conformance/BUILD.bazel index eafd606b09..e54eab02d2 100644 --- a/conformance/BUILD.bazel +++ b/conformance/BUILD.bazel @@ -130,6 +130,7 @@ internal_ruby_proto_library( cc_library( name = "conformance_test", + testonly = 1, srcs = [ "conformance_test.cc", "conformance_test_runner.cc", @@ -151,12 +152,15 @@ cc_library( cc_library( name = "binary_json_conformance_suite", + testonly = 1, srcs = ["binary_json_conformance_suite.cc"], hdrs = ["binary_json_conformance_suite.h"], deps = [ ":conformance_test", ":test_messages_proto2_proto_cc", ":test_messages_proto3_proto_cc", + "//src/google/protobuf/editions:test_messages_proto2_editions_cc_proto", + "//src/google/protobuf/editions:test_messages_proto3_editions_cc_proto", "@com_google_absl//absl/log:die_if_null", "@com_google_absl//absl/status", "@jsoncpp", @@ -165,12 +169,15 @@ cc_library( cc_library( name = "text_format_conformance_suite", + testonly = 1, srcs = ["text_format_conformance_suite.cc"], hdrs = ["text_format_conformance_suite.h"], deps = [ ":conformance_test", ":test_messages_proto2_proto_cc", ":test_messages_proto3_proto_cc", + "//src/google/protobuf/editions:test_messages_proto2_editions_cc_proto", + "//src/google/protobuf/editions:test_messages_proto3_editions_cc_proto", "@com_google_absl//absl/log:absl_log", "@com_google_absl//absl/log:die_if_null", "@com_google_absl//absl/strings", @@ -179,6 +186,7 @@ cc_library( cc_binary( name = "conformance_test_runner", + testonly = 1, srcs = ["conformance_test_main.cc"], visibility = ["//visibility:public"], deps = [ @@ -199,6 +207,8 @@ cc_binary( "//:protobuf", "//:test_messages_proto2_cc_proto", "//:test_messages_proto3_cc_proto", + "//src/google/protobuf/editions:test_messages_proto2_editions_cc_proto", + "//src/google/protobuf/editions:test_messages_proto3_editions_cc_proto", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", ], diff --git a/conformance/bazel_conformance_test_runner.sh b/conformance/bazel_conformance_test_runner.sh index fcf4a485b7..c434c1fcdc 100755 --- a/conformance/bazel_conformance_test_runner.sh +++ b/conformance/bazel_conformance_test_runner.sh @@ -28,9 +28,10 @@ else fi # --- end runfiles.bash initialization --- -TESTEE=unset -FAILURE_LIST=unset -TEXT_FORMAT_FAILURE_LIST=unset +TESTEE= +FAILURE_LIST= +TEXT_FORMAT_FAILURE_LIST= +MAXIMUM_EDITION= while [[ -n "$@" ]]; do arg="$1"; shift @@ -39,6 +40,7 @@ while [[ -n "$@" ]]; do "--testee") TESTEE="$val" ;; "--failure_list") FAILURE_LIST="$val" ;; "--text_format_failure_list") TEXT_FORMAT_FAILURE_LIST="$val" ;; + "--maximum_edition") MAXIMUM_EDITION="$val" ;; *) echo "Flag $arg is not recognized." && exit 1 ;; esac done @@ -57,4 +59,8 @@ if [ -n "$text_format_failure_list" ]; then args+=(--text_format_failure_list $text_format_failure_list) fi +if [ -n "$MAXIMUM_EDITION" ]; then + args+=(--maximum_edition $MAXIMUM_EDITION) +fi + $conformance_test_runner "${args[@]}" $conformance_testee diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index dbacc05450..628afdcb8a 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -24,9 +24,12 @@ #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" +#include "absl/strings/substitute.h" #include "json/json.h" #include "conformance/conformance.pb.h" #include "conformance_test.h" +#include "google/protobuf/editions/golden/test_messages_proto2_editions.pb.h" +#include "google/protobuf/editions/golden/test_messages_proto3_editions.pb.h" #include "google/protobuf/endian.h" #include "google/protobuf/json/json.h" #include "google/protobuf/test_messages_proto2.pb.h" @@ -47,6 +50,10 @@ using google::protobuf::internal::little_endian::FromHost; using google::protobuf::util::NewTypeResolverForDescriptorPool; using protobuf_test_messages::proto2::TestAllTypesProto2; using protobuf_test_messages::proto3::TestAllTypesProto3; +using TestAllTypesProto2Editions = + protobuf_test_messages::editions::proto2::TestAllTypesProto2; +using TestAllTypesProto3Editions = + protobuf_test_messages::editions::proto3::TestAllTypesProto3; namespace { @@ -325,12 +332,17 @@ bool BinaryAndJsonConformanceSuite::ParseResponse( void BinaryAndJsonConformanceSuite::RunSuiteImpl() { type_resolver_.reset(NewTypeResolverForDescriptorPool( kTypeUrlPrefix, DescriptorPool::generated_pool())); - type_url_ = GetTypeUrl(TestAllTypesProto3::descriptor()); BinaryAndJsonConformanceSuiteImpl( this, /*run_proto3_tests=*/true); BinaryAndJsonConformanceSuiteImpl( this, /*run_proto3_tests=*/false); + if (maximum_edition_ >= Edition::EDITION_2023) { + BinaryAndJsonConformanceSuiteImpl( + this, /*run_proto3_tests=*/true); + BinaryAndJsonConformanceSuiteImpl( + this, /*run_proto3_tests=*/false); + } } template @@ -413,8 +425,7 @@ template void BinaryAndJsonConformanceSuiteImpl:: RunValidJsonTestWithProtobufInput( const std::string& test_name, ConformanceLevel level, - const TestAllTypesProto3& input, - const std::string& equivalent_text_format) { + const MessageType& input, const std::string& equivalent_text_format) { ConformanceRequestSetting setting( level, conformance::PROTOBUF, conformance::JSON, conformance::JSON_TEST, input, test_name, input.SerializeAsString()); @@ -427,7 +438,7 @@ void BinaryAndJsonConformanceSuiteImpl:: ConformanceLevel level, const std::string& input_json, const std::string& equivalent_text_format) { - TestAllTypesProto3 prototype; + MessageType prototype; ConformanceRequestSetting setting( level, conformance::JSON, conformance::PROTOBUF, conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST, prototype, test_name, @@ -560,7 +571,7 @@ template void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForJson( const std::string& test_name, ConformanceLevel level, const std::string& input_json) { - TestAllTypesProto3 prototype; + MessageType prototype; // We don't expect output, but if the program erroneously accepts the protobuf // we let it send its response as this. We must not leave it unspecified. ConformanceRequestSetting setting(level, conformance::JSON, conformance::JSON, @@ -568,8 +579,9 @@ void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForJson( test_name, input_json); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - std::string effective_test_name = absl::StrCat( - setting.ConformanceLevelToString(level), ".Proto3.JsonInput.", test_name); + std::string effective_test_name = + absl::StrCat(setting.ConformanceLevelToString(level), ".", + SyntaxIdentifier(), ".JsonInput.", test_name); suite_.RunTest(effective_test_name, request, &response); if (response.result_case() == ConformanceResponse::kParseError) { @@ -587,18 +599,19 @@ void BinaryAndJsonConformanceSuiteImpl:: ExpectSerializeFailureForJson(const std::string& test_name, ConformanceLevel level, const std::string& text_format) { - TestAllTypesProto3 payload_message; + MessageType payload_message; ABSL_CHECK(TextFormat::ParseFromString(text_format, &payload_message)) << "Failed to parse: " << text_format; - TestAllTypesProto3 prototype; + MessageType prototype; ConformanceRequestSetting setting( level, conformance::PROTOBUF, conformance::JSON, conformance::JSON_TEST, prototype, test_name, payload_message.SerializeAsString()); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - std::string effective_test_name = absl::StrCat( - setting.ConformanceLevelToString(level), ".", test_name, ".JsonOutput"); + std::string effective_test_name = + absl::StrCat(setting.ConformanceLevelToString(level), ".", + SyntaxIdentifier(), ".", test_name, ".JsonOutput"); suite_.RunTest(effective_test_name, request, &response); if (response.result_case() == ConformanceResponse::kSerializeError) { @@ -1330,6 +1343,7 @@ BinaryAndJsonConformanceSuiteImpl:: BinaryAndJsonConformanceSuiteImpl(BinaryAndJsonConformanceSuite* suite, bool run_proto3_tests) : suite_(*ABSL_DIE_IF_NULL(suite)), run_proto3_tests_(run_proto3_tests) { + suite_.SetTypeUrl(GetTypeUrl(MessageType::GetDescriptor())); RunAllTests(); } @@ -1666,15 +1680,18 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTests() { "FieldName13": 0 })", [](const Json::Value& value) { return value.isMember("FieldName13"); }); - RunValidJsonTestWithValidator( - "FieldNameExtension", RECOMMENDED, - R"({ - "[protobuf_test_messages.proto2.extension_int32]": 1 + std::vector extensions; + MessageType::GetDescriptor()->file()->pool()->FindAllExtensions( + MessageType::GetDescriptor(), &extensions); + RunValidJsonTestWithValidator("FieldNameExtension", RECOMMENDED, + absl::Substitute(R"({ + "[$0]": 1 })", - [](const Json::Value& value) { - return value.isMember( - "[protobuf_test_messages.proto2.extension_int32]"); - }); + extensions[0]->full_name()), + [&](const Json::Value& value) { + return value.isMember(absl::StrCat( + "[", extensions[0]->full_name(), "]")); + }); return; } RunValidJsonTest("HelloWorld", REQUIRED, @@ -2175,7 +2192,7 @@ void BinaryAndJsonConformanceSuiteImpl< R"({"optionalFloat": "-Infinity"})", "optional_float: -inf"); // Non-canonical Nan will be correctly normalized. { - TestAllTypesProto3 message; + MessageType message; // IEEE floating-point standard 32-bit quiet NaN: // 0111 1111 1xxx xxxx xxxx xxxx xxxx xxxx message.set_optional_float(WireFormatLite::DecodeFloat(0x7FA12345)); @@ -2227,7 +2244,7 @@ void BinaryAndJsonConformanceSuiteImpl< "optional_double: -inf"); // Non-canonical Nan will be correctly normalized. { - TestAllTypesProto3 message; + MessageType message; message.set_optional_double( WireFormatLite::DecodeDouble(int64_t{0x7FFA123456789ABC})); RunValidJsonTestWithProtobufInput("DoubleFieldNormalizeQuietNan", REQUIRED, @@ -3008,54 +3025,61 @@ void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForValue() { template void BinaryAndJsonConformanceSuiteImpl::RunJsonTestsForAny() { + std::string type_url = GetTypeUrl(MessageType::GetDescriptor()); RunValidJsonTest("Any", REQUIRED, - R"({ + absl::Substitute(R"({ "optionalAny": { - "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3", + "@type": "$0", "optionalInt32": 12345 } })", - R"( + GetTypeUrl(MessageType::GetDescriptor())), + absl::Substitute(R"( optional_any: { - [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { + [$0] { optional_int32: 12345 - } - } - )"); + } + } + )", + type_url)); RunValidJsonTest("AnyNested", REQUIRED, - R"({ + absl::Substitute(R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Any", "value": { - "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3", + "@type": "$0", "optionalInt32": 12345 } } })", - R"( + type_url), + absl::Substitute(R"( optional_any: { - [type.googleapis.com/google.protobuf.Any] { - [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { + [type.googleapis.com/google.protobuf.Any] { + [$0] { optional_int32: 12345 - } - } - } - )"); + } + } + } + )", + type_url)); // The special "@type" tag is not required to appear first. RunValidJsonTest("AnyUnorderedTypeTag", REQUIRED, - R"({ + absl::Substitute(R"({ "optionalAny": { "optionalInt32": 12345, - "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3" - } + "@type": "$0" + } })", - R"( + type_url), + absl::Substitute(R"( optional_any: { - [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] { + [$0] { optional_int32: 12345 - } - } - )"); + } + } + )", + type_url)); // Well-known types in Any. RunValidJsonTest("AnyWithInt32ValueWrapper", REQUIRED, R"({ @@ -3253,8 +3277,13 @@ std::string BinaryAndJsonConformanceSuiteImpl::SyntaxIdentifier() const { if constexpr (std::is_same::value) { return "Proto2"; - } else { + } else if constexpr (std::is_same::value) { return "Proto3"; + } else if constexpr (std::is_same::value) { + return "Editions_Proto2"; + } else { + return "Editions_Proto3"; } } diff --git a/conformance/binary_json_conformance_suite.h b/conformance/binary_json_conformance_suite.h index f6a87088b1..d777bba019 100644 --- a/conformance/binary_json_conformance_suite.h +++ b/conformance/binary_json_conformance_suite.h @@ -14,6 +14,7 @@ #include #include +#include "absl/strings/string_view.h" #include "json/json.h" #include "conformance_test.h" #include "google/protobuf/descriptor.h" @@ -33,6 +34,9 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { bool ParseResponse(const conformance::ConformanceResponse& response, const ConformanceRequestSetting& setting, Message* test_message) override; + void SetTypeUrl(absl::string_view type_url) { + type_url_ = std::string(type_url); + } template friend class BinaryAndJsonConformanceSuiteImpl; @@ -44,8 +48,8 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { template class BinaryAndJsonConformanceSuiteImpl { public: - BinaryAndJsonConformanceSuiteImpl(BinaryAndJsonConformanceSuite* suite, - bool run_proto3_tests); + explicit BinaryAndJsonConformanceSuiteImpl( + BinaryAndJsonConformanceSuite* suite, bool run_proto3_tests); private: using ConformanceRequestSetting = @@ -79,8 +83,7 @@ class BinaryAndJsonConformanceSuiteImpl { const Message& prototype); void RunValidJsonTestWithProtobufInput( const std::string& test_name, ConformanceLevel level, - const protobuf_test_messages::proto3::TestAllTypesProto3& input, - const std::string& equivalent_text_format); + const MessageType& input, const std::string& equivalent_text_format); void RunValidJsonIgnoreUnknownTest(const std::string& test_name, ConformanceLevel level, const std::string& input_json, diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc index 30baafca22..86c651c0fb 100644 --- a/conformance/conformance_cpp.cc +++ b/conformance/conformance_cpp.cc @@ -21,6 +21,8 @@ #include "absl/status/statusor.h" #include "conformance/conformance.pb.h" #include "conformance/conformance.pb.h" +#include "google/protobuf/editions/golden/test_messages_proto2_editions.pb.h" +#include "google/protobuf/editions/golden/test_messages_proto3_editions.pb.h" #include "google/protobuf/endian.h" #include "google/protobuf/message.h" #include "google/protobuf/test_messages_proto2.pb.h" @@ -45,6 +47,10 @@ using ::google::protobuf::util::NewTypeResolverForDescriptorPool; using ::google::protobuf::util::TypeResolver; using ::protobuf_test_messages::proto2::TestAllTypesProto2; using ::protobuf_test_messages::proto3::TestAllTypesProto3; +using TestAllTypesProto2Editions = + ::protobuf_test_messages::editions::proto2::TestAllTypesProto2; +using TestAllTypesProto3Editions = + ::protobuf_test_messages::editions::proto3::TestAllTypesProto3; absl::Status ReadFd(int fd, char* buf, size_t len) { while (len > 0) { @@ -76,6 +82,8 @@ class Harness { Harness() { google::protobuf::LinkMessageReflection(); google::protobuf::LinkMessageReflection(); + google::protobuf::LinkMessageReflection(); + google::protobuf::LinkMessageReflection(); resolver_.reset(NewTypeResolverForDescriptorPool( "type.googleapis.com", DescriptorPool::generated_pool())); diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 94efbcc466..dbcaf45836 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -149,6 +149,16 @@ ConformanceTestSuite::ConformanceRequestSetting::GetSyntaxIdentifier() const { return "Proto3"; case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2: return "Proto2"; + case FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS: { + std::string id = "Editions"; + if (prototype_message_.GetDescriptor()->name() == "TestAllTypesProto2") { + absl::StrAppend(&id, "_Proto2"); + } else if (prototype_message_.GetDescriptor()->name() == + "TestAllTypesProto3") { + absl::StrAppend(&id, "_Proto3"); + } + return id; + } default: return "Unknown"; } diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index 00559d9e1a..c78f9ea8ab 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -132,6 +132,7 @@ class ConformanceTestSuite { : verbose_(false), performance_(false), enforce_recommended_(false), + maximum_edition_(Edition::EDITION_PROTO3), failure_list_flag_name_("--failure_list") {} virtual ~ConformanceTestSuite() {} @@ -148,6 +149,9 @@ class ConformanceTestSuite { // difference between REQUIRED and RECOMMENDED test cases. void SetEnforceRecommended(bool value) { enforce_recommended_ = value; } + // Sets the maximum edition (inclusive) that should be tests for conformance. + void SetMaximumEdition(Edition edition) { maximum_edition_ = edition; } + // Gets the flag name to the failure list file. // By default, this would return --failure_list std::string GetFailureListFlagName() { return failure_list_flag_name_; } @@ -284,6 +288,7 @@ class ConformanceTestSuite { bool verbose_; bool performance_; bool enforce_recommended_; + Edition maximum_edition_; std::string output_; std::string output_dir_; std::string failure_list_flag_name_; diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc index 44b9a09f5a..5edb3c651e 100644 --- a/conformance/conformance_test_runner.cc +++ b/conformance/conformance_test_runner.cc @@ -37,12 +37,15 @@ #include #include +#include #include +#include #include #include #include #include "absl/log/absl_log.h" +#include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "conformance/conformance.pb.h" #include "conformance_test.h" @@ -119,6 +122,11 @@ void UsageError() { fprintf(stderr, " strictly conforming to protobuf\n"); fprintf(stderr, " spec.\n"); + fprintf(stderr, + " --maximum edition Only run conformance tests up to \n"); + fprintf(stderr, + " and including the specified\n"); + fprintf(stderr, " edition.\n"); fprintf(stderr, " --output_dir Directory to write\n" " output files.\n"); @@ -200,6 +208,14 @@ int ForkPipeRunner::Run(int argc, char *argv[], suite->SetVerbose(true); } else if (strcmp(argv[arg], "--enforce_recommended") == 0) { suite->SetEnforceRecommended(true); + } else if (strcmp(argv[arg], "--maximum_edition") == 0) { + if (++arg == argc) UsageError(); + Edition edition = EDITION_UNKNOWN; + if (!Edition_Parse(absl::StrCat("EDITION_", argv[arg]), &edition)) { + fprintf(stderr, "Unknown edition: %s\n", argv[arg]); + UsageError(); + } + suite->SetMaximumEdition(edition); } else if (strcmp(argv[arg], "--output_dir") == 0) { if (++arg == argc) UsageError(); suite->SetOutputDir(argv[arg]); diff --git a/conformance/defs.bzl b/conformance/defs.bzl index 8daef8650c..3a7d1d6cbc 100644 --- a/conformance/defs.bzl +++ b/conformance/defs.bzl @@ -8,6 +8,7 @@ def conformance_test( testee, failure_list = None, text_format_failure_list = None, + maximum_edition = None, **kwargs): """Conformance test runner. @@ -27,6 +28,8 @@ def conformance_test( if text_format_failure_list: args = args + ["--text_format_failure_list %s" % _strip_bazel(text_format_failure_list)] failure_lists = failure_lists + [text_format_failure_list] + if maximum_edition: + args = args + ["--maximum_edition %s" % maximum_edition] native.sh_test( name = name, diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt index aa18cea1a6..235ae697b8 100644 --- a/conformance/failure_list_cpp.txt +++ b/conformance/failure_list_cpp.txt @@ -7,30 +7,57 @@ # TODO: insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? -Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput -Recommended.FieldMaskPathsDontRoundTrip.JsonOutput -Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.Proto3.FieldMaskNumbersDontRoundTrip.JsonOutput +Recommended.Editions_Proto3.FieldMaskNumbersDontRoundTrip.JsonOutput +Recommended.Proto3.FieldMaskPathsDontRoundTrip.JsonOutput +Recommended.Editions_Proto3.FieldMaskPathsDontRoundTrip.JsonOutput +Recommended.Proto3.FieldMaskTooManyUnderscore.JsonOutput +Recommended.Editions_Proto3.FieldMaskTooManyUnderscore.JsonOutput Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedFalse +Recommended.Editions_Proto3.JsonInput.BoolFieldDoubleQuotedFalse Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedTrue +Recommended.Editions_Proto3.JsonInput.BoolFieldDoubleQuotedTrue Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter +Recommended.Editions_Proto3.JsonInput.FieldMaskInvalidCharacter Recommended.Proto3.JsonInput.FieldNameDuplicate +Recommended.Editions_Proto3.JsonInput.FieldNameDuplicate Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing1 +Recommended.Editions_Proto3.JsonInput.FieldNameDuplicateDifferentCasing1 Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing2 +Recommended.Editions_Proto3.JsonInput.FieldNameDuplicateDifferentCasing2 Recommended.Proto3.JsonInput.FieldNameNotQuoted +Recommended.Editions_Proto3.JsonInput.FieldNameNotQuoted Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput Recommended.Proto3.JsonInput.MapFieldValueIsNull +Recommended.Editions_Proto3.JsonInput.MapFieldValueIsNull Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull +Recommended.Editions_Proto3.JsonInput.RepeatedFieldMessageElementIsNull Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull +Recommended.Editions_Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull Recommended.Proto3.JsonInput.RepeatedFieldTrailingComma +Recommended.Editions_Proto3.JsonInput.RepeatedFieldTrailingComma Recommended.Proto3.JsonInput.RepeatedFieldTrailingCommaWithNewlines +Recommended.Editions_Proto3.JsonInput.RepeatedFieldTrailingCommaWithNewlines Recommended.Proto3.JsonInput.RepeatedFieldTrailingCommaWithSpace +Recommended.Editions_Proto3.JsonInput.RepeatedFieldTrailingCommaWithSpace Recommended.Proto3.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace +Recommended.Editions_Proto3.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace Recommended.Proto3.JsonInput.StringFieldSingleQuoteBoth +Recommended.Editions_Proto3.JsonInput.StringFieldSingleQuoteBoth Recommended.Proto3.JsonInput.StringFieldSingleQuoteKey +Recommended.Editions_Proto3.JsonInput.StringFieldSingleQuoteKey Recommended.Proto3.JsonInput.StringFieldSingleQuoteValue +Recommended.Editions_Proto3.JsonInput.StringFieldSingleQuoteValue Recommended.Proto3.JsonInput.StringFieldUppercaseEscapeLetter +Recommended.Editions_Proto3.JsonInput.StringFieldUppercaseEscapeLetter Recommended.Proto3.JsonInput.TrailingCommaInAnObject +Recommended.Editions_Proto3.JsonInput.TrailingCommaInAnObject Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithNewlines +Recommended.Editions_Proto3.JsonInput.TrailingCommaInAnObjectWithNewlines Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpace +Recommended.Editions_Proto3.JsonInput.TrailingCommaInAnObjectWithSpace Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace +Recommended.Editions_Proto3.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace Recommended.Proto2.JsonInput.FieldNameExtension.Validator +Recommended.Editions_Proto2.JsonInput.FieldNameExtension.Validator diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt index 6999ff0755..6c7c0dd029 100644 --- a/conformance/failure_list_csharp.txt +++ b/conformance/failure_list_csharp.txt @@ -5,5 +5,5 @@ Required.Proto3.JsonInput.OneofFieldNullFirst.JsonOutput Required.Proto3.JsonInput.OneofFieldNullFirst.ProtobufOutput Required.Proto3.JsonInput.OneofFieldNullSecond.JsonOutput Required.Proto3.JsonInput.OneofFieldNullSecond.ProtobufOutput -Recommended.ValueRejectInfNumberValue.JsonOutput -Recommended.ValueRejectNanNumberValue.JsonOutput \ No newline at end of file +Recommended.Proto3.ValueRejectInfNumberValue.JsonOutput +Recommended.Proto3.ValueRejectNanNumberValue.JsonOutput diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt index 808e230eba..8508abd31d 100644 --- a/conformance/failure_list_java.txt +++ b/conformance/failure_list_java.txt @@ -4,9 +4,9 @@ # By listing them here we can keep tabs on which ones are failing and be sure # that we don't introduce regressions in other tests. -Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput -Recommended.FieldMaskPathsDontRoundTrip.JsonOutput -Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.Proto3.FieldMaskNumbersDontRoundTrip.JsonOutput +Recommended.Proto3.FieldMaskPathsDontRoundTrip.JsonOutput +Recommended.Proto3.FieldMaskTooManyUnderscore.JsonOutput Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue Recommended.Proto3.JsonInput.BoolFieldCamelCaseFalse diff --git a/conformance/failure_list_jruby.txt b/conformance/failure_list_jruby.txt index c0d29804fe..6d511a38a6 100644 --- a/conformance/failure_list_jruby.txt +++ b/conformance/failure_list_jruby.txt @@ -1,6 +1,6 @@ -Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput -Recommended.FieldMaskPathsDontRoundTrip.JsonOutput -Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.Proto3.FieldMaskNumbersDontRoundTrip.JsonOutput +Recommended.Proto3.FieldMaskPathsDontRoundTrip.JsonOutput +Recommended.Proto3.FieldMaskTooManyUnderscore.JsonOutput Recommended.Proto2.JsonInput.FieldNameExtension.Validator Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index ae39296917..1c2c17bdbe 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -15,6 +15,8 @@ #include "absl/log/die_if_null.h" #include "absl/strings/str_cat.h" #include "conformance_test.h" +#include "google/protobuf/editions/golden/test_messages_proto2_editions.pb.h" +#include "google/protobuf/editions/golden/test_messages_proto3_editions.pb.h" #include "google/protobuf/test_messages_proto2.pb.h" #include "google/protobuf/test_messages_proto3.pb.h" #include "google/protobuf/text_format.h" @@ -25,6 +27,10 @@ using conformance::WireFormat; using protobuf_test_messages::proto2::TestAllTypesProto2; using protobuf_test_messages::proto2::UnknownToTestAllTypes; using protobuf_test_messages::proto3::TestAllTypesProto3; +using TestAllTypesProto2Editions = + protobuf_test_messages::editions::proto2::TestAllTypesProto2; +using TestAllTypesProto3Editions = + protobuf_test_messages::editions::proto3::TestAllTypesProto3; namespace google { namespace protobuf { @@ -113,6 +119,10 @@ bool TextFormatConformanceTestSuite::ParseResponse( void TextFormatConformanceTestSuite::RunSuiteImpl() { TextFormatConformanceTestSuiteImpl(this); TextFormatConformanceTestSuiteImpl(this); + if (maximum_edition_ >= Edition::EDITION_2023) { + TextFormatConformanceTestSuiteImpl(this); + TextFormatConformanceTestSuiteImpl(this); + } } template diff --git a/conformance/text_format_failure_list_cpp.txt b/conformance/text_format_failure_list_cpp.txt index a25f04faf2..fd2d7ada1f 100644 --- a/conformance/text_format_failure_list_cpp.txt +++ b/conformance/text_format_failure_list_cpp.txt @@ -1,20 +1,40 @@ Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Editions_Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Editions_Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Editions_Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Editions_Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Editions_Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Editions_Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Editions_Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Editions_Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Editions_Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Editions_Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Editions_Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Editions_Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Editions_Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Editions_Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Editions_Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Recommended.Editions_Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex +Required.Editions_Proto3.TextFormatInput.StringFieldBadUTF8Hex Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal +Required.Editions_Proto3.TextFormatInput.StringFieldBadUTF8Octal Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Editions_Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString +Required.Editions_Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString diff --git a/src/BUILD.bazel b/src/BUILD.bazel index 2ce3449845..7c42d0b01a 100644 --- a/src/BUILD.bazel +++ b/src/BUILD.bazel @@ -38,6 +38,7 @@ pkg_filegroup( conformance_test( name = "conformance_test", failure_list = "//conformance:failure_list_cpp.txt", + maximum_edition = "2023", testee = "//conformance:conformance_cpp", text_format_failure_list = "//conformance:text_format_failure_list_cpp.txt", ) diff --git a/src/google/protobuf/editions/BUILD b/src/google/protobuf/editions/BUILD index 0fa11a8453..4489ffdbf8 100644 --- a/src/google/protobuf/editions/BUILD +++ b/src/google/protobuf/editions/BUILD @@ -85,22 +85,23 @@ cc_test( ) proto_library( - name = "test_messages_proto2_proto", + name = "test_messages_proto2_editions_proto", testonly = True, - srcs = ["golden/test_messages_proto2.proto"], + srcs = ["golden/test_messages_proto2_editions.proto"], strip_import_prefix = "/src", ) cc_proto_library( - name = "test_messages_proto2_cc_proto", + name = "test_messages_proto2_editions_cc_proto", testonly = True, - deps = [":test_messages_proto2_proto"], + visibility = ["//conformance:__pkg__"], + deps = [":test_messages_proto2_editions_proto"], ) proto_library( - name = "test_messages_proto3_proto", + name = "test_messages_proto3_editions_proto", testonly = True, - srcs = ["golden/test_messages_proto3.proto"], + srcs = ["golden/test_messages_proto3_editions.proto"], strip_import_prefix = "/src", deps = [ "//:any_proto", @@ -113,9 +114,10 @@ proto_library( ) cc_proto_library( - name = "test_messages_proto3_cc_proto", + name = "test_messages_proto3_editions_cc_proto", testonly = True, - deps = [":test_messages_proto3_proto"], + visibility = ["//conformance:__pkg__"], + deps = [":test_messages_proto3_editions_proto"], ) proto_library( @@ -136,8 +138,8 @@ cc_test( srcs = ["generated_files_test.cc"], deps = [ ":test_editions_default_features_cc_proto", - ":test_messages_proto2_cc_proto", - ":test_messages_proto3_cc_proto", + ":test_messages_proto2_editions_cc_proto", + ":test_messages_proto3_editions_cc_proto", "//:protobuf", "//src/google/protobuf:test_textproto", "@com_google_googletest//:gtest_main", @@ -148,7 +150,7 @@ cc_test( name = "generated_reflection_test", srcs = ["generated_reflection_test.cc"], deps = [ - ":test_messages_proto2_cc_proto", + ":test_messages_proto2_editions_cc_proto", "@com_google_googletest//:gtest_main", ], ) diff --git a/src/google/protobuf/editions/generated_files_test.cc b/src/google/protobuf/editions/generated_files_test.cc index f74aa977e9..fe2bf0f142 100644 --- a/src/google/protobuf/editions/generated_files_test.cc +++ b/src/google/protobuf/editions/generated_files_test.cc @@ -9,8 +9,8 @@ #include #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/editions/golden/test_messages_proto2.pb.h" -#include "google/protobuf/editions/golden/test_messages_proto3.pb.h" +#include "google/protobuf/editions/golden/test_messages_proto2_editions.pb.h" +#include "google/protobuf/editions/golden/test_messages_proto3_editions.pb.h" #include "google/protobuf/editions/proto/test_editions_default_features.pb.h" #include "google/protobuf/test_textproto.h" @@ -22,9 +22,9 @@ namespace protobuf { namespace { using ::protobuf_editions_test::EditionsDefaultMessage; -using ::protobuf_test_messages::proto2::TestAllRequiredTypesProto2; -using ::protobuf_test_messages::proto2::TestAllTypesProto2; -using ::protobuf_test_messages::proto3::TestAllTypesProto3; +using ::protobuf_test_messages::editions::proto2::TestAllRequiredTypesProto2; +using ::protobuf_test_messages::editions::proto2::TestAllTypesProto2; +using ::protobuf_test_messages::editions::proto3::TestAllTypesProto3; using ::testing::NotNull; TEST(Generated, Parsing) { diff --git a/src/google/protobuf/editions/generated_reflection_test.cc b/src/google/protobuf/editions/generated_reflection_test.cc index ede6c6e845..a4161b9324 100644 --- a/src/google/protobuf/editions/generated_reflection_test.cc +++ b/src/google/protobuf/editions/generated_reflection_test.cc @@ -6,13 +6,13 @@ // https://developers.google.com/open-source/licenses/bsd #include -#include "google/protobuf/editions/golden/test_messages_proto2.pb.h" +#include "google/protobuf/editions/golden/test_messages_proto2_editions.pb.h" namespace google { namespace protobuf { namespace { -using ::protobuf_test_messages::proto2::TestAllTypesProto2; +using ::protobuf_test_messages::editions::proto2::TestAllTypesProto2; // It's important that no calls that would initialize the generated pool occur // in any tests in this file. This test guarantees that there's no mutex diff --git a/src/google/protobuf/editions/golden/test_messages_proto2.proto b/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto similarity index 99% rename from src/google/protobuf/editions/golden/test_messages_proto2.proto rename to src/google/protobuf/editions/golden/test_messages_proto2_editions.proto index 32da3854c0..d13376b596 100644 --- a/src/google/protobuf/editions/golden/test_messages_proto2.proto +++ b/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto @@ -13,13 +13,13 @@ edition = "2023"; -package protobuf_test_messages.proto2; +package protobuf_test_messages.editions.proto2; option features.enum_type = CLOSED; option features.repeated_field_encoding = EXPANDED; option features.utf8_validation = NONE; option features.json_format = LEGACY_BEST_EFFORT; -option java_package = "com.google.protobuf_test_messages.proto2"; +option java_package = "com.google.protobuf_test_messages.editions.proto2"; option objc_class_prefix = "Proto2"; // This is the default, but we specify it here explicitly. diff --git a/src/google/protobuf/editions/golden/test_messages_proto3.proto b/src/google/protobuf/editions/golden/test_messages_proto3_editions.proto similarity index 98% rename from src/google/protobuf/editions/golden/test_messages_proto3.proto rename to src/google/protobuf/editions/golden/test_messages_proto3_editions.proto index be9ca144e4..9dbf63e6a5 100644 --- a/src/google/protobuf/editions/golden/test_messages_proto3.proto +++ b/src/google/protobuf/editions/golden/test_messages_proto3_editions.proto @@ -13,7 +13,7 @@ edition = "2023"; -package protobuf_test_messages.proto3; +package protobuf_test_messages.editions.proto3; import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; @@ -23,7 +23,7 @@ import "google/protobuf/timestamp.proto"; import "google/protobuf/wrappers.proto"; option features.field_presence = IMPLICIT; -option java_package = "com.google.protobuf_test_messages.proto3"; +option java_package = "com.google.protobuf_test_messages.editions.proto3"; option objc_class_prefix = "Proto3"; // This is the default, but we specify it here explicitly. From 8ff15497f301dec312d4f714078674b91e5f18f3 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 18 Oct 2023 13:32:07 -0700 Subject: [PATCH 33/95] Change the behavior of --experimental_editions. Previously, this gated all editions access and then further checks were applied. This removes those checks so that we can incrementally roll out editions support to individual languages. Anyone using the --experimental_editions flag should be careful not to use it on generators that don't support editions. As we launch editions support for individual generators, this flag won't be required to use them. PiperOrigin-RevId: 574577631 --- .../protobuf/compiler/code_generator.cc | 13 +++ .../compiler/code_generator_unittest.cc | 18 ++++ .../compiler/command_line_interface.cc | 92 +++++++++++-------- .../compiler/command_line_interface.h | 4 + .../command_line_interface_unittest.cc | 17 ++-- .../protobuf/compiler/java/generator.cc | 3 +- .../compiler/java/kotlin_generator.cc | 3 +- src/google/protobuf/compiler/plugin.cc | 19 ++-- 8 files changed, 103 insertions(+), 66 deletions(-) diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index 863192d735..332cf53dfb 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -23,6 +23,9 @@ #include "google/protobuf/descriptor.h" #include "google/protobuf/feature_resolver.h" +// Must be included last. +#include "google/protobuf/port_def.inc" + namespace google { namespace protobuf { namespace compiler { @@ -57,6 +60,14 @@ bool CodeGenerator::GenerateAll(const std::vector& files, absl::StatusOr CodeGenerator::BuildFeatureSetDefaults() const { + if ((GetSupportedFeatures() & FEATURE_SUPPORTS_EDITIONS) == 0) { + // For generators that don't fully support editions yet, provide an + // optimistic set of defaults. Protoc will check this condition later + // anyway. + return FeatureResolver::CompileDefaults( + FeatureSet::descriptor(), GetFeatureExtensions(), + PROTOBUF_MINIMUM_EDITION, PROTOBUF_MAXIMUM_EDITION); + } return FeatureResolver::CompileDefaults( FeatureSet::descriptor(), GetFeatureExtensions(), GetMinimumEdition(), GetMaximumEdition()); @@ -131,3 +142,5 @@ bool IsKnownFeatureProto(absl::string_view filename) { } // namespace compiler } // namespace protobuf } // namespace google + +#include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/compiler/code_generator_unittest.cc b/src/google/protobuf/compiler/code_generator_unittest.cc index 4cfc75c9dc..a98214b70c 100644 --- a/src/google/protobuf/compiler/code_generator_unittest.cc +++ b/src/google/protobuf/compiler/code_generator_unittest.cc @@ -7,6 +7,7 @@ #include "google/protobuf/compiler/code_generator.h" +#include #include #include @@ -43,6 +44,9 @@ class TestGenerator : public CodeGenerator { return true; } + uint64_t GetSupportedFeatures() const override { return features_; } + void set_supported_features(uint64_t features) { features_ = features; } + std::vector GetFeatureExtensions() const override { return feature_extensions_; } @@ -65,6 +69,7 @@ class TestGenerator : public CodeGenerator { using CodeGenerator::GetUnresolvedSourceFeatures; private: + uint64_t features_ = CodeGenerator::Feature::FEATURE_SUPPORTS_EDITIONS; Edition minimum_edition_ = PROTOBUF_MINIMUM_EDITION; Edition maximum_edition_ = PROTOBUF_MAXIMUM_EDITION; std::vector feature_extensions_ = { @@ -301,6 +306,19 @@ TEST_F(CodeGeneratorTest, BuildFeatureSetDefaults) { )pb"))); } +TEST_F(CodeGeneratorTest, BuildFeatureSetDefaultsUnsupported) { + TestGenerator generator; + generator.set_supported_features(0); + generator.set_feature_extensions({}); + generator.set_minimum_edition(EDITION_99997_TEST_ONLY); + generator.set_maximum_edition(EDITION_99999_TEST_ONLY); + auto result = generator.BuildFeatureSetDefaults(); + + ASSERT_TRUE(result.ok()) << result.status().message(); + EXPECT_EQ(result->minimum_edition(), PROTOBUF_MINIMUM_EDITION); + EXPECT_EQ(result->maximum_edition(), PROTOBUF_MAXIMUM_EDITION); +} + #include "google/protobuf/port_undef.inc" } // namespace diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 2e12765533..a749f79ce4 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -11,6 +11,7 @@ #include "google/protobuf/compiler/command_line_interface.h" +#include #include #include "absl/algorithm/container.h" @@ -295,28 +296,6 @@ bool GetBootstrapParam(const std::string& parameter) { } -bool EnforceEditionsSupport( - const std::string& codegen_name, uint64_t supported_features, - const std::vector& parsed_files) { - if ((supported_features & CodeGenerator::FEATURE_SUPPORTS_EDITIONS) == 0) { - for (const auto fd : parsed_files) { - if (FileDescriptorLegacy(fd).syntax() == - FileDescriptorLegacy::SYNTAX_EDITIONS) { - std::cerr - << fd->name() << ": is an editions file, but code generator " - << codegen_name - << " hasn't been updated to support editions yet. Please ask " - "the owner of this code generator to add support or " - "switch back to proto2/proto3.\n\nSee " - "https://protobuf.dev/editions/overview/ for more information." - << std::endl; - return false; - } - } - } - return true; -} - } // namespace void CommandLineInterface::GetTransitiveDependencies( @@ -1538,24 +1517,26 @@ bool CommandLineInterface::SetupFeatureResolution(DescriptorPool& pool) { for (const auto& output : output_directives_) { if (output.generator == nullptr) continue; if ((output.generator->GetSupportedFeatures() & - CodeGenerator::FEATURE_SUPPORTS_EDITIONS) == 0) { - continue; - } - if (output.generator->GetMinimumEdition() != PROTOBUF_MINIMUM_EDITION) { - ABSL_LOG(ERROR) << "Built-in generator " << output.name - << " specifies a minimum edition " - << output.generator->GetMinimumEdition() - << " which is not the protoc minimum " - << PROTOBUF_MINIMUM_EDITION << "."; - return false; - } - if (output.generator->GetMaximumEdition() != PROTOBUF_MAXIMUM_EDITION) { - ABSL_LOG(ERROR) << "Built-in generator " << output.name - << " specifies a maximum edition " - << output.generator->GetMaximumEdition() - << " which is not the protoc maximum " - << PROTOBUF_MAXIMUM_EDITION << "."; - return false; + CodeGenerator::FEATURE_SUPPORTS_EDITIONS) != 0) { + // Only validate min/max edition on generators that advertise editions + // support. Generators still under development will always use the + // correct values. + if (output.generator->GetMinimumEdition() != minimum_edition) { + ABSL_LOG(ERROR) << "Built-in generator " << output.name + << " specifies a minimum edition " + << output.generator->GetMinimumEdition() + << " which is not the protoc minimum " + << minimum_edition << "."; + return false; + } + if (output.generator->GetMaximumEdition() != maximum_edition) { + ABSL_LOG(ERROR) << "Built-in generator " << output.name + << " specifies a maximum edition " + << output.generator->GetMaximumEdition() + << " which is not the protoc maximum " + << maximum_edition << "."; + return false; + } } for (const FieldDescriptor* ext : output.generator->GetFeatureExtensions()) { @@ -2566,6 +2547,37 @@ bool CommandLineInterface::EnforceProto3OptionalSupport( return true; } +bool CommandLineInterface::EnforceEditionsSupport( + const std::string& codegen_name, uint64_t supported_features, + const std::vector& parsed_files) const { + if (supported_features & CodeGenerator::FEATURE_SUPPORTS_EDITIONS) { + // This generator explicitly supports editions. + return true; + } + if (experimental_editions_) { + // The user has explicitly specified the experimental flag. + return true; + } + for (const auto* fd : parsed_files) { + // Skip enforcement for allowlisted files. + if (IsEarlyEditionsFile(fd->name())) continue; + + if (FileDescriptorLegacy(fd).syntax() == + FileDescriptorLegacy::SYNTAX_EDITIONS) { + std::cerr + << fd->name() << ": is an editions file, but code generator " + << codegen_name + << " hasn't been updated to support editions yet. Please ask " + "the owner of this code generator to add support or " + "switch back to proto2/proto3.\n\nSee " + "https://protobuf.dev/editions/overview/ for more information." + << std::endl; + return false; + } + } + return true; +} + bool CommandLineInterface::GenerateOutput( const std::vector& parsed_files, const OutputDirective& output_directive, diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 58e7a8ab54..107c618fb1 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -222,6 +222,10 @@ class PROTOC_EXPORT CommandLineInterface { const std::string& codegen_name, uint64_t supported_features, const std::vector& parsed_files) const; + bool EnforceEditionsSupport( + const std::string& codegen_name, uint64_t supported_features, + const std::vector& parsed_files) const; + // Return status for ParseArguments() and InterpretArgument(). enum ParseArgumentStatus { diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 23a1c7014a..88e7412176 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -1354,16 +1354,14 @@ TEST_F(CommandLineInterfaceTest, AllowServicesHasService) { ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } -TEST_F(CommandLineInterfaceTest, EditionsAreNotAllowed) { +TEST_F(CommandLineInterfaceTest, NonExperimentalEditions) { CreateTempFile("foo.proto", "edition = \"2023\";\n" "message FooRequest {}\n"); Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir foo.proto"); - ExpectErrorSubstring( - "This file uses editions, but --experimental_editions has not been " - "enabled."); + ExpectErrorSubstring("--experimental_editions has not been enabled"); } TEST_F(CommandLineInterfaceTest, EditionsFlagExplicitTrue) { @@ -1713,12 +1711,10 @@ TEST_F(CommandLineInterfaceTest, GeneratorNoEditionsSupport) { "Doesn't support editions", CodeGenerator::FEATURE_SUPPORTS_EDITIONS); - Run("protocol_compiler --experimental_editions " + Run("protocol_compiler " "--proto_path=$tmpdir foo.proto --no_editions_out=$tmpdir"); - ExpectErrorSubstring( - "code generator --no_editions_out hasn't been updated to support " - "editions"); + ExpectErrorSubstring("--experimental_editions has not been enabled"); } TEST_F(CommandLineInterfaceTest, PluginNoEditionsSupport) { @@ -1730,11 +1726,10 @@ TEST_F(CommandLineInterfaceTest, PluginNoEditionsSupport) { )schema"); SetMockGeneratorTestCase("no_editions"); - Run("protocol_compiler --experimental_editions " + Run("protocol_compiler " "--proto_path=$tmpdir foo.proto --plug_out=$tmpdir"); - ExpectErrorSubstring( - "code generator prefix-gen-plug hasn't been updated to support editions"); + ExpectErrorSubstring("--experimental_editions has not been enabled"); } TEST_F(CommandLineInterfaceTest, EditionDefaults) { diff --git a/src/google/protobuf/compiler/java/generator.cc b/src/google/protobuf/compiler/java/generator.cc index aceb1207f1..5435bb9e13 100644 --- a/src/google/protobuf/compiler/java/generator.cc +++ b/src/google/protobuf/compiler/java/generator.cc @@ -38,8 +38,7 @@ JavaGenerator::JavaGenerator() {} JavaGenerator::~JavaGenerator() {} uint64_t JavaGenerator::GetSupportedFeatures() const { - return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL | - CodeGenerator::Feature::FEATURE_SUPPORTS_EDITIONS; + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; } bool JavaGenerator::Generate(const FileDescriptor* file, diff --git a/src/google/protobuf/compiler/java/kotlin_generator.cc b/src/google/protobuf/compiler/java/kotlin_generator.cc index c9848b390d..5cf3482edc 100644 --- a/src/google/protobuf/compiler/java/kotlin_generator.cc +++ b/src/google/protobuf/compiler/java/kotlin_generator.cc @@ -22,8 +22,7 @@ KotlinGenerator::KotlinGenerator() {} KotlinGenerator::~KotlinGenerator() {} uint64_t KotlinGenerator::GetSupportedFeatures() const { - return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL | - CodeGenerator::Feature::FEATURE_SUPPORTS_EDITIONS; + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; } bool KotlinGenerator::Generate(const FileDescriptor* file, diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index 471caa7914..166e1c0851 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -94,18 +94,15 @@ bool GenerateCode(const CodeGeneratorRequest& request, CodeGeneratorResponse* response, std::string* error_msg) { DescriptorPool pool; - if (generator.GetSupportedFeatures() & - CodeGenerator::FEATURE_SUPPORTS_EDITIONS) { - // Initialize feature set default mapping. - absl::StatusOr defaults = - generator.BuildFeatureSetDefaults(); - if (!defaults.ok()) { - *error_msg = absl::StrCat("error generating feature defaults: ", - defaults.status().message()); - return false; - } - pool.SetFeatureSetDefaults(*defaults); + // Initialize feature set default mapping. + absl::StatusOr defaults = + generator.BuildFeatureSetDefaults(); + if (!defaults.ok()) { + *error_msg = absl::StrCat("error generating feature defaults: ", + defaults.status().message()); + return false; } + pool.SetFeatureSetDefaults(*defaults); for (int i = 0; i < request.proto_file_size(); i++) { const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); From 0883b22ac4b830a0cb771ea7485481575a2cc7a5 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Wed, 18 Oct 2023 13:36:30 -0700 Subject: [PATCH 34/95] Enable staleness tests for 25.x branch PiperOrigin-RevId: 574579237 --- .github/workflows/staleness_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/staleness_check.yml b/.github/workflows/staleness_check.yml index 273a4b0117..45aa2b3bcc 100644 --- a/.github/workflows/staleness_check.yml +++ b/.github/workflows/staleness_check.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - branch: [main, 22.x, 23.x, 24.x] + branch: [main, 22.x, 23.x, 24.x, 25.x] os: [{ name: Linux, value: ubuntu-latest}] name: Test staleness ${{ matrix.os.name }} ${{ github.head_ref && 'PR' || matrix.branch }} From 5c252d1f240894a97dab6da3d6b7d3970b6646dc Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 18 Oct 2023 18:27:52 -0700 Subject: [PATCH 35/95] Change upb_Arena_IncRefFor to return error when using an initial block. PiperOrigin-RevId: 574673810 --- upb/mem/arena.c | 6 ++++-- upb/mem/arena.h | 2 +- upb/mem/arena_test.cc | 6 ++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/upb/mem/arena.c b/upb/mem/arena.c index b9d3d9d8f9..43a546a32c 100644 --- a/upb/mem/arena.c +++ b/upb/mem/arena.c @@ -347,8 +347,10 @@ bool upb_Arena_Fuse(upb_Arena* a1, upb_Arena* a2) { } } -void upb_Arena_IncRefFor(upb_Arena* arena, const void* owner) { +bool upb_Arena_IncRefFor(upb_Arena* arena, const void* owner) { _upb_ArenaRoot r; + if (upb_Arena_HasInitialBlock(arena)) return false; + retry: r = _upb_Arena_FindRoot(arena); if (upb_Atomic_CompareExchangeWeak( @@ -357,7 +359,7 @@ retry: _upb_Arena_RefCountFromTagged(r.tagged_count) + 1), memory_order_release, memory_order_acquire)) { // We incremented it successfully, so we are done. - return; + return true; } // We failed update due to parent switching on the arena. goto retry; diff --git a/upb/mem/arena.h b/upb/mem/arena.h index e4afceaa43..1cb9182f4b 100644 --- a/upb/mem/arena.h +++ b/upb/mem/arena.h @@ -47,7 +47,7 @@ UPB_API upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc); UPB_API void upb_Arena_Free(upb_Arena* a); UPB_API bool upb_Arena_Fuse(upb_Arena* a, upb_Arena* b); -void upb_Arena_IncRefFor(upb_Arena* arena, const void* owner); +bool upb_Arena_IncRefFor(upb_Arena* arena, const void* owner); void upb_Arena_DecRefFor(upb_Arena* arena, const void* owner); void* _upb_Arena_SlowMalloc(upb_Arena* a, size_t size); diff --git a/upb/mem/arena_test.cc b/upb/mem/arena_test.cc index 0b13e1a365..444bd0d901 100644 --- a/upb/mem/arena_test.cc +++ b/upb/mem/arena_test.cc @@ -213,6 +213,12 @@ TEST(ArenaTest, FuzzFuseIncRefCountRace) { for (auto& t : threads) t.join(); } +TEST(ArenaTest, IncRefCountShouldFailForInitialBlock) { + char buf1[1024]; + upb_Arena* arena = upb_Arena_Init(buf1, 1024, &upb_alloc_global); + EXPECT_FALSE(upb_Arena_IncRefFor(arena, nullptr)); +} + #endif } // namespace From 90a7de50632854c8b4459609cc33860824c9fc1e Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Wed, 18 Oct 2023 18:30:57 -0700 Subject: [PATCH 36/95] upb: use upb_c_proto_library() instead of upb_proto_library() PiperOrigin-RevId: 574674453 --- benchmarks/BUILD | 6 +++--- protos_generator/tests/BUILD | 4 ++-- upb/conformance/BUILD | 4 ++-- upb/json/BUILD | 6 +++--- upb/message/BUILD | 6 +++--- upb/test/BUILD | 16 ++++++++-------- upb/util/BUILD | 6 +++--- upb_generator/BUILD | 4 ++-- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/benchmarks/BUILD b/benchmarks/BUILD index 07f87a91e7..108eab493f 100644 --- a/benchmarks/BUILD +++ b/benchmarks/BUILD @@ -13,7 +13,7 @@ load("@rules_python//python:defs.bzl", "py_binary") load( "//bazel:upb_proto_library.bzl", - "upb_proto_library", + "upb_c_proto_library", "upb_proto_reflection_library", ) load( @@ -35,7 +35,7 @@ proto_library( srcs = ["descriptor.proto"], ) -upb_proto_library( +upb_c_proto_library( name = "benchmark_descriptor_upb_proto", deps = [":descriptor_proto"], ) @@ -154,7 +154,7 @@ proto_library( ) [( - upb_proto_library( + upb_c_proto_library( name = k + "_upb_proto", deps = [":" + k + "_proto"], ), diff --git a/protos_generator/tests/BUILD b/protos_generator/tests/BUILD index e5c203f229..e4b236626f 100644 --- a/protos_generator/tests/BUILD +++ b/protos_generator/tests/BUILD @@ -11,7 +11,7 @@ load( ) load( "//bazel:upb_proto_library.bzl", - "upb_proto_library", + "upb_c_proto_library", ) load( "//protos/bazel:upb_cc_proto_library.bzl", @@ -60,7 +60,7 @@ proto_library( deps = [":no_package_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "test_model_upb_proto", visibility = [ "//protos:__pkg__", diff --git a/upb/conformance/BUILD b/upb/conformance/BUILD index c22ea41301..18cfc57c14 100644 --- a/upb/conformance/BUILD +++ b/upb/conformance/BUILD @@ -12,7 +12,7 @@ load( ) load( "//bazel:upb_proto_library.bzl", - "upb_proto_library", + "upb_c_proto_library", "upb_proto_reflection_library", ) @@ -28,7 +28,7 @@ config_setting( visibility = ["//visibility:public"], ) -upb_proto_library( +upb_c_proto_library( name = "conformance_upb_proto", testonly = 1, deps = ["//conformance:conformance_proto"], diff --git a/upb/json/BUILD b/upb/json/BUILD index 31840a4f29..b560854f50 100644 --- a/upb/json/BUILD +++ b/upb/json/BUILD @@ -3,7 +3,7 @@ load("//bazel:build_defs.bzl", "UPB_DEFAULT_COPTS") load( "//bazel:upb_proto_library.bzl", - "upb_proto_library", + "upb_c_proto_library", "upb_proto_reflection_library", ) @@ -64,7 +64,7 @@ proto_library( deps = ["//:struct_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "test_upb_proto", testonly = 1, deps = [":test_proto"], @@ -77,7 +77,7 @@ upb_proto_reflection_library( ) # TODO: This target arguably belongs in //google/protobuf/BUILD -upb_proto_library( +upb_c_proto_library( name = "struct_upb_proto", testonly = 1, deps = ["//:struct_proto"], diff --git a/upb/message/BUILD b/upb/message/BUILD index 72a4500e67..22d4ea9319 100644 --- a/upb/message/BUILD +++ b/upb/message/BUILD @@ -12,7 +12,7 @@ load( ) load( "//bazel:upb_proto_library.bzl", - "upb_proto_library", + "upb_c_proto_library", "upb_proto_reflection_library", ) @@ -235,7 +235,7 @@ upb_minitable_proto_library( deps = [":message_test_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "message_test_upb_proto", testonly = 1, deps = [":message_test_proto"], @@ -377,7 +377,7 @@ upb_minitable_proto_library( deps = [":utf8_test_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "utf8_test_upb_proto", testonly = 1, deps = [":utf8_test_proto"], diff --git a/upb/test/BUILD b/upb/test/BUILD index b147e06c08..6ae451d029 100644 --- a/upb/test/BUILD +++ b/upb/test/BUILD @@ -15,7 +15,7 @@ load( ) load( "//bazel:upb_proto_library.bzl", - "upb_proto_library", + "upb_c_proto_library", "upb_proto_reflection_library", ) @@ -52,7 +52,7 @@ proto_library( deps = ["//:descriptor_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "proto3_test_upb_proto", testonly = 1, deps = [":proto3_test_proto"], @@ -77,7 +77,7 @@ upb_minitable_proto_library( deps = [":test_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "test_upb_proto", testonly = 1, visibility = ["//upb:__subpackages__"], @@ -90,7 +90,7 @@ proto_library( deps = ["//:timestamp_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "test_cpp_upb_proto", deps = ["test_cpp_proto"], ) @@ -114,21 +114,21 @@ upb_minitable_proto_library( deps = ["//src/google/protobuf:test_messages_proto3_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "test_messages_proto2_upb_proto", testonly = 1, visibility = ["//upb:__subpackages__"], deps = ["//src/google/protobuf:test_messages_proto2_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "test_messages_proto3_upb_proto", testonly = 1, visibility = ["//upb:__subpackages__"], deps = ["//src/google/protobuf:test_messages_proto3_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "timestamp_upb_proto", deps = ["//:timestamp_proto"], ) @@ -252,7 +252,7 @@ upb_minitable_proto_library( deps = [":test_import_empty_srcs_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "test_import_empty_srcs_upb_proto", testonly = 1, deps = [":test_import_empty_srcs_proto"], diff --git a/upb/util/BUILD b/upb/util/BUILD index 1abbaf070f..f15f351017 100644 --- a/upb/util/BUILD +++ b/upb/util/BUILD @@ -1,6 +1,6 @@ load( "//bazel:upb_proto_library.bzl", - "upb_proto_library", + "upb_c_proto_library", "upb_proto_reflection_library", ) @@ -33,7 +33,7 @@ proto_library( ], ) -upb_proto_library( +upb_c_proto_library( name = "def_to_proto_test_upb_proto", deps = ["def_to_proto_test_proto"], ) @@ -110,7 +110,7 @@ proto_library( srcs = ["required_fields_test.proto"], ) -upb_proto_library( +upb_c_proto_library( name = "required_fields_test_upb_proto", deps = ["required_fields_test_proto"], ) diff --git a/upb_generator/BUILD b/upb_generator/BUILD index bf0a1b9143..79f2ac3649 100644 --- a/upb_generator/BUILD +++ b/upb_generator/BUILD @@ -16,7 +16,7 @@ load( ) load( "//bazel:upb_proto_library.bzl", - "upb_proto_library", + "upb_c_proto_library", "upb_proto_reflection_library", ) load( @@ -39,7 +39,7 @@ proto_library( deps = ["//:compiler_plugin_proto"], ) -upb_proto_library( +upb_c_proto_library( name = "code_generator_request_upb_proto", visibility = ["//upb:friends"], deps = [":code_generator_request"], From 1fb26f229bcb571f74e533cbdc9b78cd7138ae6d Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 19 Oct 2023 01:48:15 +0000 Subject: [PATCH 37/95] Auto-generate files after cl/574673810 --- php/ext/google/protobuf/php-upb.c | 6 ++++-- php/ext/google/protobuf/php-upb.h | 2 +- ruby/ext/google/protobuf_c/ruby-upb.c | 6 ++++-- ruby/ext/google/protobuf_c/ruby-upb.h | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 0c4bbfb484..f999768b48 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -5803,8 +5803,10 @@ bool upb_Arena_Fuse(upb_Arena* a1, upb_Arena* a2) { } } -void upb_Arena_IncRefFor(upb_Arena* arena, const void* owner) { +bool upb_Arena_IncRefFor(upb_Arena* arena, const void* owner) { _upb_ArenaRoot r; + if (upb_Arena_HasInitialBlock(arena)) return false; + retry: r = _upb_Arena_FindRoot(arena); if (upb_Atomic_CompareExchangeWeak( @@ -5813,7 +5815,7 @@ retry: _upb_Arena_RefCountFromTagged(r.tagged_count) + 1), memory_order_release, memory_order_acquire)) { // We incremented it successfully, so we are done. - return; + return true; } // We failed update due to parent switching on the arena. goto retry; diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index ec91368750..b0621443ed 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -561,7 +561,7 @@ UPB_API upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc); UPB_API void upb_Arena_Free(upb_Arena* a); UPB_API bool upb_Arena_Fuse(upb_Arena* a, upb_Arena* b); -void upb_Arena_IncRefFor(upb_Arena* arena, const void* owner); +bool upb_Arena_IncRefFor(upb_Arena* arena, const void* owner); void upb_Arena_DecRefFor(upb_Arena* arena, const void* owner); void* _upb_Arena_SlowMalloc(upb_Arena* a, size_t size); diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index 902c9c71a6..8790a0e32d 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -5318,8 +5318,10 @@ bool upb_Arena_Fuse(upb_Arena* a1, upb_Arena* a2) { } } -void upb_Arena_IncRefFor(upb_Arena* arena, const void* owner) { +bool upb_Arena_IncRefFor(upb_Arena* arena, const void* owner) { _upb_ArenaRoot r; + if (upb_Arena_HasInitialBlock(arena)) return false; + retry: r = _upb_Arena_FindRoot(arena); if (upb_Atomic_CompareExchangeWeak( @@ -5328,7 +5330,7 @@ retry: _upb_Arena_RefCountFromTagged(r.tagged_count) + 1), memory_order_release, memory_order_acquire)) { // We incremented it successfully, so we are done. - return; + return true; } // We failed update due to parent switching on the arena. goto retry; diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index c4be0d71dd..9393812f7e 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -563,7 +563,7 @@ UPB_API upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc); UPB_API void upb_Arena_Free(upb_Arena* a); UPB_API bool upb_Arena_Fuse(upb_Arena* a, upb_Arena* b); -void upb_Arena_IncRefFor(upb_Arena* arena, const void* owner); +bool upb_Arena_IncRefFor(upb_Arena* arena, const void* owner); void upb_Arena_DecRefFor(upb_Arena* arena, const void* owner); void* _upb_Arena_SlowMalloc(upb_Arena* a, size_t size); From e098e9216f021d684f83dbe8e5098a0f87c5cf31 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 19 Oct 2023 08:20:09 -0700 Subject: [PATCH 38/95] Move `GetTypeName` implementation into `ClassData`. For LITE messages we append the type name to the data, avoiding an indirection and a relocation. For descriptor messages we have a single secondary vtable. This reduces the per-message cost of all the descriptor methods to a single pointer. PiperOrigin-RevId: 574877986 --- src/google/protobuf/compiler/cpp/message.cc | 114 ++-- src/google/protobuf/compiler/cpp/message.h | 1 + .../compiler/java/java_features.pb.cc | 17 +- .../protobuf/compiler/java/java_features.pb.h | 4 +- src/google/protobuf/compiler/plugin.pb.cc | 68 ++- src/google/protobuf/compiler/plugin.pb.h | 16 +- src/google/protobuf/cpp_features.pb.cc | 17 +- src/google/protobuf/cpp_features.pb.h | 4 +- src/google/protobuf/descriptor.pb.cc | 544 ++++++++++-------- src/google/protobuf/descriptor.pb.h | 128 ++--- .../protobuf/generated_message_bases.cc | 7 +- src/google/protobuf/implicit_weak_message.h | 9 +- src/google/protobuf/message.cc | 25 +- src/google/protobuf/message.h | 10 +- src/google/protobuf/message_lite.cc | 21 +- src/google/protobuf/message_lite.h | 17 +- 16 files changed, 572 insertions(+), 430 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 20c8f33a5d..184d83d16b 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -1603,26 +1603,20 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { break; } + if (!HasSimpleBaseClass(descriptor_, options_)) { + p->Emit(R"cc( + const ::$proto_ns$::MessageLite::ClassData* GetClassData() const final; + )cc"); + } + format( "public:\n" "\n"); if (HasDescriptorMethods(descriptor_->file(), options_)) { - if (HasGeneratedMethods(descriptor_->file(), options_) && - !HasSimpleBaseClass(descriptor_, options_)) { - format( - "static const ClassData _class_data_;\n" - "const ::$proto_ns$::Message::ClassData*" - "GetClassData() const final;\n" - "\n"); - } format( "::$proto_ns$::Metadata GetMetadata() const final;\n" "\n"); - } else { - format( - "std::string GetTypeName() const final;\n" - "\n"); } if (ShouldSplit(descriptor_, options_)) { @@ -2049,6 +2043,8 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { format("\n"); } + GenerateClassData(p); + if (HasGeneratedMethods(descriptor_->file(), options_)) { GenerateClear(p); format("\n"); @@ -2124,12 +2120,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { "}\n", index_in_file_messages_); } - } else { - format( - "std::string $classname$::GetTypeName() const {\n" - " return \"$full_name$\";\n" - "}\n" - "\n"); } if (HasTracker(descriptor_, options_)) { @@ -3587,21 +3577,27 @@ void MessageGenerator::GenerateSwap(io::Printer* p) { format("}\n"); } -void MessageGenerator::GenerateMergeFrom(io::Printer* p) { +void MessageGenerator::GenerateClassData(io::Printer* p) { Formatter format(p); if (HasSimpleBaseClass(descriptor_, options_)) return; - if (HasDescriptorMethods(descriptor_->file(), options_)) { - // We don't override the generalized MergeFrom (aka that which - // takes in the Message base class as a parameter); instead we just - // let the base Message::MergeFrom take care of it. The base MergeFrom - // knows how to quickly confirm the types exactly match, and if so, will - // use GetClassData() to retrieve the address of MergeImpl, which calls - // the fast MergeFrom overload. Most callers avoid all this by passing - // a "from" message that is the same type as the message being merged - // into, rather than a generic Message. + const auto class_data_members = [&] { p->Emit( { + {"merge_impl", + [&] { + // TODO: This check is not needed once we migrate + // CheckTypeAndMergeFrom to ClassData fully. + if (HasDescriptorMethods(descriptor_->file(), options_)) { + p->Emit(R"cc( + $classname$::MergeImpl, + )cc"); + } else { + p->Emit(R"cc( + nullptr, // MergeImpl + )cc"); + } + }}, {"on_demand_register_arena_dtor", [&] { if (NeedsArenaDestructor() == ArenaDtorNeeds::kOnDemand) { @@ -3614,17 +3610,67 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* p) { )cc"); } }}, + {"descriptor_methods", + [&] { + if (HasDescriptorMethods(descriptor_->file(), options_)) { + p->Emit(R"cc( + &::$proto_ns$::Message::kDescriptorMethods, + )cc"); + } else { + p->Emit(R"cc( + nullptr, // DescriptorMethods + )cc"); + } + }}, }, R"cc( - const ::$proto_ns$::Message::ClassData $classname$::_class_data_ = { - $classname$::MergeImpl, - $on_demand_register_arena_dtor$, - }; - const ::$proto_ns$::Message::ClassData* $classname$::GetClassData() const { - return &_class_data_; + $merge_impl$, $on_demand_register_arena_dtor$, $descriptor_methods$, + )cc"); + }; + + if (HasDescriptorMethods(descriptor_->file(), options_)) { + p->Emit( + {{"class_data_members", class_data_members}}, + R"cc( + const ::$proto_ns$::MessageLite::ClassData* + $classname$::GetClassData() const { + PROTOBUF_CONSTINIT static const ::$proto_ns$::MessageLite::ClassData + data = { + $class_data_members$, + }; + return &data; } )cc"); } else { + p->Emit( + { + {"class_data_members", class_data_members}, + {"type_size", descriptor_->full_name().size() + 1}, + }, + R"cc( + const ::$proto_ns$::MessageLite::ClassData* + $classname$::GetClassData() const { + struct ClassData_ { + ::$proto_ns$::MessageLite::ClassData header; + char type_name[$type_size$]; + }; + PROTOBUF_CONSTINIT static const ClassData_ data = { + { + $class_data_members$, + }, + "$full_name$", + }; + + return &data.header; + } + )cc"); + } +} + +void MessageGenerator::GenerateMergeFrom(io::Printer* p) { + Formatter format(p); + + if (!HasDescriptorMethods(descriptor_->file(), options_)) { // Generate CheckTypeAndMergeFrom(). format( "void $classname$::CheckTypeAndMergeFrom(\n" diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index 894650f829..26843ec412 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -117,6 +117,7 @@ class MessageGenerator { void GenerateSerializeWithCachedSizesBody(io::Printer* p); void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* p); void GenerateByteSize(io::Printer* p); + void GenerateClassData(io::Printer* p); void GenerateMergeFrom(io::Printer* p); void GenerateClassSpecificMergeImpl(io::Printer* p); void GenerateCopyFrom(io::Printer* p); diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc index e3dac1672b..309375292d 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.cc +++ b/src/google/protobuf/compiler/java/java_features.pb.cc @@ -196,6 +196,16 @@ inline void JavaFeatures::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +JavaFeatures::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + JavaFeatures::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void JavaFeatures::Clear() { // @@protoc_insertion_point(message_clear_start:pb.JavaFeatures) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -312,13 +322,6 @@ const ::_pbi::TcParseTable<1, 2, 1, 0, 2> JavaFeatures::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData JavaFeatures::_class_data_ = { - JavaFeatures::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* JavaFeatures::GetClassData() const { - return &_class_data_; -} void JavaFeatures::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/compiler/java/java_features.pb.h b/src/google/protobuf/compiler/java/java_features.pb.h index 66c51efb87..1a0c7bba2e 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.h +++ b/src/google/protobuf/compiler/java/java_features.pb.h @@ -224,11 +224,9 @@ class PROTOC_EXPORT JavaFeatures final : protected: explicit JavaFeatures(::google::protobuf::Arena* arena); JavaFeatures(::google::protobuf::Arena* arena, const JavaFeatures& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 8b8084c62f..06e403cc6e 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -381,6 +381,16 @@ inline void Version::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Version::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Version::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Version::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.Version) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -543,13 +553,6 @@ const ::_pbi::TcParseTable<2, 4, 0, 47, 2> Version::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Version::_class_data_ = { - Version::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Version::GetClassData() const { - return &_class_data_; -} void Version::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -695,6 +698,16 @@ inline void CodeGeneratorRequest::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +CodeGeneratorRequest::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + CodeGeneratorRequest::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void CodeGeneratorRequest::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -887,13 +900,6 @@ const ::_pbi::TcParseTable<3, 5, 3, 79, 2> CodeGeneratorRequest::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData CodeGeneratorRequest::_class_data_ = { - CodeGeneratorRequest::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* CodeGeneratorRequest::GetClassData() const { - return &_class_data_; -} void CodeGeneratorRequest::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1043,6 +1049,16 @@ inline void CodeGeneratorResponse_File::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +CodeGeneratorResponse_File::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + CodeGeneratorResponse_File::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void CodeGeneratorResponse_File::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse.File) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1216,13 +1232,6 @@ const ::_pbi::TcParseTable<2, 4, 1, 86, 2> CodeGeneratorResponse_File::_table_ = return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData CodeGeneratorResponse_File::_class_data_ = { - CodeGeneratorResponse_File::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* CodeGeneratorResponse_File::GetClassData() const { - return &_class_data_; -} void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1345,6 +1354,16 @@ inline void CodeGeneratorResponse::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +CodeGeneratorResponse::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + CodeGeneratorResponse::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void CodeGeneratorResponse::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1487,13 +1506,6 @@ const ::_pbi::TcParseTable<2, 3, 1, 60, 2> CodeGeneratorResponse::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData CodeGeneratorResponse::_class_data_ = { - CodeGeneratorResponse::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* CodeGeneratorResponse::GetClassData() const { - return &_class_data_; -} void CodeGeneratorResponse::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 1a2c568124..eb3da21003 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -241,11 +241,9 @@ class PROTOC_EXPORT Version final : protected: explicit Version(::google::protobuf::Arena* arena); Version(::google::protobuf::Arena* arena, const Version& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -463,11 +461,9 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : protected: explicit CodeGeneratorResponse_File(::google::protobuf::Arena* arena); CodeGeneratorResponse_File(::google::protobuf::Arena* arena, const CodeGeneratorResponse_File& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -701,11 +697,9 @@ class PROTOC_EXPORT CodeGeneratorResponse final : protected: explicit CodeGeneratorResponse(::google::protobuf::Arena* arena); CodeGeneratorResponse(::google::protobuf::Arena* arena, const CodeGeneratorResponse& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -940,11 +934,9 @@ class PROTOC_EXPORT CodeGeneratorRequest final : protected: explicit CodeGeneratorRequest(::google::protobuf::Arena* arena); CodeGeneratorRequest(::google::protobuf::Arena* arena, const CodeGeneratorRequest& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc index 762c63077a..b7eee1a5fa 100644 --- a/src/google/protobuf/cpp_features.pb.cc +++ b/src/google/protobuf/cpp_features.pb.cc @@ -157,6 +157,16 @@ inline void CppFeatures::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +CppFeatures::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + CppFeatures::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void CppFeatures::Clear() { // @@protoc_insertion_point(message_clear_start:pb.CppFeatures) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -247,13 +257,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> CppFeatures::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData CppFeatures::_class_data_ = { - CppFeatures::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* CppFeatures::GetClassData() const { - return &_class_data_; -} void CppFeatures::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/cpp_features.pb.h b/src/google/protobuf/cpp_features.pb.h index fddd800989..3b470431e3 100644 --- a/src/google/protobuf/cpp_features.pb.h +++ b/src/google/protobuf/cpp_features.pb.h @@ -193,11 +193,9 @@ class PROTOBUF_EXPORT CppFeatures final : protected: explicit CppFeatures(::google::protobuf::Arena* arena); CppFeatures(::google::protobuf::Arena* arena, const CppFeatures& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index ce7e962bf4..ae02aa9a2d 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -2396,6 +2396,16 @@ inline void FileDescriptorSet::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FileDescriptorSet::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FileDescriptorSet::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FileDescriptorSet::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -2484,13 +2494,6 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> FileDescriptorSet::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FileDescriptorSet::_class_data_ = { - FileDescriptorSet::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FileDescriptorSet::GetClassData() const { - return &_class_data_; -} void FileDescriptorSet::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -2647,6 +2650,16 @@ inline void FileDescriptorProto::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FileDescriptorProto::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FileDescriptorProto::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FileDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -3025,13 +3038,6 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 79, 2> FileDescriptorProto::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FileDescriptorProto::_class_data_ = { - FileDescriptorProto::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FileDescriptorProto::GetClassData() const { - return &_class_data_; -} void FileDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -3214,6 +3220,16 @@ inline void DescriptorProto_ExtensionRange::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +DescriptorProto_ExtensionRange::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + DescriptorProto_ExtensionRange::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void DescriptorProto_ExtensionRange::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -3354,13 +3370,6 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 0, 2> DescriptorProto_ExtensionRange::_t return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData DescriptorProto_ExtensionRange::_class_data_ = { - DescriptorProto_ExtensionRange::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* DescriptorProto_ExtensionRange::GetClassData() const { - return &_class_data_; -} void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -3470,6 +3479,16 @@ inline void DescriptorProto_ReservedRange::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +DescriptorProto_ReservedRange::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + DescriptorProto_ReservedRange::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void DescriptorProto_ReservedRange::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -3586,13 +3605,6 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 0, 2> DescriptorProto_ReservedRange::_ta return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData DescriptorProto_ReservedRange::_class_data_ = { - DescriptorProto_ReservedRange::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* DescriptorProto_ReservedRange::GetClassData() const { - return &_class_data_; -} void DescriptorProto_ReservedRange::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -3731,6 +3743,16 @@ inline void DescriptorProto::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +DescriptorProto::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + DescriptorProto::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void DescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -4037,13 +4059,6 @@ constexpr ::_pbi::TcParseTable<4, 10, 8, 65, 2> DescriptorProto::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData DescriptorProto::_class_data_ = { - DescriptorProto::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* DescriptorProto::GetClassData() const { - return &_class_data_; -} void DescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -4217,6 +4232,16 @@ inline void ExtensionRangeOptions_Declaration::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +ExtensionRangeOptions_Declaration::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + ExtensionRangeOptions_Declaration::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void ExtensionRangeOptions_Declaration::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions.Declaration) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -4405,13 +4430,6 @@ constexpr ::_pbi::TcParseTable<3, 5, 0, 71, 2> ExtensionRangeOptions_Declaration return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData ExtensionRangeOptions_Declaration::_class_data_ = { - ExtensionRangeOptions_Declaration::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* ExtensionRangeOptions_Declaration::GetClassData() const { - return &_class_data_; -} void ExtensionRangeOptions_Declaration::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -4553,6 +4571,16 @@ inline void ExtensionRangeOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +ExtensionRangeOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + ExtensionRangeOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void ExtensionRangeOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -4727,13 +4755,6 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData ExtensionRangeOptions::_class_data_ = { - ExtensionRangeOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* ExtensionRangeOptions::GetClassData() const { - return &_class_data_; -} void ExtensionRangeOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -4926,6 +4947,16 @@ inline void FieldDescriptorProto::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FieldDescriptorProto::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FieldDescriptorProto::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FieldDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -5257,13 +5288,6 @@ constexpr ::_pbi::TcParseTable<4, 11, 3, 96, 2> FieldDescriptorProto::_table_ = return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FieldDescriptorProto::_class_data_ = { - FieldDescriptorProto::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FieldDescriptorProto::GetClassData() const { - return &_class_data_; -} void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -5427,6 +5451,16 @@ inline void OneofDescriptorProto::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +OneofDescriptorProto::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + OneofDescriptorProto::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void OneofDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -5551,13 +5585,6 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 49, 2> OneofDescriptorProto::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData OneofDescriptorProto::_class_data_ = { - OneofDescriptorProto::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* OneofDescriptorProto::GetClassData() const { - return &_class_data_; -} void OneofDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -5661,6 +5688,16 @@ inline void EnumDescriptorProto_EnumReservedRange::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +EnumDescriptorProto_EnumReservedRange::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + EnumDescriptorProto_EnumReservedRange::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void EnumDescriptorProto_EnumReservedRange::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -5777,13 +5814,6 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 0, 2> EnumDescriptorProto_EnumReservedRa return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData EnumDescriptorProto_EnumReservedRange::_class_data_ = { - EnumDescriptorProto_EnumReservedRange::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* EnumDescriptorProto_EnumReservedRange::GetClassData() const { - return &_class_data_; -} void EnumDescriptorProto_EnumReservedRange::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -5912,6 +5942,16 @@ inline void EnumDescriptorProto::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +EnumDescriptorProto::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + EnumDescriptorProto::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void EnumDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -6105,13 +6145,6 @@ constexpr ::_pbi::TcParseTable<3, 5, 3, 61, 2> EnumDescriptorProto::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData EnumDescriptorProto::_class_data_ = { - EnumDescriptorProto::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* EnumDescriptorProto::GetClassData() const { - return &_class_data_; -} void EnumDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -6254,6 +6287,16 @@ inline void EnumValueDescriptorProto::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +EnumValueDescriptorProto::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + EnumValueDescriptorProto::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void EnumValueDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -6399,13 +6442,6 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 53, 2> EnumValueDescriptorProto::_table_ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData EnumValueDescriptorProto::_class_data_ = { - EnumValueDescriptorProto::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* EnumValueDescriptorProto::GetClassData() const { - return &_class_data_; -} void EnumValueDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -6540,6 +6576,16 @@ inline void ServiceDescriptorProto::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +ServiceDescriptorProto::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + ServiceDescriptorProto::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void ServiceDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -6687,13 +6733,6 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 51, 2> ServiceDescriptorProto::_table_ = return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData ServiceDescriptorProto::_class_data_ = { - ServiceDescriptorProto::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* ServiceDescriptorProto::GetClassData() const { - return &_class_data_; -} void ServiceDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -6852,6 +6891,16 @@ inline void MethodDescriptorProto::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +MethodDescriptorProto::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + MethodDescriptorProto::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void MethodDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -7065,13 +7114,6 @@ constexpr ::_pbi::TcParseTable<3, 6, 1, 71, 2> MethodDescriptorProto::_table_ = return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData MethodDescriptorProto::_class_data_ = { - MethodDescriptorProto::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* MethodDescriptorProto::GetClassData() const { - return &_class_data_; -} void MethodDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -7318,6 +7360,16 @@ inline void FileOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FileOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FileOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FileOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -7891,13 +7943,6 @@ constexpr ::_pbi::TcParseTable<5, 22, 3, 202, 12> FileOptions::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FileOptions::_class_data_ = { - FileOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FileOptions::GetClassData() const { - return &_class_data_; -} void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -8134,6 +8179,16 @@ inline void MessageOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +MessageOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + MessageOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void MessageOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -8352,13 +8407,6 @@ constexpr ::_pbi::TcParseTable<3, 7, 2, 0, 7> MessageOptions::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData MessageOptions::_class_data_ = { - MessageOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* MessageOptions::GetClassData() const { - return &_class_data_; -} void MessageOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -8499,6 +8547,16 @@ inline void FieldOptions_EditionDefault::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FieldOptions_EditionDefault::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FieldOptions_EditionDefault::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FieldOptions_EditionDefault::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions.EditionDefault) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -8618,13 +8676,6 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 57, 2> FieldOptions_EditionDefault::_tab return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FieldOptions_EditionDefault::_class_data_ = { - FieldOptions_EditionDefault::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FieldOptions_EditionDefault::GetClassData() const { - return &_class_data_; -} void FieldOptions_EditionDefault::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -8787,6 +8838,16 @@ inline void FieldOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FieldOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FieldOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FieldOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -9140,13 +9201,6 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 0, 7> FieldOptions::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FieldOptions::_class_data_ = { - FieldOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FieldOptions::GetClassData() const { - return &_class_data_; -} void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -9314,6 +9368,16 @@ inline void OneofOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +OneofOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + OneofOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void OneofOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -9440,13 +9504,6 @@ constexpr ::_pbi::TcParseTable<2, 2, 2, 0, 7> OneofOptions::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData OneofOptions::_class_data_ = { - OneofOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* OneofOptions::GetClassData() const { - return &_class_data_; -} void OneofOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -9591,6 +9648,16 @@ inline void EnumOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +EnumOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + EnumOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void EnumOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -9775,13 +9842,6 @@ constexpr ::_pbi::TcParseTable<3, 5, 2, 0, 7> EnumOptions::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData EnumOptions::_class_data_ = { - EnumOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* EnumOptions::GetClassData() const { - return &_class_data_; -} void EnumOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -9941,6 +10001,16 @@ inline void EnumValueOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +EnumValueOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + EnumValueOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void EnumValueOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -10110,13 +10180,6 @@ constexpr ::_pbi::TcParseTable<3, 4, 2, 0, 7> EnumValueOptions::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData EnumValueOptions::_class_data_ = { - EnumValueOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* EnumValueOptions::GetClassData() const { - return &_class_data_; -} void EnumValueOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -10264,6 +10327,16 @@ inline void ServiceOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +ServiceOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + ServiceOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void ServiceOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -10411,13 +10484,6 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 0, 12> ServiceOptions::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData ServiceOptions::_class_data_ = { - ServiceOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* ServiceOptions::GetClassData() const { - return &_class_data_; -} void ServiceOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -10571,6 +10637,16 @@ inline void MethodOptions::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +MethodOptions::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + MethodOptions::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void MethodOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -10745,13 +10821,6 @@ constexpr ::_pbi::TcParseTable<3, 4, 3, 0, 12> MethodOptions::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData MethodOptions::_class_data_ = { - MethodOptions::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* MethodOptions::GetClassData() const { - return &_class_data_; -} void MethodOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -10886,6 +10955,16 @@ inline void UninterpretedOption_NamePart::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +UninterpretedOption_NamePart::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + UninterpretedOption_NamePart::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void UninterpretedOption_NamePart::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -11004,13 +11083,6 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 62, 2> UninterpretedOption_NamePart::_ta return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData UninterpretedOption_NamePart::_class_data_ = { - UninterpretedOption_NamePart::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* UninterpretedOption_NamePart::GetClassData() const { - return &_class_data_; -} void UninterpretedOption_NamePart::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -11157,6 +11229,16 @@ inline void UninterpretedOption::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +UninterpretedOption::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + UninterpretedOption::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void UninterpretedOption::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -11386,13 +11468,6 @@ constexpr ::_pbi::TcParseTable<3, 7, 1, 75, 2> UninterpretedOption::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData UninterpretedOption::_class_data_ = { - UninterpretedOption::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* UninterpretedOption::GetClassData() const { - return &_class_data_; -} void UninterpretedOption::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -11552,6 +11627,16 @@ inline void FeatureSet::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FeatureSet::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FeatureSet::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FeatureSet::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSet) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -11757,13 +11842,6 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FeatureSet::_class_data_ = { - FeatureSet::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FeatureSet::GetClassData() const { - return &_class_data_; -} void FeatureSet::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -11906,6 +11984,16 @@ inline void FeatureSetDefaults_FeatureSetEditionDefault::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FeatureSetDefaults_FeatureSetEditionDefault::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FeatureSetDefaults_FeatureSetEditionDefault::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -12023,13 +12111,6 @@ constexpr ::_pbi::TcParseTable<1, 2, 2, 0, 2> FeatureSetDefaults_FeatureSetEditi return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FeatureSetDefaults_FeatureSetEditionDefault::_class_data_ = { - FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FeatureSetDefaults_FeatureSetEditionDefault::GetClassData() const { - return &_class_data_; -} void FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -12158,6 +12239,16 @@ inline void FeatureSetDefaults::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FeatureSetDefaults::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FeatureSetDefaults::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FeatureSetDefaults::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSetDefaults) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -12294,13 +12385,6 @@ constexpr ::_pbi::TcParseTable<1, 3, 3, 0, 2> FeatureSetDefaults::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FeatureSetDefaults::_class_data_ = { - FeatureSetDefaults::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FeatureSetDefaults::GetClassData() const { - return &_class_data_; -} void FeatureSetDefaults::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -12431,6 +12515,16 @@ inline void SourceCodeInfo_Location::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +SourceCodeInfo_Location::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + SourceCodeInfo_Location::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void SourceCodeInfo_Location::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -12639,13 +12733,6 @@ constexpr ::_pbi::TcParseTable<3, 5, 0, 106, 2> SourceCodeInfo_Location::_table_ return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData SourceCodeInfo_Location::_class_data_ = { - SourceCodeInfo_Location::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* SourceCodeInfo_Location::GetClassData() const { - return &_class_data_; -} void SourceCodeInfo_Location::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -12750,6 +12837,16 @@ inline void SourceCodeInfo::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +SourceCodeInfo::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + SourceCodeInfo::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void SourceCodeInfo::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -12838,13 +12935,6 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> SourceCodeInfo::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData SourceCodeInfo::_class_data_ = { - SourceCodeInfo::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* SourceCodeInfo::GetClassData() const { - return &_class_data_; -} void SourceCodeInfo::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -12966,6 +13056,16 @@ inline void GeneratedCodeInfo_Annotation::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +GeneratedCodeInfo_Annotation::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + GeneratedCodeInfo_Annotation::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void GeneratedCodeInfo_Annotation::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -13159,13 +13259,6 @@ constexpr ::_pbi::TcParseTable<3, 5, 1, 64, 2> GeneratedCodeInfo_Annotation::_ta return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData GeneratedCodeInfo_Annotation::_class_data_ = { - GeneratedCodeInfo_Annotation::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* GeneratedCodeInfo_Annotation::GetClassData() const { - return &_class_data_; -} void GeneratedCodeInfo_Annotation::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -13278,6 +13371,16 @@ inline void GeneratedCodeInfo::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +GeneratedCodeInfo::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + GeneratedCodeInfo::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void GeneratedCodeInfo::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -13366,13 +13469,6 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> GeneratedCodeInfo::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData GeneratedCodeInfo::_class_data_ = { - GeneratedCodeInfo::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* GeneratedCodeInfo::GetClassData() const { - return &_class_data_; -} void GeneratedCodeInfo::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 6367994ea9..ea38e1f3d0 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -822,11 +822,9 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : protected: explicit UninterpretedOption_NamePart(::google::protobuf::Arena* arena); UninterpretedOption_NamePart(::google::protobuf::Arena* arena, const UninterpretedOption_NamePart& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1018,11 +1016,9 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : protected: explicit SourceCodeInfo_Location(::google::protobuf::Arena* arena); SourceCodeInfo_Location(::google::protobuf::Arena* arena, const SourceCodeInfo_Location& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1292,11 +1288,9 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : protected: explicit GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena); GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena, const GeneratedCodeInfo_Annotation& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1556,11 +1550,9 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : protected: explicit FieldOptions_EditionDefault(::google::protobuf::Arena* arena); FieldOptions_EditionDefault(::google::protobuf::Arena* arena, const FieldOptions_EditionDefault& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1752,11 +1744,9 @@ class PROTOBUF_EXPORT FeatureSet final : protected: explicit FeatureSet(::google::protobuf::Arena* arena); FeatureSet(::google::protobuf::Arena* arena, const FeatureSet& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -2300,11 +2290,9 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : protected: explicit ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena); ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena, const ExtensionRangeOptions_Declaration& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -2541,11 +2529,9 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : protected: explicit EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena); EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena, const EnumDescriptorProto_EnumReservedRange& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -2731,11 +2717,9 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : protected: explicit DescriptorProto_ReservedRange(::google::protobuf::Arena* arena); DescriptorProto_ReservedRange(::google::protobuf::Arena* arena, const DescriptorProto_ReservedRange& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -2921,11 +2905,9 @@ class PROTOBUF_EXPORT UninterpretedOption final : protected: explicit UninterpretedOption(::google::protobuf::Arena* arena); UninterpretedOption(::google::protobuf::Arena* arena, const UninterpretedOption& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -3203,11 +3185,9 @@ class PROTOBUF_EXPORT SourceCodeInfo final : protected: explicit SourceCodeInfo(::google::protobuf::Arena* arena); SourceCodeInfo(::google::protobuf::Arena* arena, const SourceCodeInfo& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -3388,11 +3368,9 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : protected: explicit GeneratedCodeInfo(::google::protobuf::Arena* arena); GeneratedCodeInfo(::google::protobuf::Arena* arena, const GeneratedCodeInfo& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -3573,11 +3551,9 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : protected: explicit FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena); FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena, const FeatureSetDefaults_FeatureSetEditionDefault& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -3767,11 +3743,9 @@ class PROTOBUF_EXPORT ServiceOptions final : protected: explicit ServiceOptions(::google::protobuf::Arena* arena); ServiceOptions(::google::protobuf::Arena* arena, const ServiceOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -4160,11 +4134,9 @@ class PROTOBUF_EXPORT OneofOptions final : protected: explicit OneofOptions(::google::protobuf::Arena* arena); OneofOptions(::google::protobuf::Arena* arena, const OneofOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -4540,11 +4512,9 @@ class PROTOBUF_EXPORT MethodOptions final : protected: explicit MethodOptions(::google::protobuf::Arena* arena); MethodOptions(::google::protobuf::Arena* arena, const MethodOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -4967,11 +4937,9 @@ class PROTOBUF_EXPORT MessageOptions final : protected: explicit MessageOptions(::google::protobuf::Arena* arena); MessageOptions(::google::protobuf::Arena* arena, const MessageOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -5412,11 +5380,9 @@ class PROTOBUF_EXPORT FileOptions final : protected: explicit FileOptions(::google::protobuf::Arena* arena); FileOptions(::google::protobuf::Arena* arena, const FileOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -6133,11 +6099,9 @@ class PROTOBUF_EXPORT FieldOptions final : protected: explicit FieldOptions(::google::protobuf::Arena* arena); FieldOptions(::google::protobuf::Arena* arena, const FieldOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -6764,11 +6728,9 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : protected: explicit FeatureSetDefaults(::google::protobuf::Arena* arena); FeatureSetDefaults(::google::protobuf::Arena* arena, const FeatureSetDefaults& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -6976,11 +6938,9 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : protected: explicit ExtensionRangeOptions(::google::protobuf::Arena* arena); ExtensionRangeOptions(::google::protobuf::Arena* arena, const ExtensionRangeOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -7411,11 +7371,9 @@ class PROTOBUF_EXPORT EnumValueOptions final : protected: explicit EnumValueOptions(::google::protobuf::Arena* arena); EnumValueOptions(::google::protobuf::Arena* arena, const EnumValueOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -7817,11 +7775,9 @@ class PROTOBUF_EXPORT EnumOptions final : protected: explicit EnumOptions(::google::protobuf::Arena* arena); EnumOptions(::google::protobuf::Arena* arena, const EnumOptions& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -8236,11 +8192,9 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : protected: explicit OneofDescriptorProto(::google::protobuf::Arena* arena); OneofDescriptorProto(::google::protobuf::Arena* arena, const OneofDescriptorProto& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -8436,11 +8390,9 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : protected: explicit MethodDescriptorProto(::google::protobuf::Arena* arena); MethodDescriptorProto(::google::protobuf::Arena* arena, const MethodDescriptorProto& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -8700,11 +8652,9 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : protected: explicit FieldDescriptorProto(::google::protobuf::Arena* arena); FieldDescriptorProto(::google::protobuf::Arena* arena, const FieldDescriptorProto& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -9098,11 +9048,9 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : protected: explicit EnumValueDescriptorProto(::google::protobuf::Arena* arena); EnumValueDescriptorProto(::google::protobuf::Arena* arena, const EnumValueDescriptorProto& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -9311,11 +9259,9 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : protected: explicit DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena); DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena, const DescriptorProto_ExtensionRange& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -9518,11 +9464,9 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : protected: explicit ServiceDescriptorProto(::google::protobuf::Arena* arena); ServiceDescriptorProto(::google::protobuf::Arena* arena, const ServiceDescriptorProto& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -9738,11 +9682,9 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : protected: explicit EnumDescriptorProto(::google::protobuf::Arena* arena); EnumDescriptorProto(::google::protobuf::Arena* arena, const EnumDescriptorProto& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -10010,11 +9952,9 @@ class PROTOBUF_EXPORT DescriptorProto final : protected: explicit DescriptorProto(::google::protobuf::Arena* arena); DescriptorProto(::google::protobuf::Arena* arena, const DescriptorProto& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -10383,11 +10323,9 @@ class PROTOBUF_EXPORT FileDescriptorProto final : protected: explicit FileDescriptorProto(::google::protobuf::Arena* arena); FileDescriptorProto(::google::protobuf::Arena* arena, const FileDescriptorProto& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -10801,11 +10739,9 @@ class PROTOBUF_EXPORT FileDescriptorSet final : protected: explicit FileDescriptorSet(::google::protobuf::Arena* arena); FileDescriptorSet(::google::protobuf::Arena* arena, const FileDescriptorSet& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/generated_message_bases.cc b/src/google/protobuf/generated_message_bases.cc index 319a0ae681..5821ac6157 100644 --- a/src/google/protobuf/generated_message_bases.cc +++ b/src/google/protobuf/generated_message_bases.cc @@ -7,6 +7,7 @@ #include "google/protobuf/generated_message_bases.h" +#include "google/protobuf/generated_message_reflection.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/zero_copy_stream_impl.h" #include "google/protobuf/parse_context.h" @@ -95,7 +96,11 @@ void ZeroFieldsBase::InternalSwap(ZeroFieldsBase* other) { } const Message::ClassData* ZeroFieldsBase::GetClassData() const { - static constexpr ClassData data = {&MergeImpl}; + static constexpr ClassData data = { + &MergeImpl, + nullptr, + &kDescriptorMethods, + }; return &data; } diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h index 170155a2c9..0428d9eb32 100644 --- a/src/google/protobuf/implicit_weak_message.h +++ b/src/google/protobuf/implicit_weak_message.h @@ -56,7 +56,14 @@ class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { static const ImplicitWeakMessage* default_instance(); - std::string GetTypeName() const override { return ""; } + const ClassData* GetClassData() const final { + struct Data { + ClassData header; + char name[1]; + }; + static constexpr Data data = {{}, ""}; + return &data.header; + } MessageLite* New(Arena* arena) const override { return Arena::CreateMessage(arena); diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index b4b1a40c51..a28bd9b770 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -58,6 +58,10 @@ using internal::ReflectionOps; using internal::WireFormat; using internal::WireFormatLite; +void Message::MergeImpl(Message& to, const Message& from) { + ReflectionOps::Merge(from, &to); +} + void Message::MergeFrom(const Message& from) { auto* class_to = GetClassData(); auto* class_from = from.GetClassData(); @@ -70,6 +74,15 @@ void Message::MergeFrom(const Message& from) { merge_to_from(*this, from); } +const MessageLite::ClassData* Message::GetClassData() const { + static constexpr ClassData data = { + &MergeImpl, + nullptr, + &kDescriptorMethods, + }; + return &data; +} + void Message::CheckTypeAndMergeFrom(const MessageLite& other) { MergeFrom(*DownCast(&other)); } @@ -99,10 +112,6 @@ void Message::CopyFrom(const Message& from) { } } -std::string Message::GetTypeName() const { - return GetDescriptor()->full_name(); -} - void Message::Clear() { ReflectionOps::Clear(this); } bool Message::IsInitialized() const { @@ -182,6 +191,14 @@ size_t Message::SpaceUsedLong() const { return GetReflection()->SpaceUsedLong(*this); } +static std::string GetTypeNameImpl(const MessageLite& msg) { + return DownCast(msg).GetDescriptor()->full_name(); +} + +constexpr MessageLite::DescriptorMethods Message::kDescriptorMethods = { + GetTypeNameImpl, +}; + namespace internal { void* CreateSplitMessageGeneric(Arena* arena, const void* default_split, size_t size, const void* message, diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 1fb5368a23..9d38c634b9 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -330,7 +330,6 @@ class PROTOBUF_EXPORT Message : public MessageLite { // These methods are pure-virtual in MessageLite, but Message provides // reflection-based default implementations. - std::string GetTypeName() const override; void Clear() override; // Returns whether all required fields have been set. Note that required @@ -370,6 +369,15 @@ class PROTOBUF_EXPORT Message : public MessageLite { size_t MaybeComputeUnknownFieldsSize(size_t total_size, internal::CachedSize* cached_size) const; + // Reflection based version for reflection based types. + static void MergeImpl(Message& to, const Message& from); + + static const DescriptorMethods kDescriptorMethods; + + // Default implementation using reflection. Avoids bloat in MapEntry. + // Generated types will make their own. + const ClassData* GetClassData() const override; + }; namespace internal { diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 4505222763..390852b903 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -44,18 +44,29 @@ namespace google { namespace protobuf { +std::string MessageLite::GetTypeName() const { + auto* data = GetClassData(); + ABSL_DCHECK(data != nullptr); + + if (data->descriptor_methods != nullptr) { + // For !LITE messages, we use the descriptor method function. + return data->descriptor_methods->get_type_name(*this); + } + + // For LITE messages, the type name is a char[] just beyond ClassData. + return reinterpret_cast(data) + sizeof(ClassData); +} + void MessageLite::OnDemandRegisterArenaDtor(Arena* arena) { if (arena == nullptr) return; auto* data = GetClassData(); - if (data != nullptr && data->on_demand_register_arena_dtor != nullptr) { + ABSL_DCHECK(data != nullptr); + + if (data->on_demand_register_arena_dtor != nullptr) { data->on_demand_register_arena_dtor(*this, *arena); } } -const MessageLite::ClassData* MessageLite::GetClassData() const { - return nullptr; -} - std::string MessageLite::InitializationErrorString() const { return "(cannot determine missing fields for lite message)"; } diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index f8e1167c34..f0c16316ed 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -211,7 +211,7 @@ class PROTOBUF_EXPORT MessageLite { // Basic Operations ------------------------------------------------ // Get the name of this message type, e.g. "foo.bar.BazProto". - virtual std::string GetTypeName() const = 0; + std::string GetTypeName() const; // Construct a new instance of the same type. Ownership is passed to the // caller. @@ -518,12 +518,21 @@ class PROTOBUF_EXPORT MessageLite { // of this message or its internal memory could be changed. Arena* GetOwningArena() const { return _internal_metadata_.arena(); } + // We use a secondary vtable for descriptor based methods. This way ClassData + // does not growth with the number of descriptor methods. This avoids extra + // costs in MessageLite. + struct DescriptorMethods { + std::string (*get_type_name)(const MessageLite&); + }; struct ClassData { // Note: The order of arguments in the functions is chosen so that it has // the same ABI as the member function that calls them. Eg the `this` // pointer becomes the first argument in the free function. void (*merge_to_from)(Message& to, const Message& from_msg); void (*on_demand_register_arena_dtor)(MessageLite& msg, Arena& arena); + // LITE objects (ie !descriptor_methods) collocate their name as a + // char[] just beyond the ClassData. + const DescriptorMethods* descriptor_methods; }; // GetClassData() returns a pointer to a ClassData struct which @@ -531,9 +540,9 @@ class PROTOBUF_EXPORT MessageLite { // property is used in order to quickly determine whether two messages are // of the same type. // - // This is a work in progress. Currently only SPEED messages return an - // instance. In the future all message types will return one. - virtual const ClassData* GetClassData() const; + // This is a work in progress. There are still some types (eg MapEntry) that + // return a default table instead of a unique one. + virtual const ClassData* GetClassData() const = 0; internal::InternalMetadata _internal_metadata_; From e134c2cbb71fe132c2c28c9bb1faf8cdf53d3912 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 19 Oct 2023 15:45:51 +0000 Subject: [PATCH 39/95] Auto-generate files after cl/574877986 --- src/google/protobuf/any.pb.cc | 17 +-- src/google/protobuf/any.pb.h | 4 +- src/google/protobuf/api.pb.cc | 51 ++++---- src/google/protobuf/api.pb.h | 12 +- src/google/protobuf/duration.pb.cc | 17 +-- src/google/protobuf/duration.pb.h | 4 +- src/google/protobuf/field_mask.pb.cc | 17 +-- src/google/protobuf/field_mask.pb.h | 4 +- src/google/protobuf/source_context.pb.cc | 17 +-- src/google/protobuf/source_context.pb.h | 4 +- src/google/protobuf/struct.pb.cc | 51 ++++---- src/google/protobuf/struct.pb.h | 12 +- src/google/protobuf/timestamp.pb.cc | 17 +-- src/google/protobuf/timestamp.pb.h | 4 +- src/google/protobuf/type.pb.cc | 85 +++++++------ src/google/protobuf/type.pb.h | 20 +-- src/google/protobuf/wrappers.pb.cc | 153 +++++++++++++---------- src/google/protobuf/wrappers.pb.h | 36 ++---- 18 files changed, 275 insertions(+), 250 deletions(-) diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index e864f9d8d4..429b41c6f8 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -195,6 +195,16 @@ inline void Any::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Any::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Any::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Any::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Any) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -306,13 +316,6 @@ const ::_pbi::TcParseTable<1, 2, 0, 36, 2> Any::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Any::_class_data_ = { - Any::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Any::GetClassData() const { - return &_class_data_; -} void Any::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 0e1d77b3bd..f6eecf8cd5 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -226,11 +226,9 @@ class PROTOBUF_EXPORT Any final : protected: explicit Any(::google::protobuf::Arena* arena); Any(::google::protobuf::Arena* arena, const Any& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 2a4e891c56..773786a15b 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -332,6 +332,16 @@ inline void Api::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Api::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Api::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Api::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Api) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -560,13 +570,6 @@ const ::_pbi::TcParseTable<3, 7, 4, 39, 2> Api::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Api::_class_data_ = { - Api::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Api::GetClassData() const { - return &_class_data_; -} void Api::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -710,6 +713,16 @@ inline void Method::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Method::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Method::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Method::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Method) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -926,13 +939,6 @@ const ::_pbi::TcParseTable<3, 7, 1, 68, 2> Method::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Method::_class_data_ = { - Method::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Method::GetClassData() const { - return &_class_data_; -} void Method::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1053,6 +1059,16 @@ inline void Mixin::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Mixin::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Mixin::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Mixin::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1167,13 +1183,6 @@ const ::_pbi::TcParseTable<1, 2, 0, 38, 2> Mixin::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Mixin::_class_data_ = { - Mixin::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Mixin::GetClassData() const { - return &_class_data_; -} void Mixin::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 92dbccec85..08d2f8addf 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -199,11 +199,9 @@ class PROTOBUF_EXPORT Mixin final : protected: explicit Mixin(::google::protobuf::Arena* arena); Mixin(::google::protobuf::Arena* arena, const Mixin& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -398,11 +396,9 @@ class PROTOBUF_EXPORT Method final : protected: explicit Method(::google::protobuf::Arena* arena); Method(::google::protobuf::Arena* arena, const Method& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -671,11 +667,9 @@ class PROTOBUF_EXPORT Api final : protected: explicit Api(::google::protobuf::Arena* arena); Api(::google::protobuf::Arena* arena, const Api& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index 90237e4cfe..a3838bdfa3 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -159,6 +159,16 @@ inline void Duration::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Duration::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Duration::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Duration::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Duration) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -268,13 +278,6 @@ const ::_pbi::TcParseTable<1, 2, 0, 0, 2> Duration::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Duration::_class_data_ = { - Duration::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Duration::GetClassData() const { - return &_class_data_; -} void Duration::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 2f79454e5f..3a7539d2a3 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -191,11 +191,9 @@ class PROTOBUF_EXPORT Duration final : protected: explicit Duration(::google::protobuf::Arena* arena); Duration(::google::protobuf::Arena* arena, const Duration& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index 0eeae84950..2c6c5badc2 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -165,6 +165,16 @@ inline void FieldMask::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FieldMask::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FieldMask::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FieldMask::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -257,13 +267,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 39, 2> FieldMask::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FieldMask::_class_data_ = { - FieldMask::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FieldMask::GetClassData() const { - return &_class_data_; -} void FieldMask::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index 787e47152e..e4d6dca8a2 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -191,11 +191,9 @@ class PROTOBUF_EXPORT FieldMask final : protected: explicit FieldMask(::google::protobuf::Arena* arena); FieldMask(::google::protobuf::Arena* arena, const FieldMask& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index 82c89ed22a..b93bf206fa 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -168,6 +168,16 @@ inline void SourceContext::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +SourceContext::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + SourceContext::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void SourceContext::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceContext) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -260,13 +270,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 47, 2> SourceContext::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData SourceContext::_class_data_ = { - SourceContext::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* SourceContext::GetClassData() const { - return &_class_data_; -} void SourceContext::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 51b0402123..ed58fe7fcf 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -191,11 +191,9 @@ class PROTOBUF_EXPORT SourceContext final : protected: explicit SourceContext(::google::protobuf::Arena* arena); SourceContext(::google::protobuf::Arena* arena, const SourceContext& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index fe6ca61ca3..cb8e5c9736 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -286,6 +286,16 @@ inline void Struct::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Struct::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Struct::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Struct::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Struct) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -400,13 +410,6 @@ const ::_pbi::TcParseTable<0, 1, 2, 37, 2> Struct::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Struct::_class_data_ = { - Struct::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Struct::GetClassData() const { - return &_class_data_; -} void Struct::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -596,6 +599,16 @@ void Value::clear_kind() { } +const ::google::protobuf::MessageLite::ClassData* +Value::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Value::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Value) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -768,13 +781,6 @@ const ::_pbi::TcParseTable<0, 6, 2, 42, 2> Value::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Value::_class_data_ = { - Value::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Value::GetClassData() const { - return &_class_data_; -} void Value::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -892,6 +898,16 @@ inline void ListValue::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +ListValue::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + ListValue::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void ListValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -981,13 +997,6 @@ const ::_pbi::TcParseTable<0, 1, 1, 0, 2> ListValue::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData ListValue::_class_data_ = { - ListValue::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* ListValue::GetClassData() const { - return &_class_data_; -} void ListValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 40010b95ba..6f9c7d176e 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -236,11 +236,9 @@ class PROTOBUF_EXPORT ListValue final : protected: explicit ListValue(::google::protobuf::Arena* arena); ListValue(::google::protobuf::Arena* arena, const ListValue& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -419,11 +417,9 @@ class PROTOBUF_EXPORT Struct final : protected: explicit Struct(::google::protobuf::Arena* arena); Struct(::google::protobuf::Arena* arena, const Struct& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -641,11 +637,9 @@ class PROTOBUF_EXPORT Value final : protected: explicit Value(::google::protobuf::Arena* arena); Value(::google::protobuf::Arena* arena, const Value& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 4cb535e7b3..e048cb8c30 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -159,6 +159,16 @@ inline void Timestamp::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Timestamp::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Timestamp::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Timestamp::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Timestamp) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -268,13 +278,6 @@ const ::_pbi::TcParseTable<1, 2, 0, 0, 2> Timestamp::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Timestamp::_class_data_ = { - Timestamp::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Timestamp::GetClassData() const { - return &_class_data_; -} void Timestamp::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index aa31472f5f..8c1d97196e 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -191,11 +191,9 @@ class PROTOBUF_EXPORT Timestamp final : protected: explicit Timestamp(::google::protobuf::Arena* arena); Timestamp(::google::protobuf::Arena* arena, const Timestamp& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 29bae8b957..29884227e7 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -512,6 +512,16 @@ inline void Type::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Type::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Type::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Type::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Type) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -740,13 +750,6 @@ const ::_pbi::TcParseTable<3, 7, 3, 46, 2> Type::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Type::_class_data_ = { - Type::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Type::GetClassData() const { - return &_class_data_; -} void Type::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -888,6 +891,16 @@ inline void Field::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Field::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Field::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Field::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Field) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1170,13 +1183,6 @@ const ::_pbi::TcParseTable<4, 10, 1, 72, 2> Field::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Field::_class_data_ = { - Field::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Field::GetClassData() const { - return &_class_data_; -} void Field::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1339,6 +1345,16 @@ inline void Enum::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Enum::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Enum::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Enum::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Enum) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1546,13 +1562,6 @@ const ::_pbi::TcParseTable<3, 6, 3, 40, 2> Enum::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Enum::_class_data_ = { - Enum::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Enum::GetClassData() const { - return &_class_data_; -} void Enum::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1672,6 +1681,16 @@ inline void EnumValue::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +EnumValue::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + EnumValue::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void EnumValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValue) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1806,13 +1825,6 @@ const ::_pbi::TcParseTable<2, 3, 1, 38, 2> EnumValue::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData EnumValue::_class_data_ = { - EnumValue::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* EnumValue::GetClassData() const { - return &_class_data_; -} void EnumValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1933,6 +1945,16 @@ inline void Option::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Option::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Option::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Option::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Option) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -2052,13 +2074,6 @@ const ::_pbi::TcParseTable<1, 2, 1, 35, 2> Option::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Option::_class_data_ = { - Option::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Option::GetClassData() const { - return &_class_data_; -} void Option::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index 0ae554ccfb..489cbdd116 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -325,11 +325,9 @@ class PROTOBUF_EXPORT Option final : protected: explicit Option(::google::protobuf::Arena* arena); Option(::google::protobuf::Arena* arena, const Option& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -524,11 +522,9 @@ class PROTOBUF_EXPORT Field final : protected: explicit Field(::google::protobuf::Arena* arena); Field(::google::protobuf::Arena* arena, const Field& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -898,11 +894,9 @@ class PROTOBUF_EXPORT EnumValue final : protected: explicit EnumValue(::google::protobuf::Arena* arena); EnumValue(::google::protobuf::Arena* arena, const EnumValue& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1111,11 +1105,9 @@ class PROTOBUF_EXPORT Type final : protected: explicit Type(::google::protobuf::Arena* arena); Type(::google::protobuf::Arena* arena, const Type& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1410,11 +1402,9 @@ class PROTOBUF_EXPORT Enum final : protected: explicit Enum(::google::protobuf::Arena* arena); Enum(::google::protobuf::Arena* arena, const Enum& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index 95244fc650..cf7efbb562 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -402,6 +402,16 @@ inline void DoubleValue::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +DoubleValue::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + DoubleValue::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void DoubleValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DoubleValue) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -499,13 +509,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> DoubleValue::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData DoubleValue::_class_data_ = { - DoubleValue::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* DoubleValue::GetClassData() const { - return &_class_data_; -} void DoubleValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -586,6 +589,16 @@ inline void FloatValue::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +FloatValue::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + FloatValue::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void FloatValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FloatValue) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -683,13 +696,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> FloatValue::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData FloatValue::_class_data_ = { - FloatValue::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* FloatValue::GetClassData() const { - return &_class_data_; -} void FloatValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -770,6 +776,16 @@ inline void Int64Value::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Int64Value::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Int64Value::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Int64Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Int64Value) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -858,13 +874,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> Int64Value::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Int64Value::_class_data_ = { - Int64Value::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Int64Value::GetClassData() const { - return &_class_data_; -} void Int64Value::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -940,6 +949,16 @@ inline void UInt64Value::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +UInt64Value::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + UInt64Value::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void UInt64Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UInt64Value) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1028,13 +1047,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> UInt64Value::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData UInt64Value::_class_data_ = { - UInt64Value::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* UInt64Value::GetClassData() const { - return &_class_data_; -} void UInt64Value::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1110,6 +1122,16 @@ inline void Int32Value::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +Int32Value::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + Int32Value::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void Int32Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Int32Value) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1198,13 +1220,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> Int32Value::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData Int32Value::_class_data_ = { - Int32Value::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* Int32Value::GetClassData() const { - return &_class_data_; -} void Int32Value::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1280,6 +1295,16 @@ inline void UInt32Value::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +UInt32Value::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + UInt32Value::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void UInt32Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UInt32Value) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1368,13 +1393,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> UInt32Value::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData UInt32Value::_class_data_ = { - UInt32Value::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* UInt32Value::GetClassData() const { - return &_class_data_; -} void UInt32Value::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1450,6 +1468,16 @@ inline void BoolValue::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +BoolValue::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + BoolValue::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void BoolValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.BoolValue) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1537,13 +1565,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> BoolValue::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData BoolValue::_class_data_ = { - BoolValue::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* BoolValue::GetClassData() const { - return &_class_data_; -} void BoolValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1633,6 +1654,16 @@ inline void StringValue::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +StringValue::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + StringValue::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void StringValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.StringValue) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1725,13 +1756,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 41, 2> StringValue::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData StringValue::_class_data_ = { - StringValue::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* StringValue::GetClassData() const { - return &_class_data_; -} void StringValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); @@ -1823,6 +1847,16 @@ inline void BytesValue::SharedDtor() { _impl_.~Impl_(); } +const ::google::protobuf::MessageLite::ClassData* +BytesValue::GetClassData() const { + PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData + data = { + BytesValue::MergeImpl, + nullptr, // OnDemandRegisterArenaDtor + &::google::protobuf::Message::kDescriptorMethods, + }; + return &data; +} PROTOBUF_NOINLINE void BytesValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.BytesValue) PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); @@ -1910,13 +1944,6 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> BytesValue::_table_ = { return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -const ::google::protobuf::Message::ClassData BytesValue::_class_data_ = { - BytesValue::MergeImpl, - nullptr, // OnDemandRegisterArenaDtor -}; -const ::google::protobuf::Message::ClassData* BytesValue::GetClassData() const { - return &_class_data_; -} void BytesValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 4491ed9874..78d3c718f1 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -215,11 +215,9 @@ class PROTOBUF_EXPORT UInt64Value final : protected: explicit UInt64Value(::google::protobuf::Arena* arena); UInt64Value(::google::protobuf::Arena* arena, const UInt64Value& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -390,11 +388,9 @@ class PROTOBUF_EXPORT UInt32Value final : protected: explicit UInt32Value(::google::protobuf::Arena* arena); UInt32Value(::google::protobuf::Arena* arena, const UInt32Value& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -565,11 +561,9 @@ class PROTOBUF_EXPORT StringValue final : protected: explicit StringValue(::google::protobuf::Arena* arena); StringValue(::google::protobuf::Arena* arena, const StringValue& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -746,11 +740,9 @@ class PROTOBUF_EXPORT Int64Value final : protected: explicit Int64Value(::google::protobuf::Arena* arena); Int64Value(::google::protobuf::Arena* arena, const Int64Value& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -921,11 +913,9 @@ class PROTOBUF_EXPORT Int32Value final : protected: explicit Int32Value(::google::protobuf::Arena* arena); Int32Value(::google::protobuf::Arena* arena, const Int32Value& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1096,11 +1086,9 @@ class PROTOBUF_EXPORT FloatValue final : protected: explicit FloatValue(::google::protobuf::Arena* arena); FloatValue(::google::protobuf::Arena* arena, const FloatValue& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1271,11 +1259,9 @@ class PROTOBUF_EXPORT DoubleValue final : protected: explicit DoubleValue(::google::protobuf::Arena* arena); DoubleValue(::google::protobuf::Arena* arena, const DoubleValue& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1446,11 +1432,9 @@ class PROTOBUF_EXPORT BytesValue final : protected: explicit BytesValue(::google::protobuf::Arena* arena); BytesValue(::google::protobuf::Arena* arena, const BytesValue& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -1627,11 +1611,9 @@ class PROTOBUF_EXPORT BoolValue final : protected: explicit BoolValue(::google::protobuf::Arena* arena); BoolValue(::google::protobuf::Arena* arena, const BoolValue& from); + const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; public: - static const ClassData _class_data_; - const ::google::protobuf::Message::ClassData*GetClassData() const final; - ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- From 287374e5eb76a3feb12a8d156d61ca16d1e68b93 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 19 Oct 2023 08:53:42 -0700 Subject: [PATCH 40/95] Replace try-catch Blocks with assertThrows() in GeneratedMessageTest PiperOrigin-RevId: 574887696 --- .../google/protobuf/GeneratedMessageTest.java | 383 ++++++++---------- 1 file changed, 159 insertions(+), 224 deletions(-) diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java index dbe3072fb7..86f2bb43b8 100644 --- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java @@ -9,6 +9,7 @@ package com.google.protobuf; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertThrows; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; @@ -213,28 +214,28 @@ public class GeneratedMessageTest { @Test public void testGetExtensionFieldOutOfBound() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); - try { - builder.getRepeatedField(UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0); - assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); - } catch (IndexOutOfBoundsException expected) { - } - try { - builder.getExtension(UnittestProto.repeatedNestedMessageExtension, 0); - assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); - } catch (IndexOutOfBoundsException expected) { - } + + assertThrows( + "Expected IndexOutOfBoundsException to be thrown", + IndexOutOfBoundsException.class, + () -> + builder.getRepeatedField( + UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0)); + assertThrows( + "Expected IndexOutOfBoundsException to be thrown", + IndexOutOfBoundsException.class, + () -> builder.getExtension(UnittestProto.repeatedNestedMessageExtension, 0)); TestAllExtensions extensionsMessage = builder.build(); - try { - extensionsMessage.getRepeatedField( - UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0); - assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); - } catch (IndexOutOfBoundsException expected) { - } - try { - extensionsMessage.getExtension(UnittestProto.repeatedNestedMessageExtension, 0); - assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); - } catch (IndexOutOfBoundsException expected) { - } + assertThrows( + "Expected IndexOutOfBoundsException to be thrown", + IndexOutOfBoundsException.class, + () -> + extensionsMessage.getRepeatedField( + UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0)); + assertThrows( + "Expected IndexOutOfBoundsException to be thrown", + IndexOutOfBoundsException.class, + () -> extensionsMessage.getExtension(UnittestProto.repeatedNestedMessageExtension, 0)); } @Test @@ -365,78 +366,51 @@ public class GeneratedMessageTest { if (list == Collections.emptyList()) { // OKAY -- Need to check this b/c EmptyList allows you to call clear. } else { - try { - list.clear(); - assertWithMessage("List wasn't immutable").fail(); - } catch (UnsupportedOperationException e) { - // good - } + assertThrows( + "List wasn't immutable", UnsupportedOperationException.class, () -> list.clear()); } } @Test public void testSettersRejectNull() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - try { - builder.setOptionalString(null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.setOptionalBytes(null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.setOptionalNestedMessage((TestAllTypes.NestedMessage.Builder) null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.setOptionalNestedEnum(null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.addRepeatedString(null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.addRepeatedBytes(null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage.Builder) null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.addRepeatedNestedEnum(null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } + + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setOptionalString(null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setOptionalNestedMessage((TestAllTypes.NestedMessage.Builder) null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setOptionalNestedEnum(null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.addRepeatedString(null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.addRepeatedBytes(null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage.Builder) null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.addRepeatedNestedEnum(null)); } @Test @@ -454,45 +428,35 @@ public class GeneratedMessageTest { builder.addRepeatedString("one"); builder.addRepeatedString("two"); - try { - builder.setRepeatedString(1, null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setRepeatedString(1, null)); builder.addRepeatedBytes(TestUtil.toBytes("one")); builder.addRepeatedBytes(TestUtil.toBytes("two")); - try { - builder.setRepeatedBytes(1, null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setRepeatedBytes(1, null)); builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(218).build()); builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(456).build()); - try { - builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - try { - builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage.Builder) null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null)); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage.Builder) null)); builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO); builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR); - try { - builder.setRepeatedNestedEnum(1, null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.setRepeatedNestedEnum(1, null)); } @Test @@ -518,33 +482,24 @@ public class GeneratedMessageTest { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); ForeignMessage foreignMessage = ForeignMessage.newBuilder().setC(12).build(); - try { - builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage, (ForeignMessage) null)); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - - try { - builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ, null)); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - - try { - builder.addAllRepeatedString(Arrays.asList("one", null)); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } - - try { - builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null)); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> + builder.addAllRepeatedForeignMessage( + Arrays.asList(foreignMessage, (ForeignMessage) null))); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ, null))); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.addAllRepeatedString(Arrays.asList("one", null))); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null))); } @Test @@ -570,23 +525,19 @@ public class GeneratedMessageTest { assertThat(builder.getRepeatedString(1)).isEqualTo("two"); assertThat(builder.getRepeatedString(2)).isEqualTo("three"); - try { - builder.addAllRepeatedString(stringIterable); - assertWithMessage("Exception was not thrown").fail(); - } catch (IllegalStateException e) { - // We expect this exception. - } + assertThrows( + "Exception was not thrown", + IllegalStateException.class, + () -> builder.addAllRepeatedString(stringIterable)); } @Test public void testMergeFromOtherRejectsNull() throws Exception { - try { - TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - builder.mergeFrom((TestAllTypes) null); - assertWithMessage("Exception was not thrown").fail(); - } catch (NullPointerException e) { - // We expect this exception. - } + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + assertThrows( + "Exception was not thrown", + NullPointerException.class, + () -> builder.mergeFrom((TestAllTypes) null)); } @Test @@ -781,13 +732,11 @@ public class GeneratedMessageTest { @Test public void testGetBuilderForNonMessageExtensionField() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); - try { - // This should throw an exception because the extension field is not a message. - builder.newBuilderForField(UnittestProto.optionalInt32Extension.getDescriptor()); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // This exception is expected. - } + // This should throw an exception because the extension field is not a message. + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> builder.newBuilderForField(UnittestProto.optionalInt32Extension.getDescriptor())); } @Test @@ -1388,36 +1337,26 @@ public class GeneratedMessageTest { public void testGetFieldBuilderNotSupportedException() { Descriptor descriptor = TestAllTypes.getDescriptor(); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - try { - builder.getFieldBuilder(descriptor.findFieldByName("optional_int32")); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } - try { - builder.getFieldBuilder(descriptor.findFieldByName("optional_nested_enum")); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } - try { - builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32")); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } - try { - builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_enum")); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } - try { - builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_message")); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> builder.getFieldBuilder(descriptor.findFieldByName("optional_int32"))); + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> builder.getFieldBuilder(descriptor.findFieldByName("optional_nested_enum"))); + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32"))); + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_enum"))); + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_message"))); } // Test that when the default outer class name conflicts with another type @@ -1873,42 +1812,38 @@ public class GeneratedMessageTest { public void testGetRepeatedFieldBuilderNotSupportedException() { Descriptor descriptor = TestAllTypes.getDescriptor(); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - try { - builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_int32"), 0); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } - try { - builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_nested_enum"), 0); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } - try { - builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_int32"), 0); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } - try { - builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_nested_enum"), 0); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } - try { - builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_nested_message"), 0); - assertWithMessage("Exception was not thrown").fail(); - } catch (UnsupportedOperationException e) { - // We expect this exception. - } + + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_int32"), 0)); + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> + builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_nested_enum"), 0)); + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_int32"), 0)); + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> + builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_nested_enum"), 0)); + assertThrows( + "Exception was not thrown", + UnsupportedOperationException.class, + () -> + builder.getRepeatedFieldBuilder( + descriptor.findFieldByName("optional_nested_message"), 0)); } private static final FieldDescriptor OPTIONAL_NESTED_MESSAGE_EXTENSION = UnittestProto.getDescriptor().findExtensionByName("optional_nested_message_extension"); private static final FieldDescriptor REPEATED_NESTED_MESSAGE_EXTENSION = UnittestProto.getDescriptor().findExtensionByName("repeated_nested_message_extension"); + // A compile-time check that TestAllExtensions.Builder does in fact extend // GeneratedMessageV3.ExtendableBuilder. The tests below assume that it does. static { From 2690017b169e7f28cfa845c8bafdb9149f21473c Mon Sep 17 00:00:00 2001 From: Hong Shin Date: Thu, 19 Oct 2023 09:21:18 -0700 Subject: [PATCH 41/95] cleanup upb.rs We shouldn't give easy access to the zeroed block, so let's pass in pbi::private to deter misuse. Also saw that arena wasn't used mutably in a repeatedfield test, so let mut -> let; PiperOrigin-RevId: 574896460 --- rust/upb.rs | 4 ++-- .../protobuf/compiler/rust/accessors/singular_message.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/upb.rs b/rust/upb.rs index 57f9c5512b..24edbce347 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -150,7 +150,7 @@ const UPB_SCRATCH_SPACE_BYTES: usize = 64_000; /// with readonly access. pub struct ScratchSpace; impl ScratchSpace { - pub fn zeroed_block() -> RawMessage { + pub fn zeroed_block(_private: Private) -> RawMessage { unsafe { INIT.call_once(|| { let layout = @@ -455,7 +455,7 @@ mod tests { #[test] fn i32_array() { - let mut arena = Arena::new(); + let arena = Arena::new(); let mut arr = RepeatedField::::new(&arena); assert_eq!(arr.len(), 0); arr.push(1); diff --git a/src/google/protobuf/compiler/rust/accessors/singular_message.cc b/src/google/protobuf/compiler/rust/accessors/singular_message.cc index 7c3d3adbe3..2978631faf 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_message.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_message.cc @@ -51,7 +51,7 @@ void SingularMessage::InMsgImpl(Context field) const { // a null ptr received from upb manifests as Option::None match submsg { // TODO:(b/304357029) - None => $prefix$View::new($pbi$::Private, $pbr$::ScratchSpace::zeroed_block()), + None => $prefix$View::new($pbi$::Private, $pbr$::ScratchSpace::zeroed_block($pbi$::Private)), Some(field) => $prefix$View::new($pbi$::Private, field), } } From 1b7615905fc03996f1cdabc80291c624706795d6 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 19 Oct 2023 14:01:15 -0700 Subject: [PATCH 42/95] Move `InitializationErrorString` into the secondary vtable, retrieved from `ClassData`. This removes one virtual function from MessageLite with zero per-type increase. PiperOrigin-RevId: 574994142 --- src/google/protobuf/message.cc | 5 +++++ src/google/protobuf/message.h | 2 +- src/google/protobuf/message_lite.cc | 8 ++++++++ src/google/protobuf/message_lite.h | 3 ++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index a28bd9b770..eb81694daf 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -195,8 +195,13 @@ static std::string GetTypeNameImpl(const MessageLite& msg) { return DownCast(msg).GetDescriptor()->full_name(); } +static std::string InitializationErrorStringImpl(const MessageLite& msg) { + return DownCast(msg).InitializationErrorString(); +} + constexpr MessageLite::DescriptorMethods Message::kDescriptorMethods = { GetTypeNameImpl, + InitializationErrorStringImpl, }; namespace internal { diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 9d38c634b9..83ba793e93 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -271,7 +271,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // Like FindInitializationErrors, but joins all the strings, delimited by // commas, and returns them. - std::string InitializationErrorString() const override; + std::string InitializationErrorString() const; // Clears all unknown fields from this message and all embedded messages. // Normally, if unknown tag numbers are encountered when parsing a message, diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 390852b903..12ee82f4ca 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -68,6 +68,14 @@ void MessageLite::OnDemandRegisterArenaDtor(Arena* arena) { } std::string MessageLite::InitializationErrorString() const { + auto* data = GetClassData(); + ABSL_DCHECK(data != nullptr); + + if (data->descriptor_methods != nullptr) { + // For !LITE messages, we use the descriptor method function. + return data->descriptor_methods->initialization_error_string(*this); + } + return "(cannot determine missing fields for lite message)"; } diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index f0c16316ed..6d3b93432b 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -235,7 +235,7 @@ class PROTOBUF_EXPORT MessageLite { // This is not implemented for Lite messages -- it just returns "(cannot // determine missing fields for lite message)". However, it is implemented // for full messages. See message.h. - virtual std::string InitializationErrorString() const; + std::string InitializationErrorString() const; // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, // results are undefined (probably crash). @@ -523,6 +523,7 @@ class PROTOBUF_EXPORT MessageLite { // costs in MessageLite. struct DescriptorMethods { std::string (*get_type_name)(const MessageLite&); + std::string (*initialization_error_string)(const MessageLite&); }; struct ClassData { // Note: The order of arguments in the functions is chosen so that it has From d617c032217d017ad10119e17ee533c15b8a27d9 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 19 Oct 2023 14:40:00 -0700 Subject: [PATCH 43/95] Internal change. PiperOrigin-RevId: 575006343 --- src/google/protobuf/text_format.cc | 64 ++++++++++++++++-- src/google/protobuf/text_format_unittest.cc | 72 +++++++++------------ 2 files changed, 88 insertions(+), 48 deletions(-) diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index f5df44215a..9abd84772a 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -2769,7 +2769,12 @@ void TextFormat::Printer::PrintUnknownFields( case UnknownField::TYPE_VARINT: OutOfLinePrintString(generator, field.number()); generator->PrintMaybeWithMarker(MarkerToken(), ": "); - OutOfLinePrintString(generator, field.varint()); + if (redact_debug_string_) { + OutOfLinePrintString(generator, "UNKNOWN_VARINT "); + OutOfLinePrintString(generator, kFieldValueReplacement); + } else { + OutOfLinePrintString(generator, field.varint()); + } if (single_line_mode_) { generator->PrintLiteral(" "); } else { @@ -2778,9 +2783,15 @@ void TextFormat::Printer::PrintUnknownFields( break; case UnknownField::TYPE_FIXED32: { OutOfLinePrintString(generator, field.number()); - generator->PrintMaybeWithMarker(MarkerToken(), ": ", "0x"); - OutOfLinePrintString(generator, - absl::Hex(field.fixed32(), absl::kZeroPad8)); + if (redact_debug_string_) { + generator->PrintMaybeWithMarker(MarkerToken(), ": ", + "UNKNOWN_FIXED32 "); + OutOfLinePrintString(generator, kFieldValueReplacement); + } else { + generator->PrintMaybeWithMarker(MarkerToken(), ": ", "0x"); + OutOfLinePrintString(generator, + absl::Hex(field.fixed32(), absl::kZeroPad8)); + } if (single_line_mode_) { generator->PrintLiteral(" "); } else { @@ -2790,9 +2801,15 @@ void TextFormat::Printer::PrintUnknownFields( } case UnknownField::TYPE_FIXED64: { OutOfLinePrintString(generator, field.number()); - generator->PrintMaybeWithMarker(MarkerToken(), ": ", "0x"); - OutOfLinePrintString(generator, - absl::Hex(field.fixed64(), absl::kZeroPad16)); + if (redact_debug_string_) { + generator->PrintMaybeWithMarker(MarkerToken(), ": ", + "UNKNOWN_FIXED64 "); + OutOfLinePrintString(generator, kFieldValueReplacement); + } else { + generator->PrintMaybeWithMarker(MarkerToken(), ": ", "0x"); + OutOfLinePrintString(generator, + absl::Hex(field.fixed64(), absl::kZeroPad16)); + } if (single_line_mode_) { generator->PrintLiteral(" "); } else { @@ -2814,6 +2831,17 @@ void TextFormat::Printer::PrintUnknownFields( embedded_unknown_fields.ParseFromCodedStream(&input_stream)) { // This field is parseable as a Message. // So it is probably an embedded message. + if (redact_debug_string_) { + generator->PrintMaybeWithMarker(MarkerToken(), ": ", + "UNKNOWN_MESSAGE "); + OutOfLinePrintString(generator, kFieldValueReplacement); + if (single_line_mode_) { + generator->PrintLiteral(" "); + } else { + generator->PrintLiteral("\n"); + } + break; + } if (single_line_mode_) { generator->PrintMaybeWithMarker(MarkerToken(), " ", "{ "); } else { @@ -2831,6 +2859,17 @@ void TextFormat::Printer::PrintUnknownFields( } else { // This field is not parseable as a Message (or we ran out of // recursion budget). So it is probably just a plain string. + if (redact_debug_string_) { + generator->PrintMaybeWithMarker(MarkerToken(), ": ", + "UNKNOWN_STRING "); + OutOfLinePrintString(generator, kFieldValueReplacement); + if (single_line_mode_) { + generator->PrintLiteral(" "); + } else { + generator->PrintLiteral("\n"); + } + break; + } generator->PrintMaybeWithMarker(MarkerToken(), ": ", "\""); generator->PrintString(absl::CEscape(value)); if (single_line_mode_) { @@ -2843,6 +2882,17 @@ void TextFormat::Printer::PrintUnknownFields( } case UnknownField::TYPE_GROUP: OutOfLinePrintString(generator, field.number()); + if (redact_debug_string_) { + generator->PrintMaybeWithMarker(MarkerToken(), ": ", + "UNKNOWN_GROUP "); + OutOfLinePrintString(generator, kFieldValueReplacement); + if (single_line_mode_) { + generator->PrintLiteral(" "); + } else { + generator->PrintLiteral("\n"); + } + break; + } if (single_line_mode_) { generator->PrintMaybeWithMarker(MarkerToken(), " ", "{ "); } else { diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 0ac3ab7265..9f60c9f3fd 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -69,6 +69,8 @@ constexpr absl::string_view kEscapeTestStringEscaped = "\"\\\"A string with \\' characters \\n and \\r newlines " "and \\t tabs and \\001 slashes \\\\ and multiple spaces\""; +constexpr absl::string_view value_replacement = "\\[REDACTED\\]"; + class TextFormatTest : public testing::Test { public: static void SetUpTestSuite() { @@ -172,35 +174,24 @@ TEST_F(TextFormatTest, ShortFormat) { std::string value_replacement = "\\[REDACTED\\]"; EXPECT_THAT(google::protobuf::ShortFormat(proto), - testing::MatchesRegex( - "optional_redacted_string: " + - value_replacement + - " " + testing::MatchesRegex(absl::Substitute( + "optional_redacted_string: $0 " "optional_unredacted_string: \"bar\" " - "repeated_redacted_string: " + - value_replacement + - " " - "repeated_redacted_string: " + - value_replacement + - " " + "repeated_redacted_string: $0 " + "repeated_redacted_string: $0 " "repeated_unredacted_string: \"3\" " "repeated_unredacted_string: \"4\" " - "optional_redacted_message: " + - value_replacement + - " " + "optional_redacted_message: $0 " "optional_unredacted_message \\{ " "optional_unredacted_nested_string: \"world\" \\} " - "repeated_redacted_message: " + - value_replacement + - " " + "repeated_redacted_message: $0 " "repeated_unredacted_message " "\\{ optional_unredacted_nested_string: \"7\" \\} " "repeated_unredacted_message " "\\{ optional_unredacted_nested_string: \"8\" \\} " - "map_redacted_string: " + - value_replacement + - " " - "map_unredacted_string \\{ key: \"ghi\" value: \"jkl\" \\}")); + "map_redacted_string: $0 " + "map_unredacted_string \\{ key: \"ghi\" value: \"jkl\" \\}", + value_replacement))); } TEST_F(TextFormatTest, Utf8Format) { @@ -234,39 +225,27 @@ TEST_F(TextFormatTest, Utf8Format) { (*proto.mutable_map_redacted_string())["abc"] = "def"; (*proto.mutable_map_unredacted_string())["ghi"] = "jkl"; - std::string value_replacement = "\\[REDACTED\\]"; EXPECT_THAT(google::protobuf::Utf8Format(proto), - testing::MatchesRegex( - "optional_redacted_string: " + - value_replacement + - "\n" + testing::MatchesRegex(absl::Substitute( + "optional_redacted_string: $0\n" "optional_unredacted_string: \"bar\"\n" - "repeated_redacted_string: " + - value_replacement + - "\n" - "repeated_redacted_string: " + - value_replacement + - "\n" + "repeated_redacted_string: $0\n" + "repeated_redacted_string: $0\n" "repeated_unredacted_string: \"3\"\n" "repeated_unredacted_string: \"4\"\n" - "optional_redacted_message: " + - value_replacement + - "\n" + "optional_redacted_message: $0\n" "optional_unredacted_message \\{\n " "optional_unredacted_nested_string: " "\"\xE8\xB0\xB7\xE6\xAD\x8C\"\n\\}\n" - "repeated_redacted_message: " + - value_replacement + - "\n" + "repeated_redacted_message: $0\n" "repeated_unredacted_message \\{\n " "optional_unredacted_nested_string: \"7\"\n\\}\n" "repeated_unredacted_message \\{\n " "optional_unredacted_nested_string: \"8\"\n\\}\n" - "map_redacted_string: " + - value_replacement + - "\n" + "map_redacted_string: $0\n" "map_unredacted_string \\{\n " - "key: \"ghi\"\n value: \"jkl\"\n\\}\n")); + "key: \"ghi\"\n value: \"jkl\"\n\\}\n", + value_replacement))); } TEST_F(TextFormatTest, ShortPrimitiveRepeateds) { @@ -402,6 +381,17 @@ TEST_F(TextFormatTest, PrintUnknownFields) { "8: 2\n" "8: 3\n"), message.DebugString()); + + EXPECT_THAT(absl::StrCat(message), testing::MatchesRegex(absl::Substitute( + "5: UNKNOWN_VARINT $0\n" + "5: UNKNOWN_FIXED32 $0\n" + "5: UNKNOWN_FIXED64 $0\n" + "5: UNKNOWN_STRING $0\n" + "5: UNKNOWN_GROUP $0\n" + "8: UNKNOWN_VARINT $0\n" + "8: UNKNOWN_VARINT $0\n" + "8: UNKNOWN_VARINT $0\n", + value_replacement))); } TEST_F(TextFormatTest, PrintUnknownFieldsDeepestStackWorks) { From 1934daf26ee1bc8518649ce51f13e54213b48efe Mon Sep 17 00:00:00 2001 From: Martijn Vels Date: Thu, 19 Oct 2023 20:05:29 -0700 Subject: [PATCH 44/95] Internal changes PiperOrigin-RevId: 575078212 --- src/google/protobuf/compiler/cpp/helpers.h | 11 +++- .../cpp/tools/analyze_profile_proto.cc | 51 ++++++++++++------- .../cpp/tools/analyze_profile_proto_test.cc | 21 ++++---- .../tools/analyze_profile_proto_test.proto | 2 + 4 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index 6e5896dc80..4c590cdc76 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -358,9 +358,18 @@ bool IsStringInliningEnabled(const Options& options); // Returns true if the provided field is a singular string and can be inlined. bool CanStringBeInlined(const FieldDescriptor* field); -// Returns true if `field` should be inlined based on PDProto profile. +// Returns true if `field` is a string field that can and should be inlined +// based on PDProto profile. bool IsStringInlined(const FieldDescriptor* field, const Options& options); +// Returns true if `field` should be inlined based on PDProto profile. +// Currently we only enable inlining for string fields backed by a std::string +// instance, but in the future we may expand this to message types. +inline bool IsFieldInlined(const FieldDescriptor* field, + const Options& options) { + return IsStringInlined(field, options); +} + // Does the given FileDescriptor use lazy fields? bool HasLazyFields(const FileDescriptor* file, const Options& options, MessageSCCAnalyzer* scc_analyzer); diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc index f5042371b1..8af6b57380 100644 --- a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc @@ -19,6 +19,7 @@ #include "google/protobuf/testing/file.h" #include "google/protobuf/testing/file.h" #include "google/protobuf/compiler/access_info_map.h" +#include "google/protobuf/compiler/split_map.h" #include "google/protobuf/compiler/profile_bootstrap.pb.h" #include "absl/log/absl_log.h" #include "absl/log/log.h" @@ -29,6 +30,7 @@ #include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/cpp_access_info_parse_helper.h" #include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "third_party/re2/re2.h" @@ -61,7 +63,7 @@ std::ostream& operator<<(std::ostream& s, PDProtoScale scale) { return s; } -enum PDProtoOptimization { kNone, kLazy, kInline, kSplit }; +enum PDProtoOptimization { kNone, kUnverifiedLazy, kLazy, kInline, kSplit }; std::ostream& operator<<(std::ostream& s, PDProtoOptimization optimization) { switch (optimization) { @@ -69,6 +71,8 @@ std::ostream& operator<<(std::ostream& s, PDProtoOptimization optimization) { return s << "NONE"; case PDProtoOptimization::kLazy: return s << "LAZY"; + case PDProtoOptimization::kUnverifiedLazy: + return s << "UNVERIFIED_LAZY"; case PDProtoOptimization::kInline: return s << "INLINE"; case PDProtoOptimization::kSplit: @@ -83,6 +87,16 @@ class PDProtoAnalyzer { : info_map_(access_info) { info_map_.SetAccessInfoParseHelper( std::make_unique()); + options_.access_info_map = &info_map_; + scc_analyzer_ = std::make_unique(options_); + } + + void SetFile(const FileDescriptor* file) { + if (current_file_ != file) { + split_map_ = cpp::CreateSplitMap(file, options_); + options_.split_map = &split_map_; + current_file_ = file; + } } bool HasProfile(const Descriptor* descriptor) const { @@ -110,25 +124,20 @@ class PDProtoAnalyzer { } PDProtoOptimization OptimizeField(const FieldDescriptor* field) { - PDProtoAnalysis analysis = AnalyzeField(field); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - if (analysis.presence >= PDProtoScale::kLikely) { - if (cpp::CanStringBeInlined(field)) { - return PDProtoOptimization::kInline; - } + if (IsFieldInlined(field, options_)) { + return PDProtoOptimization::kInline; + } + if (IsLazy(field, options_, scc_analyzer_.get())) { + if (IsLazilyVerifiedLazy(field, options_)) { + return PDProtoOptimization::kUnverifiedLazy; } + return PDProtoOptimization::kLazy; } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (analysis.presence > PDProtoScale::kRarely) { - // Exclude 'never' as that may simply mean we have no data. - if (analysis.usage == PDProtoScale::kRarely) { - if (!field->is_repeated()) { - return PDProtoOptimization::kLazy; - } - } - } + if (cpp::ShouldSplit(field, options_)) { + return PDProtoOptimization::kSplit; } + return PDProtoOptimization::kNone; } @@ -156,7 +165,11 @@ class PDProtoAnalyzer { info_map_.IsCold(field, AccessInfoMap::kWrite, kColdRatio); } + cpp::Options options_; AccessInfoMap info_map_; + SplitMap split_map_; + std::unique_ptr scc_analyzer_; + const FileDescriptor* current_file_ = nullptr; }; size_t GetLongestName(const DescriptorPool& pool, absl::string_view name, @@ -291,6 +304,7 @@ absl::Status AnalyzeProfileProtoToText( if (RE2::PartialMatch(message->name(), regex)) { if (const Descriptor* descriptor = FindMessageTypeByCppName(pool, message->name())) { + analyzer.SetFile(descriptor->file()); if (analyzer.HasProfile(descriptor)) { bool message_header = false; for (int i = 0; i < descriptor->field_count(); ++i) { @@ -301,7 +315,10 @@ absl::Status AnalyzeProfileProtoToText( optimized != PDProtoOptimization::kNone) { if (!message_header) { message_header = true; - stream << "Message " << descriptor->full_name() << "\n"; + stream << "Message " + << absl::StrReplaceAll(descriptor->full_name(), + {{".", "::"}}) + << "\n"; } stream << " " << TypeName(field) << " " << field->name() << ":"; diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc index 8b13cf06a4..04ebbf1c51 100644 --- a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc @@ -67,7 +67,7 @@ TEST(AnalyzeProfileProtoTest, LikelyStringPresence) { options.print_unused_threshold = false; options.pool = DescriptorPool::generated_pool(); EXPECT_STREQ(AnalyzeToText(info, options).c_str(), - "Message google.protobuf.compiler.tools.AnalyzeThis\n" + "Message google::protobuf::compiler::tools::AnalyzeThis\n" " string optional_string: INLINE\n"); } @@ -79,7 +79,7 @@ TEST(AnalyzeProfileProtoTest, ChildLikelyPresentAndUsed) { message { name: "google::protobuf::compiler::tools::AnalyzeThis" count: 100 - field { name: "id" getters_count: 0 configs_count: 100 } + field { name: "id" getters_count: 1000 configs_count: 100 } field { name: "optional_string" getters_count: 100 configs_count: 100 } field { name: "optional_child" getters_count: 100 configs_count: 102 } field { name: "repeated_string" getters_count: 100 configs_count: 1 } @@ -91,7 +91,7 @@ TEST(AnalyzeProfileProtoTest, ChildLikelyPresentAndUsed) { options.print_unused_threshold = false; options.pool = DescriptorPool::generated_pool(); EXPECT_STREQ(AnalyzeToText(info, options).c_str(), - "Message google.protobuf.compiler.tools.AnalyzeThis\n" + "Message google::protobuf::compiler::tools::AnalyzeThis\n" " string optional_string: INLINE\n"); } @@ -103,20 +103,19 @@ TEST(AnalyzeProfileProtoTest, ChildLikelyPresentAndRarelyUsed) { message { name: "google::protobuf::compiler::tools::AnalyzeThis" count: 100 - field { name: "id" getters_count: 0 configs_count: 100 } - field { name: "optional_string" getters_count: 100 configs_count: 100 } + field { name: "id" getters_count: 1 configs_count: 100 } + field { name: "optional_string" getters_count: 1 configs_count: 100 } field { name: "optional_child" getters_count: 100 configs_count: 1 } - field { name: "repeated_string" getters_count: 100 configs_count: 1 } - field { name: "repeated_child" getters_count: 100 configs_count: 1 } - field { name: "nested" getters_count: 0 configs_count: 1 } + field { name: "repeated_string" getters_count: 100 configs_count: 100 } + field { name: "repeated_child" getters_count: 100 configs_count: 100 } + field { name: "nested" getters_count: 1 configs_count: 100 } } )pb"); AnalyzeProfileProtoOptions options; options.print_unused_threshold = false; options.pool = DescriptorPool::generated_pool(); EXPECT_STREQ(AnalyzeToText(info, options).c_str(), - "Message google.protobuf.compiler.tools.AnalyzeThis\n" - " string optional_string: INLINE\n" + "Message google::protobuf::compiler::tools::AnalyzeThis\n" " AnalyzeChild optional_child: LAZY\n"); } @@ -134,7 +133,7 @@ TEST(AnalyzeProfileProtoTest, NestedCppNameMatchedToPoolName) { options.print_unused_threshold = false; options.pool = DescriptorPool::generated_pool(); EXPECT_STREQ(AnalyzeToText(info, options).c_str(), - "Message google.protobuf.compiler.tools.AnalyzeThis.Nested\n" + "Message google::protobuf::compiler::tools::AnalyzeThis::Nested\n" " string optional_string: INLINE\n"); } diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.proto b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.proto index d689886b31..74fe17ca4d 100644 --- a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.proto +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.proto @@ -2,8 +2,10 @@ syntax = "proto2"; package google.protobuf.compiler.tools; +// Non trivial child message message AnalyzeChild { optional int32 child_id = 1; + optional AnalyzeChild child = 2; } message AnalyzeThis { From 96c7680f4e2ad2ebb4365a25f194de0f194de97c Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Fri, 20 Oct 2023 07:58:05 -0700 Subject: [PATCH 45/95] Update CMake install test to use shared libraries This should help us catch problems that come up when libprotobuf and libprotoc are built as shared libraries. The motivating example was that we recently had build failures due to `PROTOBUF_EXPORT` being missing from a symbol that needed it, but none of our existing tests caught this. (Technically this test wouldn't catch it either since that particular issue affected C++17 only, but at least this should help with similar problems.) PiperOrigin-RevId: 575218922 --- .github/workflows/test_cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_cpp.yml b/.github/workflows/test_cpp.yml index 511f9ec189..62f8296ad5 100644 --- a/.github/workflows/test_cpp.yml +++ b/.github/workflows/test_cpp.yml @@ -172,7 +172,7 @@ jobs: image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake:3.13.3-63dd26c0c7a808d92673a3e52e848189d4ab0f17 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} command: >- - /install.sh -DCMAKE_CXX_STANDARD=14 ${{ env.SCCACHE_CMAKE_FLAGS }} -Dprotobuf_USE_EXTERNAL_GTEST=ON -Dprotobuf_ABSL_PROVIDER=package \&\& + /install.sh -DCMAKE_CXX_STANDARD=14 ${{ env.SCCACHE_CMAKE_FLAGS }} -Dprotobuf_USE_EXTERNAL_GTEST=ON -Dprotobuf_ABSL_PROVIDER=package -Dprotobuf_BUILD_SHARED_LIBS=ON \&\& /test.sh ${{ env.SCCACHE_CMAKE_FLAGS }} -Dprotobuf_REMOVE_INSTALLED_HEADERS=ON From 8647a803a0d0279daac09f15e76181d79006255d Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 20 Oct 2023 08:30:44 -0700 Subject: [PATCH 46/95] Cleaned up more cases of NULL -> nullptr PiperOrigin-RevId: 575226197 --- upb/test/test_cpp.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/upb/test/test_cpp.cc b/upb/test/test_cpp.cc index bd917c1d9b..a2d1c4c456 100644 --- a/upb/test/test_cpp.cc +++ b/upb/test/test_cpp.cc @@ -57,7 +57,7 @@ TEST(Cpp, Default) { upb::Arena arena; upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(defpool.ptr())); upb_test_TestMessage* msg = upb_test_TestMessage_new(arena.ptr()); - size_t size = upb_JsonEncode(msg, md.ptr(), NULL, 0, NULL, 0, NULL); + size_t size = upb_JsonEncode(msg, md.ptr(), nullptr, 0, nullptr, 0, nullptr); EXPECT_EQ(2, size); // "{}" } @@ -95,10 +95,10 @@ TEST(Cpp, TimestampEncoder) { google_protobuf_Timestamp_set_seconds(timestamp_upb, timestamp); char json[128]; - size_t size = upb_JsonEncode(timestamp_upb, md.ptr(), NULL, 0, json, - sizeof(json), NULL); + size_t size = upb_JsonEncode(timestamp_upb, md.ptr(), nullptr, 0, json, + sizeof(json), nullptr); bool result = upb_JsonDecode(json, size, timestamp_upb_decoded, md.ptr(), - NULL, 0, arena.ptr(), NULL); + nullptr, 0, arena.ptr(), nullptr); const int64_t timestamp_decoded = google_protobuf_Timestamp_seconds(timestamp_upb_decoded); From 3d068a22470f2f9e08d797dcb5d937e1fdc9b456 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Fri, 20 Oct 2023 08:34:58 -0700 Subject: [PATCH 47/95] Reduce CI frequency. We're having issues with github runners right now where they're queueing for long periods, and this has become disruptive. We've gotten the flake rate under 2% total (<0.5% per build), and can ramp this up again later if we want to reduce it further. PiperOrigin-RevId: 575227138 --- .github/workflows/test_runner.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test_runner.yml b/.github/workflows/test_runner.yml index ea84407874..dfd47fbe21 100644 --- a/.github/workflows/test_runner.yml +++ b/.github/workflows/test_runner.yml @@ -12,9 +12,8 @@ name: Tests on: # continuous schedule: - # TODO Reduce this frequency - # Run every 15 minutes for now to gather statistics - - cron: "*/15 * * * *" + # Run every hour + - cron: "0 * * * *" # postsubmit push: From e419f7365f88635da156ebf2a612e700c8f41867 Mon Sep 17 00:00:00 2001 From: Martijn Vels Date: Fri, 20 Oct 2023 09:01:24 -0700 Subject: [PATCH 48/95] Remove dead code that was only used in aggregate initialization PiperOrigin-RevId: 575233315 --- src/google/protobuf/compiler/cpp/message.cc | 185 -------------------- src/google/protobuf/compiler/cpp/message.h | 5 - 2 files changed, 190 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 184d83d16b..b5f89a9da2 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -2659,71 +2659,6 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) { )cc"); } -void MessageGenerator::GenerateCopyConstructorBody(io::Printer* p) const { - Formatter format(p); - - const RunMap runs = - FindRuns(optimized_order_, [this](const FieldDescriptor* field) { - return IsPOD(field) && !ShouldSplit(field, options_); - }); - - std::string pod_template = - "::memcpy(&$first$, &from.$first$,\n" - " static_cast<::size_t>(reinterpret_cast(&$last$) -\n" - " reinterpret_cast(&$first$)) + sizeof($last$));\n"; - - if (ShouldForceAllocationOnConstruction(descriptor_, options_)) { - format( - "#ifdef PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION\n" - "$mutable_unknown_fields$;\n" - "#endif // PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION\n"); - } - - for (size_t i = 0; i < optimized_order_.size(); ++i) { - const FieldDescriptor* field = optimized_order_[i]; - if (ShouldSplit(field, options_)) { - continue; - } - const auto it = runs.find(field); - - // We only apply the memset technique to runs of more than one field, as - // assignment is better than memset for generated code clarity. - if (it != runs.end() && it->second > 1) { - // Use a memset, then skip run_length fields. - const size_t run_length = it->second; - const std::string first_field_name = - FieldMemberName(field, /*cold=*/false); - const std::string last_field_name = - FieldMemberName(optimized_order_[i + run_length - 1], /*cold=*/false); - - auto v = p->WithVars({ - {"first", first_field_name}, - {"last", last_field_name}, - }); - format(pod_template.c_str()); - - i += run_length - 1; - // ++i at the top of the loop. - } else { - field_generators_.get(field).GenerateCopyConstructorCode(p); - } - } - - if (ShouldSplit(descriptor_, options_)) { - format("if (PROTOBUF_PREDICT_FALSE(!from.IsSplitMessageDefault())) {\n"); - format.Indent(); - format("_this->PrepareSplitMessageForWrite();\n"); - // TODO: cache the split pointers. - for (auto field : optimized_order_) { - if (ShouldSplit(field, options_)) { - field_generators_.get(field).GenerateCopyConstructorCode(p); - } - } - format.Outdent(); - format("}\n"); - } -} - bool MessageGenerator::ImplHasCopyCtor() const { if (ShouldSplit(descriptor_, options_)) return false; if (HasSimpleBaseClass(descriptor_, options_)) return false; @@ -2753,126 +2688,6 @@ bool MessageGenerator::ImplHasCopyCtor() const { return true; } -void MessageGenerator::GenerateCopyConstructorBodyImpl(io::Printer* p) const { - if (!HasImplData(descriptor_, options_)) return; - - p->Emit( - {{"initializer", - [&] { - if (descriptor_->extension_range_count() > 0) { - p->Emit(R"cc( - /*decltype($extensions$)*/ {}, - )cc"); - } - if (!inlined_string_indices_.empty()) { - // Do not copy inlined_string_donated_, because this is not an - // arena constructor. - p->Emit(R"cc( - decltype($inlined_string_donated_array$){}, - )cc"); - } - - bool need_to_emit_cached_size = - !HasSimpleBaseClass(descriptor_, options_); - if (!has_bit_indices_.empty()) { - p->Emit(R"cc( - decltype($has_bits$){from.$has_bits$}, - )cc"); - if (need_to_emit_cached_size) { - p->Emit(R"cc( - /*decltype($cached_size$)*/ {}, - )cc"); - need_to_emit_cached_size = false; - } - } - // Initialize member variables with arena constructor. - for (const auto* field : optimized_order_) { - if (ShouldSplit(field, options_)) continue; - field_generators_.get(field).GenerateCopyAggregateInitializer(p); - } - if (ShouldSplit(descriptor_, options_)) { - p->Emit({{"name", DefaultInstanceName(descriptor_, options_, - /*split=*/true)}}, - R"cc( - decltype($split$){const_cast( - reinterpret_cast(&$name$))}, - )cc"); - } - for (auto oneof : OneOfRange(descriptor_)) { - p->Emit({{"name", oneof->name()}}, - R"cc( - decltype(_impl_.$name$_){}, - )cc"); - } - if (need_to_emit_cached_size) { - p->Emit(R"cc( - /*decltype($cached_size$)*/ {}, - )cc"); - need_to_emit_cached_size = false; - } - if (descriptor_->real_oneof_decl_count() > 0) { - p->Emit(R"cc( - /*decltype($oneof_case$)*/ {}, - )cc"); - } - if (num_weak_fields_ > 0) { - p->Emit(R"cc( - decltype($weak_field_map$){from.$weak_field_map$}, - )cc"); - } - if (IsAnyMessage(descriptor_)) { - p->Emit(R"cc( - /*decltype($any_metadata$)*/ { - &_impl_.type_url_, - &_impl_.value_, - }, - )cc"); - } - }}}, - R"cc( - new (&_impl_) Impl_{ - $initializer$, - }; - )cc"); -} - -void MessageGenerator::GenerateCopyConstructorBodyOneofs(io::Printer* p) const { - // Copy oneof fields. Oneof field requires oneof case check. - for (const auto* oneof : OneOfRange(descriptor_)) { - p->Emit( - { - {"name", oneof->name()}, - {"NAME", absl::AsciiStrToUpper(oneof->name())}, - {"cases", - [&] { - for (const auto* field : FieldRange(oneof)) { - p->Emit( - {{"Name", UnderscoresToCamelCase(field->name(), true)}, - {"body", - [&] { - field_generators_.get(field).GenerateMergingCode(p); - }}}, - R"cc( - case k$Name$: { - $body$; - break; - } - )cc"); - } - }}, - }, - R"cc( - clear_has_$name$(); - switch (from.$name$_case()) { - $cases$; - case $NAME$_NOT_SET: { - break; - } - } - )cc"); - } -} - void MessageGenerator::GenerateCopyInitFields(io::Printer* p) const { auto begin = optimized_order_.begin(); auto end = optimized_order_.end(); diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index 26843ec412..4c404adcb9 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -151,11 +151,6 @@ class MessageGenerator { // Returns whether impl_ has a copy ctor. bool ImplHasCopyCtor() const; - // Generates the body of the message's copy constructor. - void GenerateCopyConstructorBody(io::Printer* p) const; - void GenerateCopyConstructorBodyImpl(io::Printer* p) const; - void GenerateCopyConstructorBodyOneofs(io::Printer* p) const; - // Returns the level that this message needs ArenaDtor. If the message has // a field that is not arena-exclusive, it needs an ArenaDtor // (go/proto-destructor). From 5eecee27de0d4e18a18d71ad99a601bf839321b0 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 20 Oct 2023 09:35:03 -0700 Subject: [PATCH 49/95] Update rules_rust usage to match https://github.com/bazelbuild/rules_rust/commit/cd3e53e9b8555543071ea109218baf41fc4b88f7. PiperOrigin-RevId: 575241905 --- Cargo.bazel.lock | 98 +++++++++++++++++++++++++++++++++++++++++++++++- WORKSPACE | 4 +- rust/aspects.bzl | 3 +- 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/Cargo.bazel.lock b/Cargo.bazel.lock index 3839525cf1..a287466e2e 100644 --- a/Cargo.bazel.lock +++ b/Cargo.bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "641f887b045ff0fc19f64df79b53d96d77d1c03c96069036d84bd1104ddc0000", + "checksum": "f93f5d1848bc00c6384273f9fb5273cc1b7fc0cb4dbc2afd776d2feb7b37f3ae", "crates": { "aho-corasick 1.1.2": { "name": "aho-corasick", @@ -829,5 +829,99 @@ "workspace_members": { "direct-cargo-bazel-deps 0.0.1": "" }, - "conditions": {} + "conditions": { + "aarch64-apple-darwin": [ + "aarch64-apple-darwin" + ], + "aarch64-apple-ios": [ + "aarch64-apple-ios" + ], + "aarch64-apple-ios-sim": [ + "aarch64-apple-ios-sim" + ], + "aarch64-fuchsia": [ + "aarch64-fuchsia" + ], + "aarch64-linux-android": [ + "aarch64-linux-android" + ], + "aarch64-pc-windows-msvc": [ + "aarch64-pc-windows-msvc" + ], + "aarch64-unknown-linux-gnu": [ + "aarch64-unknown-linux-gnu" + ], + "arm-unknown-linux-gnueabi": [ + "arm-unknown-linux-gnueabi" + ], + "armv7-linux-androideabi": [ + "armv7-linux-androideabi" + ], + "armv7-unknown-linux-gnueabi": [ + "armv7-unknown-linux-gnueabi" + ], + "i686-apple-darwin": [ + "i686-apple-darwin" + ], + "i686-linux-android": [ + "i686-linux-android" + ], + "i686-pc-windows-msvc": [ + "i686-pc-windows-msvc" + ], + "i686-unknown-freebsd": [ + "i686-unknown-freebsd" + ], + "i686-unknown-linux-gnu": [ + "i686-unknown-linux-gnu" + ], + "powerpc-unknown-linux-gnu": [ + "powerpc-unknown-linux-gnu" + ], + "riscv32imc-unknown-none-elf": [ + "riscv32imc-unknown-none-elf" + ], + "riscv64gc-unknown-none-elf": [ + "riscv64gc-unknown-none-elf" + ], + "s390x-unknown-linux-gnu": [ + "s390x-unknown-linux-gnu" + ], + "thumbv7em-none-eabi": [ + "thumbv7em-none-eabi" + ], + "thumbv8m.main-none-eabi": [ + "thumbv8m.main-none-eabi" + ], + "wasm32-unknown-unknown": [ + "wasm32-unknown-unknown" + ], + "wasm32-wasi": [ + "wasm32-wasi" + ], + "x86_64-apple-darwin": [ + "x86_64-apple-darwin" + ], + "x86_64-apple-ios": [ + "x86_64-apple-ios" + ], + "x86_64-fuchsia": [ + "x86_64-fuchsia" + ], + "x86_64-linux-android": [ + "x86_64-linux-android" + ], + "x86_64-pc-windows-msvc": [ + "x86_64-pc-windows-msvc" + ], + "x86_64-unknown-freebsd": [ + "x86_64-unknown-freebsd" + ], + "x86_64-unknown-linux-gnu": [ + "x86_64-unknown-linux-gnu" + ], + "x86_64-unknown-none": [ + "x86_64-unknown-none" + ] + } } diff --git a/WORKSPACE b/WORKSPACE index d0d66ec54f..37994f8c06 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -174,8 +174,8 @@ bind( http_archive( name = "rules_rust", - sha256 = "4a9cb4fda6ccd5b5ec393b2e944822a62e050c7c06f1ea41607f14c4fdec57a2", - urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.25.1/rules_rust-v0.25.1.tar.gz"], + sha256 = "9ecd0f2144f0a24e6bc71ebcc50a1ee5128cedeceb32187004532c9710cb2334", + urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.29.1/rules_rust-v0.29.1.tar.gz"], ) load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains") diff --git a/rust/aspects.bzl b/rust/aspects.bzl index d0c877db0d..68a590e76a 100644 --- a/rust/aspects.bzl +++ b/rust/aspects.bzl @@ -8,7 +8,6 @@ load("@rules_rust//rust/private:providers.bzl", "CrateInfo", "DepInfo", "DepVari # buildifier: disable=bzl-visibility load("@rules_rust//rust/private:rustc.bzl", "rustc_compile_action") -load("@rules_rust//rust:defs.bzl", "rust_common") load("//bazel:upb_proto_library.bzl", "UpbWrappedCcInfo", "upb_proto_library_aspect") load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") @@ -173,7 +172,7 @@ def _compile_rust(ctx, attr, src, extra_srcs, deps): ctx = ctx, attr = attr, toolchain = toolchain, - crate_info = rust_common.create_crate_info( + crate_info_dict = dict( name = crate_name, type = "rlib", root = src, From b7de33ce48a34ff1a1c824c82a1a4a0a06e24a23 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Fri, 20 Oct 2023 11:31:11 -0700 Subject: [PATCH 50/95] Internal changes PiperOrigin-RevId: 575274614 --- .../protobuf/editions/golden/editions_transform_proto2.proto | 1 - .../editions/golden/editions_transform_proto2_lite.proto | 3 --- .../golden/editions_transform_proto2_utf8_disabled.proto | 3 --- .../editions/golden/test_messages_proto2_editions.proto | 1 - 4 files changed, 8 deletions(-) diff --git a/src/google/protobuf/editions/golden/editions_transform_proto2.proto b/src/google/protobuf/editions/golden/editions_transform_proto2.proto index d664bbc447..0c483d1db4 100644 --- a/src/google/protobuf/editions/golden/editions_transform_proto2.proto +++ b/src/google/protobuf/editions/golden/editions_transform_proto2.proto @@ -21,7 +21,6 @@ import "google/protobuf/editions/proto/editions_transform_proto3.proto"; option features.enum_type = CLOSED; option features.repeated_field_encoding = EXPANDED; option features.utf8_validation = NONE; -option features.json_format = LEGACY_BEST_EFFORT; option java_multiple_files = true; option cc_enable_arenas = true; diff --git a/src/google/protobuf/editions/golden/editions_transform_proto2_lite.proto b/src/google/protobuf/editions/golden/editions_transform_proto2_lite.proto index 125be83a0f..ca0d3d8bdc 100644 --- a/src/google/protobuf/editions/golden/editions_transform_proto2_lite.proto +++ b/src/google/protobuf/editions/golden/editions_transform_proto2_lite.proto @@ -9,10 +9,7 @@ edition = "2023"; package protobuf_editions_test; -option features.enum_type = CLOSED; -option features.repeated_field_encoding = EXPANDED; option features.utf8_validation = NONE; -option features.json_format = LEGACY_BEST_EFFORT; option optimize_for = LITE_RUNTIME; message TestMessageLite { diff --git a/src/google/protobuf/editions/golden/editions_transform_proto2_utf8_disabled.proto b/src/google/protobuf/editions/golden/editions_transform_proto2_utf8_disabled.proto index 9a7d0c54dc..b0a70863e8 100644 --- a/src/google/protobuf/editions/golden/editions_transform_proto2_utf8_disabled.proto +++ b/src/google/protobuf/editions/golden/editions_transform_proto2_utf8_disabled.proto @@ -9,10 +9,7 @@ edition = "2023"; package protobuf_editions_test; -option features.enum_type = CLOSED; -option features.repeated_field_encoding = EXPANDED; option features.utf8_validation = NONE; -option features.json_format = LEGACY_BEST_EFFORT; message TestMessageUtf8Disabled { string string_field = 1; diff --git a/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto b/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto index d13376b596..3d9e9adf6f 100644 --- a/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto +++ b/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto @@ -18,7 +18,6 @@ package protobuf_test_messages.editions.proto2; option features.enum_type = CLOSED; option features.repeated_field_encoding = EXPANDED; option features.utf8_validation = NONE; -option features.json_format = LEGACY_BEST_EFFORT; option java_package = "com.google.protobuf_test_messages.editions.proto2"; option objc_class_prefix = "Proto2"; From 108a4a30942f81e8f8cc376e354f657141fa3594 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Fri, 20 Oct 2023 11:43:24 -0700 Subject: [PATCH 51/95] Use protobuf-ci for staleness infra. This will pin our version of Bazel, and avoid non-hermetic breakages from github runner changes PiperOrigin-RevId: 575277990 --- .github/workflows/staleness_check.yml | 18 +++++++++++------- .github/workflows/staleness_refresh.yml | 8 ++++++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/staleness_check.yml b/.github/workflows/staleness_check.yml index 45aa2b3bcc..2669821443 100644 --- a/.github/workflows/staleness_check.yml +++ b/.github/workflows/staleness_check.yml @@ -49,10 +49,14 @@ jobs: # In branches where automatic updates work as post-submits, we don't want to run staleness # tests along with user changes. Any stale files will be automatically fixed in a follow-up # commit. - run: | - if [[ -z $COMMIT_TRIGGERED_RUN || -z $MAIN_RUN ]]; then - bazel query 'attr(tags, "staleness_test", //...)' | xargs bazel test $BAZEL_FLAGS || \ - echo "Please run ./regenerate_stale_files.sh to regenerate stale files" - else - bazel query 'attr(tags, "staleness_test", //...)' - fi + uses: protocolbuffers/protobuf-ci/bazel@v2 + with: + credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} + bazel-cache: staleness + bash: > + if [[ -z $COMMIT_TRIGGERED_RUN || -z $MAIN_RUN ]]; then + bazel query 'attr(tags, "staleness_test", //...)' | xargs bazel test $BAZEL_FLAGS || + echo "Please run ./regenerate_stale_files.sh to regenerate stale files"; + else + bazel query 'attr(tags, "staleness_test", //...)'; + fi diff --git a/.github/workflows/staleness_refresh.yml b/.github/workflows/staleness_refresh.yml index c53e4ed9fb..8fadfb1f85 100644 --- a/.github/workflows/staleness_refresh.yml +++ b/.github/workflows/staleness_refresh.yml @@ -30,6 +30,10 @@ jobs: # failing then you may need to generate a fresh token. token: ${{ secrets.BOT_ACCESS_TOKEN }} - name: Configure name and email address in Git - run: cd ${{ github.workspace }} && git config user.name "Protobuf Team Bot" && git config user.email "protobuf-team-bot@google.com" + run: git config user.name "Protobuf Team Bot" && git config user.email "protobuf-team-bot@google.com" - name: Commit and push update - run: cd ${{ github.workspace }} && ./ci/push_auto_update.sh + uses: protocolbuffers/protobuf-ci/bazel@v2 + with: + credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} + bazel-cache: staleness + bash: ci/push_auto_update.sh From 8b2a3a613963d1bf9f5bcda44b016594f556beda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 12:05:36 -0700 Subject: [PATCH 52/95] Bump actions/checkout from 3.1.0 to 4.1.0 (#14412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 4.1.0.
Release notes

Sourced from actions/checkout's releases.

v4.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.0.0...v4.1.0

v4.0.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

... (truncated)

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.1.0&new-version=4.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Closes #14412 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/14412 from protocolbuffers:dependabot/github_actions/actions/checkout-4.1.0 20c4eb77c6d03d3ed980bf45020645f0de8b3636 PiperOrigin-RevId: 575284289 --- .github/workflows/scorecard.yml | 2 +- .github/workflows/staleness_refresh.yml | 2 +- .github/workflows/update_php_repo.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a6d55589d3..bf2788fe7d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -27,7 +27,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: persist-credentials: false diff --git a/.github/workflows/staleness_refresh.yml b/.github/workflows/staleness_refresh.yml index 8fadfb1f85..6f6b5ac4b5 100644 --- a/.github/workflows/staleness_refresh.yml +++ b/.github/workflows/staleness_refresh.yml @@ -24,7 +24,7 @@ jobs: fail-fast: false # Don't cancel all jobs if one fails. steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: # Note: this token has an expiration date, so if the workflow starts # failing then you may need to generate a fresh token. diff --git a/.github/workflows/update_php_repo.yml b/.github/workflows/update_php_repo.yml index cb3383ad01..41ec07626f 100644 --- a/.github/workflows/update_php_repo.yml +++ b/.github/workflows/update_php_repo.yml @@ -15,12 +15,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout protobuf-php - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: repository: protocolbuffers/protobuf-php token: ${{ secrets.BOT_ACCESS_TOKEN }} - name: Clone protobuf - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: path: protobuf - name: Configure Git Bot From 77aa913e689304329b6e3df71eea9944acfbc62f Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Sat, 21 Oct 2023 09:37:33 -0700 Subject: [PATCH 53/95] Update `cc_file_list_aspect` to handle targets with missing `hdrs/textual_hdrs` Our stale file regeneration logic broke with Bazel 6.4.0, and I suspect it was caused by this change: https://github.com/bazelbuild/bazel/pull/19534 Our logic assumed that any target with a `CcInfo` provider must have `hdrs` and `textual_hdrs` attributes, but it seems that this is no longer true for `cc_proto_library` starting with Bazel 6.4.0. The fix is just to use `getattr` and treat the item as an empty list if it's missing. PiperOrigin-RevId: 575473886 --- pkg/cc_dist_library.bzl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cc_dist_library.bzl b/pkg/cc_dist_library.bzl index 42553ca3f8..9fc2c414e6 100644 --- a/pkg/cc_dist_library.bzl +++ b/pkg/cc_dist_library.bzl @@ -170,12 +170,12 @@ def _cc_file_list_aspect_impl(target, ctx): return [CcFileList( hdrs = _get_transitive_sources( - _flatten_target_files(rule_attr.hdrs).to_list(), + _flatten_target_files(getattr(rule_attr, "hdrs", [])).to_list(), "hdrs", rule_attr.deps, ), textual_hdrs = _get_transitive_sources( - _flatten_target_files(rule_attr.textual_hdrs).to_list(), + _flatten_target_files(getattr(rule_attr, "textual_hdrs", [])).to_list(), "textual_hdrs", rule_attr.deps, ), From cc27cc3cf7d41d36577965e06f74e9bd4677b200 Mon Sep 17 00:00:00 2001 From: st-cheewah <103625673+st-cheewah@users.noreply.github.com> Date: Mon, 23 Oct 2023 06:11:56 -0700 Subject: [PATCH 54/95] Update docs/third_party.md with new Clojure/Script libraries (#14415) * https://github.com/s-expresso/clojobuf * https://github.com/s-expresso/rubberbuf * https://github.com/s-expresso/clojobuf-codec Closes #14415 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/14415 from st-cheewah:main ec6b50a46b024d2c5581d8dc54736baa0e3567e5 PiperOrigin-RevId: 575796617 --- docs/third_party.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/third_party.md b/docs/third_party.md index ed63375bf6..a3763a974e 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -31,6 +31,8 @@ These are projects we know about implementing Protocol Buffers for other program * Clojure: http://github.com/ninjudd/clojure-protobuf * Clojure: https://github.com/clojusc/protobuf * Clojure: https://protojure.readthedocs.io +* Clojure: https://github.com/s-expresso/clojobuf +* ClojureScript: https://github.com/s-expresso/clojobuf * Common Lisp: http://github.com/brown/protobuf * Common Lisp: http://github.com/qitab/cl-protobuf * D: https://github.com/dcarp/protobuf-d @@ -233,3 +235,8 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d * [protobuf-decoder-explainer - Web page which decodes and explains pasted binary Protocol Buffers](https://github.com/jamesdbrock/protobuf-decoder-explainer) +* [rubberbuf - dynamically transpile protobuf into AST](https://github.com/s-expresso/rubberbuf) + `clojure` `clojurescript` +* [clojobuf-serdes - low level serialize/deserialize library for protobuf + binary format](https://github.com/s-expresso/clojobuf-codec) `clojure` + `clojurescript` From 8bf4fe924a924e0ee290bf883977c108fc12f28d Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 23 Oct 2023 07:25:51 -0700 Subject: [PATCH 55/95] Fix static reflection for an enum's min/max value to be signed (int instead of usize). PiperOrigin-RevId: 575811496 --- src/google/protobuf/compiler/cpp/enum.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/google/protobuf/compiler/cpp/enum.cc b/src/google/protobuf/compiler/cpp/enum.cc index a43106f6b2..e23d6e0d64 100644 --- a/src/google/protobuf/compiler/cpp/enum.cc +++ b/src/google/protobuf/compiler/cpp/enum.cc @@ -12,6 +12,7 @@ #include "google/protobuf/compiler/cpp/enum.h" #include +#include #include #include #include From 538a8e9a0d90b0bd8aea7b10f8e17ba76585b2e8 Mon Sep 17 00:00:00 2001 From: Martijn Vels Date: Mon, 23 Oct 2023 09:29:57 -0700 Subject: [PATCH 56/95] Use Arena enabled copy constructor when merging child messages PiperOrigin-RevId: 575841937 --- src/google/protobuf/compiler/cpp/field.cc | 4 + src/google/protobuf/compiler/cpp/field.h | 16 ++ .../cpp/field_generators/message_field.cc | 21 +- src/google/protobuf/compiler/cpp/message.cc | 14 ++ src/google/protobuf/compiler/cpp/message.h | 5 + src/google/protobuf/compiler/plugin.pb.cc | 18 +- src/google/protobuf/descriptor.pb.cc | 179 ++++++++++++++---- 7 files changed, 212 insertions(+), 45 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/field.cc b/src/google/protobuf/compiler/cpp/field.cc index e9ccf46bbd..d2fee868e1 100644 --- a/src/google/protobuf/compiler/cpp/field.cc +++ b/src/google/protobuf/compiler/cpp/field.cc @@ -263,6 +263,7 @@ void HasBitVars(const FieldDescriptor* field, const Options& opts, absl::optional idx, std::vector& vars) { if (!idx.has_value()) { vars.emplace_back("set_hasbit", ""); + vars.emplace_back("this_set_hasbit", ""); vars.emplace_back("clear_hasbit", ""); return; } @@ -283,6 +284,9 @@ void HasBitVars(const FieldDescriptor* field, const Options& opts, vars.emplace_back("has_hasbit", has); vars.emplace_back(Sub("set_hasbit", set).WithSuffix(";")); vars.emplace_back(Sub("clear_hasbit", clr).WithSuffix(";")); + + set = absl::StrFormat("_this->%s[%d] |= %s;", has_bits, index, mask); + vars.emplace_back(Sub("this_set_hasbit", set).WithSuffix(";")); } void InlinedStringVars(const FieldDescriptor* field, const Options& opts, diff --git a/src/google/protobuf/compiler/cpp/field.h b/src/google/protobuf/compiler/cpp/field.h index 1bba5f27b5..d24d816d81 100644 --- a/src/google/protobuf/compiler/cpp/field.h +++ b/src/google/protobuf/compiler/cpp/field.h @@ -39,6 +39,11 @@ namespace cpp { // matter of clean composability. class FieldGeneratorBase { public: + // `GeneratorFunction` defines a subset of generator functions that may have + // additional optimizations or requirements such as 'uses a local `arena` + // variable instead of calling GetArena()' + enum class GeneratorFunction { kMergeFrom }; + FieldGeneratorBase(const FieldDescriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); @@ -100,6 +105,10 @@ class FieldGeneratorBase { return has_default_constexpr_constructor_; } + // Returns true if this generator requires an 'arena' parameter on the + // given generator function. + virtual bool RequiresArena(GeneratorFunction) const { return false; } + virtual std::vector MakeVars() const { return {}; } virtual void GeneratePrivateMembers(io::Printer* p) const = 0; @@ -230,6 +239,8 @@ class FieldGenerator { } public: + using GeneratorFunction = FieldGeneratorBase::GeneratorFunction; + FieldGenerator(const FieldGenerator&) = delete; FieldGenerator& operator=(const FieldGenerator&) = delete; FieldGenerator(FieldGenerator&&) = default; @@ -256,6 +267,11 @@ class FieldGenerator { return impl_->has_default_constexpr_constructor(); } + // Requirements: see FieldGeneratorBase for documentation + bool RequiresArena(GeneratorFunction function) const { + return impl_->RequiresArena(function); + } + // Prints private members needed to represent this field. // // These are placed inside the class definition. diff --git a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc index 34c7733eac..0171381d57 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc @@ -102,6 +102,8 @@ class SingularMessage : public FieldGeneratorBase { )cc"); } + bool RequiresArena(GeneratorFunction function) const override; + void GenerateNonInlineAccessorDefinitions(io::Printer* p) const override {} void GenerateAccessorDeclarations(io::Printer* p) const override; @@ -415,15 +417,32 @@ void SingularMessage::GenerateMessageClearingCode(io::Printer* p) const { } } +bool SingularMessage::RequiresArena(GeneratorFunction function) const { + switch (function) { + case GeneratorFunction::kMergeFrom: + return !(is_weak() || is_oneof() || should_split()); + } + return false; +} + void SingularMessage::GenerateMergingCode(io::Printer* p) const { if (is_weak()) { p->Emit( "_Internal::mutable_$name$(_this)->CheckTypeAndMergeFrom(\n" " _Internal::$name$(&from));\n"); - } else { + } else if (is_oneof() || should_split()) { p->Emit( "_this->_internal_mutable_$name$()->$Submsg$::MergeFrom(\n" " from._internal_$name$());\n"); + } else { + p->Emit(R"cc( + $this_set_hasbit$; + if (_this->$field_$ == nullptr) { + _this->$field_$ = CreateMaybeMessage<$Submsg$>(arena, *from.$field_$); + } else { + _this->$field_$->MergeFrom(*from.$field_$); + } + )cc"); } } diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index b5f89a9da2..dd98fcb872 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -3496,6 +3496,15 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* p) { } } +bool MessageGenerator::RequiresArena(GeneratorFunction function) const { + for (const FieldDescriptor* field : FieldRange(descriptor_)) { + if (field_generators_.get(field).RequiresArena(function)) { + return true; + } + } + return false; +} + void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { if (HasSimpleBaseClass(descriptor_, options_)) return; // Generate the class-specific MergeFrom, which avoids the ABSL_CHECK and @@ -3515,6 +3524,11 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { " auto& from = static_cast(from_msg);\n"); } format.Indent(); + if (RequiresArena(GeneratorFunction::kMergeFrom)) { + p->Emit(R"cc( + ::$proto_ns$::Arena* arena = _this->GetArena(); + )cc"); + } format( "$annotate_mergefrom$" "// @@protoc_insertion_point(class_specific_merge_from_start:" diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index 4c404adcb9..e62bce2797 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -80,6 +80,7 @@ class MessageGenerator { const Descriptor* descriptor() const { return descriptor_; } private: + using GeneratorFunction = FieldGeneratorBase::GeneratorFunction; enum class InitType { kConstexpr, kArena, kArenaCopy }; // Generate declarations and definitions of accessors for fields. @@ -148,6 +149,10 @@ class MessageGenerator { void GenerateFieldClear(const FieldDescriptor* field, bool is_inline, io::Printer* p); + // Returns true if any of the fields needs an `arena` variable containing + // the current message's arena, reducing `GetArena()` call churn. + bool RequiresArena(GeneratorFunction function) const; + // Returns whether impl_ has a copy ctor. bool ImplHasCopyCtor() const; diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 06e403cc6e..c9ec566504 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -904,6 +904,7 @@ const ::_pbi::TcParseTable<3, 5, 3, 79, 2> CodeGeneratorRequest::_table_ = { void CodeGeneratorRequest::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -920,8 +921,12 @@ void CodeGeneratorRequest::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_parameter(from._internal_parameter()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_compiler_version()->::google::protobuf::compiler::Version::MergeFrom( - from._internal_compiler_version()); + _this->_impl_._has_bits_[0] |= 0x00000002u; + if (_this->_impl_.compiler_version_ == nullptr) { + _this->_impl_.compiler_version_ = CreateMaybeMessage<::google::protobuf::compiler::Version>(arena, *from._impl_.compiler_version_); + } else { + _this->_impl_.compiler_version_->MergeFrom(*from._impl_.compiler_version_); + } } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -1236,6 +1241,7 @@ const ::_pbi::TcParseTable<2, 4, 1, 86, 2> CodeGeneratorResponse_File::_table_ = void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -1253,8 +1259,12 @@ void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::Message& to_msg, _this->_internal_set_content(from._internal_content()); } if (cached_has_bits & 0x00000008u) { - _this->_internal_mutable_generated_code_info()->::google::protobuf::GeneratedCodeInfo::MergeFrom( - from._internal_generated_code_info()); + _this->_impl_._has_bits_[0] |= 0x00000008u; + if (_this->_impl_.generated_code_info_ == nullptr) { + _this->_impl_.generated_code_info_ = CreateMaybeMessage<::google::protobuf::GeneratedCodeInfo>(arena, *from._impl_.generated_code_info_); + } else { + _this->_impl_.generated_code_info_->MergeFrom(*from._impl_.generated_code_info_); + } } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index ae02aa9a2d..d82e6dc1aa 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -3042,6 +3042,7 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 79, 2> FileDescriptorProto::_table_ = { void FileDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -3070,12 +3071,20 @@ void FileDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const : _this->_internal_set_syntax(from._internal_syntax()); } if (cached_has_bits & 0x00000008u) { - _this->_internal_mutable_options()->::google::protobuf::FileOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000008u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::FileOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000010u) { - _this->_internal_mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom( - from._internal_source_code_info()); + _this->_impl_._has_bits_[0] |= 0x00000010u; + if (_this->_impl_.source_code_info_ == nullptr) { + _this->_impl_.source_code_info_ = CreateMaybeMessage<::google::protobuf::SourceCodeInfo>(arena, *from._impl_.source_code_info_); + } else { + _this->_impl_.source_code_info_->MergeFrom(*from._impl_.source_code_info_); + } } if (cached_has_bits & 0x00000020u) { _this->_impl_.edition_ = from._impl_.edition_; @@ -3374,6 +3383,7 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 0, 2> DescriptorProto_ExtensionRange::_t void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -3382,8 +3392,12 @@ void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::Message& to_m cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_options()->::google::protobuf::ExtensionRangeOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::ExtensionRangeOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.start_ = from._impl_.start_; @@ -4063,6 +4077,7 @@ constexpr ::_pbi::TcParseTable<4, 10, 8, 65, 2> DescriptorProto::_table_ = { void DescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -4089,8 +4104,12 @@ void DescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::goo _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::MessageOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000002u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::MessageOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -4759,6 +4778,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = void ExtensionRangeOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -4771,8 +4791,12 @@ void ExtensionRangeOptions::MergeImpl(::google::protobuf::Message& to_msg, const cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.verification_ = from._impl_.verification_; @@ -5292,6 +5316,7 @@ constexpr ::_pbi::TcParseTable<4, 11, 3, 96, 2> FieldDescriptorProto::_table_ = void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -5315,8 +5340,12 @@ void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_json_name(from._internal_json_name()); } if (cached_has_bits & 0x00000020u) { - _this->_internal_mutable_options()->::google::protobuf::FieldOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000020u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::FieldOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000040u) { _this->_impl_.number_ = from._impl_.number_; @@ -5589,6 +5618,7 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 49, 2> OneofDescriptorProto::_table_ = { void OneofDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -5600,8 +5630,12 @@ void OneofDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::OneofOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000002u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::OneofOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -6149,6 +6183,7 @@ constexpr ::_pbi::TcParseTable<3, 5, 3, 61, 2> EnumDescriptorProto::_table_ = { void EnumDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6165,8 +6200,12 @@ void EnumDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const : _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::EnumOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000002u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::EnumOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -6446,6 +6485,7 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 53, 2> EnumValueDescriptorProto::_table_ void EnumValueDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6457,8 +6497,12 @@ void EnumValueDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, co _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000002u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::EnumValueOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000004u) { _this->_impl_.number_ = from._impl_.number_; @@ -6737,6 +6781,7 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 51, 2> ServiceDescriptorProto::_table_ = void ServiceDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6750,8 +6795,12 @@ void ServiceDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, cons _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::ServiceOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000002u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::ServiceOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -7118,6 +7167,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 1, 71, 2> MethodDescriptorProto::_table_ = void MethodDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -7135,8 +7185,12 @@ void MethodDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_output_type(from._internal_output_type()); } if (cached_has_bits & 0x00000008u) { - _this->_internal_mutable_options()->::google::protobuf::MethodOptions::MergeFrom( - from._internal_options()); + _this->_impl_._has_bits_[0] |= 0x00000008u; + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::MethodOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000010u) { _this->_impl_.client_streaming_ = from._impl_.client_streaming_; @@ -7947,6 +8001,7 @@ constexpr ::_pbi::TcParseTable<5, 22, 3, 202, 12> FileOptions::_table_ = { void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -7989,8 +8044,12 @@ void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: _this->_internal_set_ruby_package(from._internal_ruby_package()); } if (cached_has_bits & 0x00000400u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000400u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000800u) { _this->_impl_.java_multiple_files_ = from._impl_.java_multiple_files_; @@ -8411,6 +8470,7 @@ constexpr ::_pbi::TcParseTable<3, 7, 2, 0, 7> MessageOptions::_table_ = { void MessageOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -8421,8 +8481,12 @@ void MessageOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::goog cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x0000003fu) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.message_set_wire_format_ = from._impl_.message_set_wire_format_; @@ -9205,6 +9269,7 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 0, 7> FieldOptions::_table_ = { void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9218,8 +9283,12 @@ void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x000000ffu) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.ctype_ = from._impl_.ctype_; @@ -9508,6 +9577,7 @@ constexpr ::_pbi::TcParseTable<2, 2, 2, 0, 7> OneofOptions::_table_ = { void OneofOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9516,8 +9586,12 @@ void OneofOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google _this->_internal_mutable_uninterpreted_option()->MergeFrom( from._internal_uninterpreted_option()); if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -9846,6 +9920,7 @@ constexpr ::_pbi::TcParseTable<3, 5, 2, 0, 7> EnumOptions::_table_ = { void EnumOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9856,8 +9931,12 @@ void EnumOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.allow_alias_ = from._impl_.allow_alias_; @@ -10184,6 +10263,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 2, 0, 7> EnumValueOptions::_table_ = { void EnumValueOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10194,8 +10274,12 @@ void EnumValueOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::go cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; @@ -10488,6 +10572,7 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 0, 12> ServiceOptions::_table_ = { void ServiceOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10498,8 +10583,12 @@ void ServiceOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::goog cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; @@ -10825,6 +10914,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 3, 0, 12> MethodOptions::_table_ = { void MethodOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10835,8 +10925,12 @@ void MethodOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::googl cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; @@ -12115,6 +12209,7 @@ constexpr ::_pbi::TcParseTable<1, 2, 2, 0, 2> FeatureSetDefaults_FeatureSetEditi void FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -12123,8 +12218,12 @@ void FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(::google::protobuf:: cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + _this->_impl_._has_bits_[0] |= 0x00000001u; + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.edition_ = from._impl_.edition_; From 356d774e1830d609320d85a7cc71e1c759fe2a63 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 23 Oct 2023 10:23:39 -0700 Subject: [PATCH 57/95] Use GetArena() instead of GetOwningArena() #5. PiperOrigin-RevId: 575857972 --- src/google/protobuf/arena.h | 12 ++++++++++-- src/google/protobuf/message_lite.h | 12 +++++------- src/google/protobuf/repeated_field.h | 11 ++++------- src/google/protobuf/repeated_ptr_field.h | 10 ---------- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 0e5d6a9e00..83beb8f9b4 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -389,7 +389,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // mutually exclusive fashion, we use implicit conversions to base classes // to force an explicit ranking for our preferences. The lowest ranked // version that compiles will be accepted. - struct Rank1 {}; + struct Rank2 {}; + struct Rank1 : Rank2 {}; struct Rank0 : Rank1 {}; static Arena* GetOwningArena(const T* p) { @@ -402,8 +403,15 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { return p->GetOwningArena(); } + // TODO: remove this function. template - static Arena* GetOwningArena(Rank1, const U*) { + static auto GetOwningArena(Rank1, const U* p) + -> EnableIfArenaGetArena())> { + return p->GetArena(); + } + + template + static Arena* GetOwningArena(Rank2, const U*) { return nullptr; } diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 6d3b93432b..cbece7c799 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -221,6 +221,11 @@ class PROTOBUF_EXPORT MessageLite { // if arena is a nullptr. virtual MessageLite* New(Arena* arena) const = 0; + // Returns the arena, if any, that directly owns this message and its internal + // memory (Arena::Own is different in that the arena doesn't directly own the + // internal memory). This method is used in proto's implementation for + // swapping, moving and setting allocated, for deciding whether the ownership + // of this message or its internal memory could be changed. Arena* GetArena() const { return _internal_metadata_.arena(); } // Clear all fields of the message and set them to their default values. @@ -511,13 +516,6 @@ class PROTOBUF_EXPORT MessageLite { inline explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {} - // Returns the arena, if any, that directly owns this message and its internal - // memory (Arena::Own is different in that the arena doesn't directly own the - // internal memory). This method is used in proto's implementation for - // swapping, moving and setting allocated, for deciding whether the ownership - // of this message or its internal memory could be changed. - Arena* GetOwningArena() const { return _internal_metadata_.arena(); } - // We use a secondary vtable for descriptor based methods. This way ClassData // does not growth with the number of descriptor methods. This avoids extra // costs in MessageLite. diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index bbce360899..0647790b78 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -293,7 +293,10 @@ class RepeatedField final // Gets the Arena on which this RepeatedField stores its elements. // Note: this can be inaccurate for split default fields so we make this // function non-const. - inline Arena* GetArena() { return GetOwningArena(); } + inline Arena* GetArena() { + return (total_size_ == 0) ? static_cast(arena_or_elements_) + : rep()->arena; + } // For internal use only. // @@ -327,12 +330,6 @@ class RepeatedField final RepeatedField(Arena* arena, const RepeatedField& rhs); - // Gets the Arena on which this RepeatedField stores its elements. - inline Arena* GetOwningArena() const { - return (total_size_ == 0) ? static_cast(arena_or_elements_) - : rep()->arena; - } - // Swaps entire contents with "other". Should be called only if the caller can // guarantee that both repeated fields are on the same arena or are on the diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index 72beb1c2f5..5894e777e2 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -651,8 +651,6 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // Gets the Arena on which this RepeatedPtrField stores its elements. inline Arena* GetArena() const { return arena_; } - inline Arena* GetOwningArena() const { return arena_; } - private: using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; @@ -1317,9 +1315,6 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { RepeatedPtrField(Arena* arena, const RepeatedPtrField& rhs); - // Internal version of GetArena(). - inline Arena* GetOwningArena() const; - // Implementations for ExtractSubrange(). The copying behavior must be // included only if the type supports the necessary operations (e.g., @@ -1676,11 +1671,6 @@ inline Arena* RepeatedPtrField::GetArena() const { } #endif // !PROTOBUF_FUTURE_REMOVE_CONST_REPEATEDFIELD_GETARENA_API -template -inline Arena* RepeatedPtrField::GetOwningArena() const { - return RepeatedPtrFieldBase::GetArena(); -} - template inline size_t RepeatedPtrField::SpaceUsedExcludingSelfLong() const { // `google::protobuf::Message` has a virtual method `SpaceUsedLong`, hence we can From 022d223488c0807e11d1c2509123901f5cc6b0b6 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 23 Oct 2023 12:10:40 -0700 Subject: [PATCH 58/95] Automated rollback of commit 538a8e9a0d90b0bd8aea7b10f8e17ba76585b2e8. PiperOrigin-RevId: 575890896 --- src/google/protobuf/compiler/cpp/field.cc | 4 - src/google/protobuf/compiler/cpp/field.h | 16 -- .../cpp/field_generators/message_field.cc | 21 +- src/google/protobuf/compiler/cpp/message.cc | 14 -- src/google/protobuf/compiler/cpp/message.h | 5 - src/google/protobuf/compiler/plugin.pb.cc | 18 +- src/google/protobuf/descriptor.pb.cc | 179 ++++-------------- 7 files changed, 45 insertions(+), 212 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/field.cc b/src/google/protobuf/compiler/cpp/field.cc index d2fee868e1..e9ccf46bbd 100644 --- a/src/google/protobuf/compiler/cpp/field.cc +++ b/src/google/protobuf/compiler/cpp/field.cc @@ -263,7 +263,6 @@ void HasBitVars(const FieldDescriptor* field, const Options& opts, absl::optional idx, std::vector& vars) { if (!idx.has_value()) { vars.emplace_back("set_hasbit", ""); - vars.emplace_back("this_set_hasbit", ""); vars.emplace_back("clear_hasbit", ""); return; } @@ -284,9 +283,6 @@ void HasBitVars(const FieldDescriptor* field, const Options& opts, vars.emplace_back("has_hasbit", has); vars.emplace_back(Sub("set_hasbit", set).WithSuffix(";")); vars.emplace_back(Sub("clear_hasbit", clr).WithSuffix(";")); - - set = absl::StrFormat("_this->%s[%d] |= %s;", has_bits, index, mask); - vars.emplace_back(Sub("this_set_hasbit", set).WithSuffix(";")); } void InlinedStringVars(const FieldDescriptor* field, const Options& opts, diff --git a/src/google/protobuf/compiler/cpp/field.h b/src/google/protobuf/compiler/cpp/field.h index d24d816d81..1bba5f27b5 100644 --- a/src/google/protobuf/compiler/cpp/field.h +++ b/src/google/protobuf/compiler/cpp/field.h @@ -39,11 +39,6 @@ namespace cpp { // matter of clean composability. class FieldGeneratorBase { public: - // `GeneratorFunction` defines a subset of generator functions that may have - // additional optimizations or requirements such as 'uses a local `arena` - // variable instead of calling GetArena()' - enum class GeneratorFunction { kMergeFrom }; - FieldGeneratorBase(const FieldDescriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); @@ -105,10 +100,6 @@ class FieldGeneratorBase { return has_default_constexpr_constructor_; } - // Returns true if this generator requires an 'arena' parameter on the - // given generator function. - virtual bool RequiresArena(GeneratorFunction) const { return false; } - virtual std::vector MakeVars() const { return {}; } virtual void GeneratePrivateMembers(io::Printer* p) const = 0; @@ -239,8 +230,6 @@ class FieldGenerator { } public: - using GeneratorFunction = FieldGeneratorBase::GeneratorFunction; - FieldGenerator(const FieldGenerator&) = delete; FieldGenerator& operator=(const FieldGenerator&) = delete; FieldGenerator(FieldGenerator&&) = default; @@ -267,11 +256,6 @@ class FieldGenerator { return impl_->has_default_constexpr_constructor(); } - // Requirements: see FieldGeneratorBase for documentation - bool RequiresArena(GeneratorFunction function) const { - return impl_->RequiresArena(function); - } - // Prints private members needed to represent this field. // // These are placed inside the class definition. diff --git a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc index 0171381d57..34c7733eac 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc @@ -102,8 +102,6 @@ class SingularMessage : public FieldGeneratorBase { )cc"); } - bool RequiresArena(GeneratorFunction function) const override; - void GenerateNonInlineAccessorDefinitions(io::Printer* p) const override {} void GenerateAccessorDeclarations(io::Printer* p) const override; @@ -417,32 +415,15 @@ void SingularMessage::GenerateMessageClearingCode(io::Printer* p) const { } } -bool SingularMessage::RequiresArena(GeneratorFunction function) const { - switch (function) { - case GeneratorFunction::kMergeFrom: - return !(is_weak() || is_oneof() || should_split()); - } - return false; -} - void SingularMessage::GenerateMergingCode(io::Printer* p) const { if (is_weak()) { p->Emit( "_Internal::mutable_$name$(_this)->CheckTypeAndMergeFrom(\n" " _Internal::$name$(&from));\n"); - } else if (is_oneof() || should_split()) { + } else { p->Emit( "_this->_internal_mutable_$name$()->$Submsg$::MergeFrom(\n" " from._internal_$name$());\n"); - } else { - p->Emit(R"cc( - $this_set_hasbit$; - if (_this->$field_$ == nullptr) { - _this->$field_$ = CreateMaybeMessage<$Submsg$>(arena, *from.$field_$); - } else { - _this->$field_$->MergeFrom(*from.$field_$); - } - )cc"); } } diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index dd98fcb872..b5f89a9da2 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -3496,15 +3496,6 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* p) { } } -bool MessageGenerator::RequiresArena(GeneratorFunction function) const { - for (const FieldDescriptor* field : FieldRange(descriptor_)) { - if (field_generators_.get(field).RequiresArena(function)) { - return true; - } - } - return false; -} - void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { if (HasSimpleBaseClass(descriptor_, options_)) return; // Generate the class-specific MergeFrom, which avoids the ABSL_CHECK and @@ -3524,11 +3515,6 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { " auto& from = static_cast(from_msg);\n"); } format.Indent(); - if (RequiresArena(GeneratorFunction::kMergeFrom)) { - p->Emit(R"cc( - ::$proto_ns$::Arena* arena = _this->GetArena(); - )cc"); - } format( "$annotate_mergefrom$" "// @@protoc_insertion_point(class_specific_merge_from_start:" diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index e62bce2797..4c404adcb9 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -80,7 +80,6 @@ class MessageGenerator { const Descriptor* descriptor() const { return descriptor_; } private: - using GeneratorFunction = FieldGeneratorBase::GeneratorFunction; enum class InitType { kConstexpr, kArena, kArenaCopy }; // Generate declarations and definitions of accessors for fields. @@ -149,10 +148,6 @@ class MessageGenerator { void GenerateFieldClear(const FieldDescriptor* field, bool is_inline, io::Printer* p); - // Returns true if any of the fields needs an `arena` variable containing - // the current message's arena, reducing `GetArena()` call churn. - bool RequiresArena(GeneratorFunction function) const; - // Returns whether impl_ has a copy ctor. bool ImplHasCopyCtor() const; diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index c9ec566504..06e403cc6e 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -904,7 +904,6 @@ const ::_pbi::TcParseTable<3, 5, 3, 79, 2> CodeGeneratorRequest::_table_ = { void CodeGeneratorRequest::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -921,12 +920,8 @@ void CodeGeneratorRequest::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_parameter(from._internal_parameter()); } if (cached_has_bits & 0x00000002u) { - _this->_impl_._has_bits_[0] |= 0x00000002u; - if (_this->_impl_.compiler_version_ == nullptr) { - _this->_impl_.compiler_version_ = CreateMaybeMessage<::google::protobuf::compiler::Version>(arena, *from._impl_.compiler_version_); - } else { - _this->_impl_.compiler_version_->MergeFrom(*from._impl_.compiler_version_); - } + _this->_internal_mutable_compiler_version()->::google::protobuf::compiler::Version::MergeFrom( + from._internal_compiler_version()); } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -1241,7 +1236,6 @@ const ::_pbi::TcParseTable<2, 4, 1, 86, 2> CodeGeneratorResponse_File::_table_ = void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -1259,12 +1253,8 @@ void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::Message& to_msg, _this->_internal_set_content(from._internal_content()); } if (cached_has_bits & 0x00000008u) { - _this->_impl_._has_bits_[0] |= 0x00000008u; - if (_this->_impl_.generated_code_info_ == nullptr) { - _this->_impl_.generated_code_info_ = CreateMaybeMessage<::google::protobuf::GeneratedCodeInfo>(arena, *from._impl_.generated_code_info_); - } else { - _this->_impl_.generated_code_info_->MergeFrom(*from._impl_.generated_code_info_); - } + _this->_internal_mutable_generated_code_info()->::google::protobuf::GeneratedCodeInfo::MergeFrom( + from._internal_generated_code_info()); } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index d82e6dc1aa..ae02aa9a2d 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -3042,7 +3042,6 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 79, 2> FileDescriptorProto::_table_ = { void FileDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -3071,20 +3070,12 @@ void FileDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const : _this->_internal_set_syntax(from._internal_syntax()); } if (cached_has_bits & 0x00000008u) { - _this->_impl_._has_bits_[0] |= 0x00000008u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::FileOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::FileOptions::MergeFrom( + from._internal_options()); } if (cached_has_bits & 0x00000010u) { - _this->_impl_._has_bits_[0] |= 0x00000010u; - if (_this->_impl_.source_code_info_ == nullptr) { - _this->_impl_.source_code_info_ = CreateMaybeMessage<::google::protobuf::SourceCodeInfo>(arena, *from._impl_.source_code_info_); - } else { - _this->_impl_.source_code_info_->MergeFrom(*from._impl_.source_code_info_); - } + _this->_internal_mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom( + from._internal_source_code_info()); } if (cached_has_bits & 0x00000020u) { _this->_impl_.edition_ = from._impl_.edition_; @@ -3383,7 +3374,6 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 0, 2> DescriptorProto_ExtensionRange::_t void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -3392,12 +3382,8 @@ void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::Message& to_m cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::ExtensionRangeOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::ExtensionRangeOptions::MergeFrom( + from._internal_options()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.start_ = from._impl_.start_; @@ -4077,7 +4063,6 @@ constexpr ::_pbi::TcParseTable<4, 10, 8, 65, 2> DescriptorProto::_table_ = { void DescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -4104,12 +4089,8 @@ void DescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::goo _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_impl_._has_bits_[0] |= 0x00000002u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::MessageOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::MessageOptions::MergeFrom( + from._internal_options()); } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -4778,7 +4759,6 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = void ExtensionRangeOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -4791,12 +4771,8 @@ void ExtensionRangeOptions::MergeImpl(::google::protobuf::Message& to_msg, const cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.verification_ = from._impl_.verification_; @@ -5316,7 +5292,6 @@ constexpr ::_pbi::TcParseTable<4, 11, 3, 96, 2> FieldDescriptorProto::_table_ = void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -5340,12 +5315,8 @@ void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_json_name(from._internal_json_name()); } if (cached_has_bits & 0x00000020u) { - _this->_impl_._has_bits_[0] |= 0x00000020u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::FieldOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::FieldOptions::MergeFrom( + from._internal_options()); } if (cached_has_bits & 0x00000040u) { _this->_impl_.number_ = from._impl_.number_; @@ -5618,7 +5589,6 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 49, 2> OneofDescriptorProto::_table_ = { void OneofDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -5630,12 +5600,8 @@ void OneofDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_impl_._has_bits_[0] |= 0x00000002u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::OneofOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::OneofOptions::MergeFrom( + from._internal_options()); } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -6183,7 +6149,6 @@ constexpr ::_pbi::TcParseTable<3, 5, 3, 61, 2> EnumDescriptorProto::_table_ = { void EnumDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6200,12 +6165,8 @@ void EnumDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const : _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_impl_._has_bits_[0] |= 0x00000002u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::EnumOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::EnumOptions::MergeFrom( + from._internal_options()); } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -6485,7 +6446,6 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 53, 2> EnumValueDescriptorProto::_table_ void EnumValueDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6497,12 +6457,8 @@ void EnumValueDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, co _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_impl_._has_bits_[0] |= 0x00000002u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::EnumValueOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom( + from._internal_options()); } if (cached_has_bits & 0x00000004u) { _this->_impl_.number_ = from._impl_.number_; @@ -6781,7 +6737,6 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 51, 2> ServiceDescriptorProto::_table_ = void ServiceDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6795,12 +6750,8 @@ void ServiceDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, cons _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_impl_._has_bits_[0] |= 0x00000002u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::ServiceOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::ServiceOptions::MergeFrom( + from._internal_options()); } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -7167,7 +7118,6 @@ constexpr ::_pbi::TcParseTable<3, 6, 1, 71, 2> MethodDescriptorProto::_table_ = void MethodDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -7185,12 +7135,8 @@ void MethodDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_output_type(from._internal_output_type()); } if (cached_has_bits & 0x00000008u) { - _this->_impl_._has_bits_[0] |= 0x00000008u; - if (_this->_impl_.options_ == nullptr) { - _this->_impl_.options_ = CreateMaybeMessage<::google::protobuf::MethodOptions>(arena, *from._impl_.options_); - } else { - _this->_impl_.options_->MergeFrom(*from._impl_.options_); - } + _this->_internal_mutable_options()->::google::protobuf::MethodOptions::MergeFrom( + from._internal_options()); } if (cached_has_bits & 0x00000010u) { _this->_impl_.client_streaming_ = from._impl_.client_streaming_; @@ -8001,7 +7947,6 @@ constexpr ::_pbi::TcParseTable<5, 22, 3, 202, 12> FileOptions::_table_ = { void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -8044,12 +7989,8 @@ void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: _this->_internal_set_ruby_package(from._internal_ruby_package()); } if (cached_has_bits & 0x00000400u) { - _this->_impl_._has_bits_[0] |= 0x00000400u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000800u) { _this->_impl_.java_multiple_files_ = from._impl_.java_multiple_files_; @@ -8470,7 +8411,6 @@ constexpr ::_pbi::TcParseTable<3, 7, 2, 0, 7> MessageOptions::_table_ = { void MessageOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -8481,12 +8421,8 @@ void MessageOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::goog cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x0000003fu) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.message_set_wire_format_ = from._impl_.message_set_wire_format_; @@ -9269,7 +9205,6 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 0, 7> FieldOptions::_table_ = { void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9283,12 +9218,8 @@ void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x000000ffu) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.ctype_ = from._impl_.ctype_; @@ -9577,7 +9508,6 @@ constexpr ::_pbi::TcParseTable<2, 2, 2, 0, 7> OneofOptions::_table_ = { void OneofOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9586,12 +9516,8 @@ void OneofOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google _this->_internal_mutable_uninterpreted_option()->MergeFrom( from._internal_uninterpreted_option()); if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -9920,7 +9846,6 @@ constexpr ::_pbi::TcParseTable<3, 5, 2, 0, 7> EnumOptions::_table_ = { void EnumOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9931,12 +9856,8 @@ void EnumOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.allow_alias_ = from._impl_.allow_alias_; @@ -10263,7 +10184,6 @@ constexpr ::_pbi::TcParseTable<3, 4, 2, 0, 7> EnumValueOptions::_table_ = { void EnumValueOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10274,12 +10194,8 @@ void EnumValueOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::go cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; @@ -10572,7 +10488,6 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 0, 12> ServiceOptions::_table_ = { void ServiceOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10583,12 +10498,8 @@ void ServiceOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::goog cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; @@ -10914,7 +10825,6 @@ constexpr ::_pbi::TcParseTable<3, 4, 3, 0, 12> MethodOptions::_table_ = { void MethodOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10925,12 +10835,8 @@ void MethodOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::googl cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; @@ -12209,7 +12115,6 @@ constexpr ::_pbi::TcParseTable<1, 2, 2, 0, 2> FeatureSetDefaults_FeatureSetEditi void FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); - ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -12218,12 +12123,8 @@ void FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(::google::protobuf:: cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_impl_._has_bits_[0] |= 0x00000001u; - if (_this->_impl_.features_ == nullptr) { - _this->_impl_.features_ = CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); - } else { - _this->_impl_.features_->MergeFrom(*from._impl_.features_); - } + _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_features()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.edition_ = from._impl_.edition_; From 65cdac4ac5631163d0ffe08957838c754155750d Mon Sep 17 00:00:00 2001 From: Kevin King Date: Mon, 23 Oct 2023 14:50:42 -0700 Subject: [PATCH 59/95] Finish Proxied impls for rust repeated scalars PiperOrigin-RevId: 575935874 --- rust/cpp.rs | 23 +++- rust/cpp_kernel/cpp_api.cc | 42 ++++--- rust/primitive.rs | 76 +++++++++--- rust/repeated.rs | 114 ++++++++++++++++++ rust/shared.rs | 2 +- rust/test/shared/accessors_test.rs | 73 ++++++++++- rust/upb.rs | 26 +++- .../rust/accessors/singular_scalar.cc | 4 +- 8 files changed, 316 insertions(+), 44 deletions(-) diff --git a/rust/cpp.rs b/rust/cpp.rs index 6ef124070e..7c4998f875 100644 --- a/rust/cpp.rs +++ b/rust/cpp.rs @@ -197,7 +197,7 @@ pub fn copy_bytes_in_arena_if_needed_by_runtime<'a>( /// must be different fields, and not be in the same oneof. As such, a `Mut` /// cannot be `Clone` but *can* reborrow itself with `.as_mut()`, which /// converts `&'b mut Mut<'a, T>` to `Mut<'b, T>`. -#[derive(Clone, Copy)] +#[derive(Debug)] pub struct RepeatedField<'msg, T: ?Sized> { inner: RepeatedFieldInner<'msg>, _phantom: PhantomData<&'msg mut T>, @@ -206,7 +206,7 @@ pub struct RepeatedField<'msg, T: ?Sized> { /// CPP runtime-specific arguments for initializing a RepeatedField. /// See RepeatedField comment about mutation invariants for when this type can /// be copied. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct RepeatedFieldInner<'msg> { pub raw: RawRepeatedField, pub _phantom: PhantomData<&'msg ()>, @@ -217,7 +217,16 @@ impl<'msg, T: ?Sized> RepeatedField<'msg, T> { RepeatedField { inner, _phantom: PhantomData } } } -impl<'msg> RepeatedField<'msg, i32> {} + +// These use manual impls instead of derives to avoid unnecessary bounds on `T`. +// This problem is referred to as "perfect derive". +// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/ +impl<'msg, T: ?Sized> Copy for RepeatedField<'msg, T> {} +impl<'msg, T: ?Sized> Clone for RepeatedField<'msg, T> { + fn clone(&self) -> RepeatedField<'msg, T> { + *self + } +} pub trait RepeatedScalarOps { fn new_repeated_field() -> RawRepeatedField; @@ -225,6 +234,7 @@ pub trait RepeatedScalarOps { fn len(f: RawRepeatedField) -> usize; fn get(f: RawRepeatedField, i: usize) -> Self; fn set(f: RawRepeatedField, i: usize, v: Self); + fn copy_from(src: RawRepeatedField, dst: RawRepeatedField); } macro_rules! impl_repeated_scalar_ops { @@ -236,6 +246,7 @@ macro_rules! impl_repeated_scalar_ops { fn [< __pb_rust_RepeatedField_ $t _size >](f: RawRepeatedField) -> usize; fn [< __pb_rust_RepeatedField_ $t _get >](f: RawRepeatedField, i: usize) -> $t; fn [< __pb_rust_RepeatedField_ $t _set >](f: RawRepeatedField, i: usize, v: $t); + fn [< __pb_rust_RepeatedField_ $t _copy_from >](src: RawRepeatedField, dst: RawRepeatedField); } impl RepeatedScalarOps for $t { fn new_repeated_field() -> RawRepeatedField { @@ -253,6 +264,9 @@ macro_rules! impl_repeated_scalar_ops { fn set(f: RawRepeatedField, i: usize, v: Self) { unsafe { [< __pb_rust_RepeatedField_ $t _set >](f, i, v) } } + fn copy_from(src: RawRepeatedField, dst: RawRepeatedField) { + unsafe { [< __pb_rust_RepeatedField_ $t _copy_from >](src, dst) } + } } )* } }; @@ -292,6 +306,9 @@ impl<'msg, T: RepeatedScalarOps> RepeatedField<'msg, T> { } T::set(self.inner.raw, index, val) } + pub fn copy_from(&mut self, src: &RepeatedField<'_, T>) { + T::copy_from(src.inner.raw, self.inner.raw) + } } #[cfg(test)] diff --git a/rust/cpp_kernel/cpp_api.cc b/rust/cpp_kernel/cpp_api.cc index 8ff79d8fa9..1381611064 100644 --- a/rust/cpp_kernel/cpp_api.cc +++ b/rust/cpp_kernel/cpp_api.cc @@ -2,25 +2,29 @@ extern "C" { -#define expose_repeated_field_methods(ty, rust_ty) \ - google::protobuf::RepeatedField* __pb_rust_RepeatedField_##rust_ty##_new() { \ - return new google::protobuf::RepeatedField(); \ - } \ - void __pb_rust_RepeatedField_##rust_ty##_add(google::protobuf::RepeatedField* r, \ - ty val) { \ - r->Add(val); \ - } \ - size_t __pb_rust_RepeatedField_##rust_ty##_size( \ - google::protobuf::RepeatedField* r) { \ - return r->size(); \ - } \ - ty __pb_rust_RepeatedField_##rust_ty##_get(google::protobuf::RepeatedField* r, \ - size_t index) { \ - return r->Get(index); \ - } \ - void __pb_rust_RepeatedField_##rust_ty##_set(google::protobuf::RepeatedField* r, \ - size_t index, ty val) { \ - return r->Set(index, val); \ +#define expose_repeated_field_methods(ty, rust_ty) \ + google::protobuf::RepeatedField* __pb_rust_RepeatedField_##rust_ty##_new() { \ + return new google::protobuf::RepeatedField(); \ + } \ + void __pb_rust_RepeatedField_##rust_ty##_add(google::protobuf::RepeatedField* r, \ + ty val) { \ + r->Add(val); \ + } \ + size_t __pb_rust_RepeatedField_##rust_ty##_size( \ + google::protobuf::RepeatedField* r) { \ + return r->size(); \ + } \ + ty __pb_rust_RepeatedField_##rust_ty##_get(google::protobuf::RepeatedField* r, \ + size_t index) { \ + return r->Get(index); \ + } \ + void __pb_rust_RepeatedField_##rust_ty##_set(google::protobuf::RepeatedField* r, \ + size_t index, ty val) { \ + return r->Set(index, val); \ + } \ + void __pb_rust_RepeatedField_##rust_ty##_copy_from( \ + google::protobuf::RepeatedField const& src, google::protobuf::RepeatedField& dst) { \ + dst.CopyFrom(src); \ } expose_repeated_field_methods(int32_t, i32); diff --git a/rust/primitive.rs b/rust/primitive.rs index e69afe66f4..dd2fec18d4 100644 --- a/rust/primitive.rs +++ b/rust/primitive.rs @@ -7,6 +7,7 @@ use crate::__internal::Private; use crate::__runtime::InnerPrimitiveMut; +use crate::repeated::RepeatedMut; use crate::vtable::{ PrimitiveOptionalMutVTable, PrimitiveVTable, ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, RawVTableOptionalMutatorData, @@ -14,18 +15,31 @@ use crate::vtable::{ use crate::{Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy}; #[derive(Debug)] -pub struct PrimitiveMut<'a, T: ProxiedWithRawVTable> { +pub struct SingularPrimitiveMut<'a, T: ProxiedWithRawVTable> { inner: InnerPrimitiveMut<'a, T>, } +#[derive(Debug)] +pub enum PrimitiveMut<'a, T: ProxiedWithRawVTable> { + Singular(SingularPrimitiveMut<'a, T>), + Repeated(RepeatedMut<'a, T>, usize), +} + impl<'a, T: ProxiedWithRawVTable> PrimitiveMut<'a, T> { + #[doc(hidden)] + pub fn from_singular(_private: Private, inner: InnerPrimitiveMut<'a, T>) -> Self { + PrimitiveMut::Singular(SingularPrimitiveMut::from_inner(_private, inner)) + } +} + +impl<'a, T: ProxiedWithRawVTable> SingularPrimitiveMut<'a, T> { #[doc(hidden)] pub fn from_inner(_private: Private, inner: InnerPrimitiveMut<'a, T>) -> Self { Self { inner } } } -unsafe impl<'a, T: ProxiedWithRawVTable> Sync for PrimitiveMut<'a, T> {} +unsafe impl<'a, T: ProxiedWithRawVTable> Sync for SingularPrimitiveMut<'a, T> {} macro_rules! impl_singular_primitives { ($($t:ty),*) => { @@ -47,6 +61,29 @@ macro_rules! impl_singular_primitives { } } + impl<'a> PrimitiveMut<'a, $t> { + pub fn get(&self) -> View<'_, $t> { + match self { + PrimitiveMut::Singular(s) => { + s.get() + } + PrimitiveMut::Repeated(r, i) => { + r.get().get(*i).unwrap() + } + } + } + + pub fn set(&mut self, val: impl SettableValue<$t>) { + val.set_on(Private, self.as_mut()); + } + + pub fn clear(&mut self) { + // The default value for a boolean field is false and 0 for numerical types. It + // matches the Rust default values for corresponding types. Let's use this fact. + SettableValue::<$t>::set_on(<$t>::default(), Private, MutProxy::as_mut(self)); + } + } + impl<'a> ViewProxy<'a> for PrimitiveMut<'a, $t> { type Proxied = $t; @@ -61,7 +98,14 @@ macro_rules! impl_singular_primitives { impl<'a> MutProxy<'a> for PrimitiveMut<'a, $t> { fn as_mut(&mut self) -> Mut<'_, Self::Proxied> { - PrimitiveMut::from_inner(Private, self.inner) + match self { + PrimitiveMut::Singular(s) => { + PrimitiveMut::Singular(s.as_mut()) + } + PrimitiveMut::Repeated(r, i) => { + PrimitiveMut::Repeated(r.as_mut(), *i) + } + } } fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied> @@ -73,23 +117,23 @@ macro_rules! impl_singular_primitives { impl SettableValue<$t> for $t { fn set_on(self, _private: Private, mutator: Mut<'_, $t>) { - unsafe { (mutator.inner).set(self) }; + match mutator { + PrimitiveMut::Singular(s) => { + unsafe { (s.inner).set(self) }; + } + PrimitiveMut::Repeated(mut r, i) => { + r.set(i, self); + } + } } } - impl<'a> PrimitiveMut<'a, $t> { - pub fn set(&mut self, val: impl SettableValue<$t>) { - val.set_on(Private, self.as_mut()); - } - + impl<'a> SingularPrimitiveMut<'a, $t> { pub fn get(&self) -> $t { self.inner.get() } - - pub fn clear(&mut self) { - // The default value for a boolean field is false and 0 for numerical types. It - // matches the Rust default values for corresponding types. Let's use this fact. - SettableValue::<$t>::set_on(<$t>::default(), Private, MutProxy::as_mut(self)); + pub fn as_mut(&mut self) -> SingularPrimitiveMut<'_, $t> { + SingularPrimitiveMut::from_inner(Private, self.inner) } } @@ -104,7 +148,7 @@ macro_rules! impl_singular_primitives { } fn make_mut(_private: Private, inner: InnerPrimitiveMut<'_, Self>) -> Mut<'_, Self> { - PrimitiveMut::from_inner(Private, inner) + PrimitiveMut::Singular(SingularPrimitiveMut::from_inner(Private, inner)) } } @@ -121,7 +165,7 @@ macro_rules! impl_singular_primitives { fn set_absent_to_default( absent_mutator: Self::AbsentMutData<'_>, ) -> Self::PresentMutData<'_> { - absent_mutator.set_absent_to_default() + absent_mutator.set_absent_to_default() } } diff --git a/rust/repeated.rs b/rust/repeated.rs index b824de8399..1abb7152ba 100644 --- a/rust/repeated.rs +++ b/rust/repeated.rs @@ -12,8 +12,11 @@ use std::marker::PhantomData; use crate::{ + Mut, MutProxy, Proxied, SettableValue, View, ViewProxy, __internal::{Private, RawRepeatedField}, __runtime::{RepeatedField, RepeatedFieldInner}, + primitive::PrimitiveMut, + vtable::ProxiedWithRawVTable, }; #[derive(Clone, Copy)] @@ -31,6 +34,9 @@ pub struct RepeatedView<'a, T: ?Sized> { inner: RepeatedField<'a, T>, } +unsafe impl<'a, T: ProxiedWithRawVTable> Sync for RepeatedView<'a, T> {} +unsafe impl<'a, T: ProxiedWithRawVTable> Send for RepeatedView<'a, T> {} + impl<'msg, T: ?Sized> RepeatedView<'msg, T> { pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self { Self { inner: RepeatedField::<'msg>::from_inner(_private, inner) } @@ -49,14 +55,20 @@ impl<'a, T> std::fmt::Debug for RepeatedView<'a, T> { } #[repr(transparent)] +#[derive(Debug)] pub struct RepeatedMut<'a, T: ?Sized> { inner: RepeatedField<'a, T>, } +unsafe impl<'a, T: ProxiedWithRawVTable> Sync for RepeatedMut<'a, T> {} + impl<'msg, T: ?Sized> RepeatedMut<'msg, T> { pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self { Self { inner: RepeatedField::from_inner(_private, inner) } } + pub fn as_mut(&self) -> RepeatedMut<'_, T> { + Self { inner: self.inner } + } } impl<'a, T> std::ops::Deref for RepeatedMut<'a, T> { @@ -70,9 +82,67 @@ impl<'a, T> std::ops::Deref for RepeatedMut<'a, T> { } } +pub struct RepeatedFieldIterMut<'a, T> { + inner: RepeatedMut<'a, T>, + current_index: usize, +} + +pub struct Repeated(PhantomData); + macro_rules! impl_repeated_primitives { ($($t:ty),*) => { $( + impl Proxied for Repeated<$t> { + type View<'a> = RepeatedView<'a, $t>; + type Mut<'a> = RepeatedMut<'a, $t>; + } + + impl<'a> ViewProxy<'a> for RepeatedView<'a, $t> { + type Proxied = Repeated<$t>; + + fn as_view(&self) -> View<'_, Self::Proxied> { + *self + } + + fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> + where 'a: 'shorter, + { + RepeatedView { inner: self.inner } + } + } + + impl<'a> ViewProxy<'a> for RepeatedMut<'a, $t> { + type Proxied = Repeated<$t>; + + fn as_view(&self) -> View<'_, Self::Proxied> { + **self + } + + fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> + where 'a: 'shorter, + { + *self.into_mut::<'shorter>() + } + } + + impl<'a> MutProxy<'a> for RepeatedMut<'a, $t> { + fn as_mut(&mut self) -> Mut<'_, Self::Proxied> { + RepeatedMut { inner: self.inner } + } + + fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied> + where 'a: 'shorter, + { + RepeatedMut { inner: self.inner } + } + } + + impl <'a> SettableValue> for RepeatedView<'a, $t> { + fn set_on(self, _private: Private, mut mutator: Mut<'_, Repeated<$t>>) { + mutator.copy_from(self); + } + } + impl<'a> RepeatedView<'a, $t> { pub fn len(&self) -> usize { self.inner.len() @@ -83,6 +153,9 @@ macro_rules! impl_repeated_primitives { pub fn get(&self, index: usize) -> Option<$t> { self.inner.get(index) } + pub fn iter(&self) -> RepeatedFieldIter<'_, $t> { + (*self).into_iter() + } } impl<'a> RepeatedMut<'a, $t> { @@ -92,6 +165,21 @@ macro_rules! impl_repeated_primitives { pub fn set(&mut self, index: usize, val: $t) { self.inner.set(index, val) } + pub fn get_mut(&mut self, index: usize) -> Option> { + if index >= self.len() { + return None; + } + Some(PrimitiveMut::Repeated(self.as_mut(), index)) + } + pub fn iter(&self) -> RepeatedFieldIter<'_, $t> { + self.as_view().into_iter() + } + pub fn iter_mut(&mut self) -> RepeatedFieldIterMut<'_, $t> { + self.as_mut().into_iter() + } + pub fn copy_from(&mut self, src: RepeatedView<'_, $t>) { + self.inner.copy_from(&src.inner); + } } impl<'a> std::iter::Iterator for RepeatedFieldIter<'a, $t> { @@ -112,6 +200,32 @@ macro_rules! impl_repeated_primitives { RepeatedFieldIter { inner: self.inner, current_index: 0 } } } + + impl <'a> std::iter::Iterator for RepeatedFieldIterMut<'a, $t> { + type Item = Mut<'a, $t>; + fn next(&mut self) -> Option { + if self.current_index >= self.inner.len() { + return None; + } + let elem = PrimitiveMut::Repeated( + // While this appears to allow mutable aliasing + // (multiple `Self::Item`s can co-exist), each `Item` + // only references a specific unique index. + RepeatedMut{ inner: self.inner.inner }, + self.current_index, + ); + self.current_index += 1; + Some(elem) + } + } + + impl<'a> std::iter::IntoIterator for RepeatedMut<'a, $t> { + type Item = Mut<'a, $t>; + type IntoIter = RepeatedFieldIterMut<'a, $t>; + fn into_iter(self) -> Self::IntoIter { + RepeatedFieldIterMut { inner: self, current_index: 0 } + } + } )* } } diff --git a/rust/shared.rs b/rust/shared.rs index f8a9d117d9..7c3a3d163d 100644 --- a/rust/shared.rs +++ b/rust/shared.rs @@ -18,7 +18,7 @@ use std::fmt; #[doc(hidden)] pub mod __public { pub use crate::optional::{AbsentField, FieldEntry, Optional, PresentField}; - pub use crate::primitive::PrimitiveMut; + pub use crate::primitive::{PrimitiveMut, SingularPrimitiveMut}; pub use crate::proxied::{ Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy, }; diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs index ef33f21bf3..f1f55f663d 100644 --- a/rust/test/shared/accessors_test.rs +++ b/rust/test/shared/accessors_test.rs @@ -714,7 +714,47 @@ macro_rules! generate_repeated_numeric_test { assert_that!(mutator.get(0), some(eq(2 as $t))); mutator.push(1 as $t); - assert_that!(mutator.into_iter().collect::>(), eq(vec![2 as $t, 1 as $t])); + mutator.push(3 as $t); + assert_that!(mutator.get_mut(2).is_some(), eq(true)); + let mut mut_elem = mutator.get_mut(2).unwrap(); + mut_elem.set(4 as $t); + assert_that!(mut_elem.get(), eq(4 as $t)); + mut_elem.clear(); + assert_that!(mut_elem.get(), eq(0 as $t)); + + assert_that!( + mutator.iter().collect::>(), + eq(vec![2 as $t, 1 as $t, 0 as $t]) + ); + assert_that!( + (*mutator).into_iter().collect::>(), + eq(vec![2 as $t, 1 as $t, 0 as $t]) + ); + + for mut mutable_elem in msg.[]() { + mutable_elem.set(0 as $t); + } + assert_that!( + msg.[]().iter().all(|v| v == (0 as $t)), + eq(true) + ); + } + + #[test] + fn [< test_repeated_ $field _set >]() { + let mut msg = TestAllTypes::new(); + let mut mutator = msg.[](); + let mut msg2 = TestAllTypes::new(); + let mut mutator2 = msg2.[](); + for i in 0..5 { + mutator2.push(i as $t); + } + protobuf::MutProxy::set(&mut mutator, *mutator2); + + assert_that!( + mutator.iter().collect::>(), + eq(mutator2.iter().collect::>()) + ); } )* } }; @@ -742,5 +782,34 @@ fn test_repeated_bool_accessors() { mutator.set(0, false); assert_that!(mutator.get(0), some(eq(false))); mutator.push(true); - assert_that!(mutator.into_iter().collect::>(), eq(vec![false, true])); + + mutator.push(false); + assert_that!(mutator.get_mut(2), pat!(Some(_))); + let mut mut_elem = mutator.get_mut(2).unwrap(); + mut_elem.set(true); + assert_that!(mut_elem.get(), eq(true)); + mut_elem.clear(); + assert_that!(mut_elem.get(), eq(false)); + + assert_that!(mutator.iter().collect::>(), eq(vec![false, true, false])); + assert_that!((*mutator).into_iter().collect::>(), eq(vec![false, true, false])); + + for mut mutable_elem in msg.repeated_bool_mut() { + mutable_elem.set(false); + } + assert_that!(msg.repeated_bool().iter().all(|v| v), eq(false)); +} + +#[test] +fn test_repeated_bool_set() { + let mut msg = TestAllTypes::new(); + let mut mutator = msg.repeated_bool_mut(); + let mut msg2 = TestAllTypes::new(); + let mut mutator2 = msg2.repeated_bool_mut(); + for _ in 0..5 { + mutator2.push(true); + } + protobuf::MutProxy::set(&mut mutator, *mutator2); + + assert_that!(mutator.iter().collect::>(), eq(mutator2.iter().collect::>())); } diff --git a/rust/upb.rs b/rust/upb.rs index 24edbce347..b6fd7b322a 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -293,12 +293,22 @@ pub struct RepeatedFieldInner<'msg> { pub arena: &'msg Arena, } -#[derive(Clone, Copy, Debug)] +#[derive(Debug)] pub struct RepeatedField<'msg, T: ?Sized> { inner: RepeatedFieldInner<'msg>, _phantom: PhantomData<&'msg mut T>, } +// These use manual impls instead of derives to avoid unnecessary bounds on `T`. +// This problem is referred to as "perfect derive". +// https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/ +impl<'msg, T: ?Sized> Copy for RepeatedField<'msg, T> {} +impl<'msg, T: ?Sized> Clone for RepeatedField<'msg, T> { + fn clone(&self) -> RepeatedField<'msg, T> { + *self + } +} + impl<'msg, T: ?Sized> RepeatedField<'msg, T> { pub fn len(&self) -> usize { unsafe { upb_Array_Size(self.inner.raw) } @@ -352,6 +362,7 @@ extern "C" { fn upb_Array_Set(arr: RawRepeatedField, i: usize, val: upb_MessageValue); fn upb_Array_Get(arr: RawRepeatedField, i: usize) -> upb_MessageValue; fn upb_Array_Append(arr: RawRepeatedField, val: upb_MessageValue, arena: RawArena); + fn upb_Array_Resize(arr: RawRepeatedField, size: usize, arena: RawArena); } macro_rules! impl_repeated_primitives { @@ -392,6 +403,19 @@ macro_rules! impl_repeated_primitives { upb_MessageValue { $union_field: val }, ) } } + pub fn copy_from(&mut self, src: &RepeatedField<'_, $rs_type>) { + // TODO: Optimize this copy_from implementation using memcopy. + // NOTE: `src` cannot be `self` because this would violate borrowing rules. + unsafe { upb_Array_Resize(self.inner.raw, 0, self.inner.arena.raw()) }; + // `upb_Array_DeepClone` is not used here because it returns + // a new `upb_Array*`. The contained `RawRepeatedField` must + // then be set to this new pointer, but other copies of this + // pointer may exist because of re-borrowed `RepeatedMut`s. + // Alternatively, a `clone_into` method could be exposed by upb. + for i in 0..src.len() { + self.push(src.get(i).unwrap()); + } + } } )* } diff --git a/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc b/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc index 818dc7ce9b..b7b7a55643 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc @@ -162,7 +162,7 @@ void SingularScalar::InMsgImpl(Context field) const { )rs"); } else { field.Emit({}, R"rs( - pub fn r#$field$_mut(&mut self) -> $pb$::PrimitiveMut<'_, $Scalar$> { + pub fn r#$field$_mut(&mut self) -> $pb$::Mut<'_, $Scalar$> { static VTABLE: $pbi$::PrimitiveVTable<$Scalar$> = $pbi$::PrimitiveVTable::new( $pbi$::Private, @@ -170,7 +170,7 @@ void SingularScalar::InMsgImpl(Context field) const { $setter_thunk$, ); - $pb$::PrimitiveMut::from_inner( + $pb$::PrimitiveMut::from_singular( $pbi$::Private, unsafe { $pbi$::RawVTableMutator::new( From c68554cc24e2d0bd35757f07bcc7f87db13bac04 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 24 Oct 2023 06:57:24 -0700 Subject: [PATCH 60/95] Optimize RepeatedPtrField constructors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Writing zeros is faster as they are often available in the cache as well as it can be done with less instructions on common platforms. ``` BM_RepeatedPtrField_Ctor 125ns ± 3% 118ns ± 3% -5.34% (p=0.000 n=217+219) ``` PiperOrigin-RevId: 576126835 --- src/google/protobuf/repeated_ptr_field.cc | 31 ++++--- src/google/protobuf/repeated_ptr_field.h | 102 +++++++++++++--------- 2 files changed, 80 insertions(+), 53 deletions(-) diff --git a/src/google/protobuf/repeated_ptr_field.cc b/src/google/protobuf/repeated_ptr_field.cc index 19b4ca59c4..734a6a7188 100644 --- a/src/google/protobuf/repeated_ptr_field.cc +++ b/src/google/protobuf/repeated_ptr_field.cc @@ -20,6 +20,7 @@ #include "absl/log/absl_check.h" #include "google/protobuf/arena.h" #include "google/protobuf/implicit_weak_message.h" +#include "google/protobuf/message_lite.h" #include "google/protobuf/port.h" #include "google/protobuf/repeated_field.h" @@ -34,10 +35,11 @@ namespace internal { void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { ABSL_DCHECK(extend_amount > 0); constexpr size_t ptr_size = sizeof(rep()->elements[0]); - int new_capacity = total_size_ + extend_amount; + int capacity = Capacity(); + int new_capacity = capacity + extend_amount; Arena* arena = GetArena(); new_capacity = internal::CalculateReserveSize( - total_size_, new_capacity); + capacity, new_capacity); ABSL_CHECK_LE( static_cast(new_capacity), static_cast( @@ -45,7 +47,6 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { << "Requested size is too large to fit into size_t."; size_t bytes = kRepHeaderSize + ptr_size * new_capacity; Rep* new_rep; - void* old_tagged_ptr = tagged_rep_or_elem_; if (arena == nullptr) { internal::SizedPtr res = internal::AllocateAtLeast(bytes); new_capacity = static_cast((res.n - kRepHeaderSize) / ptr_size); @@ -55,18 +56,17 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { } if (using_sso()) { - new_rep->allocated_size = old_tagged_ptr != nullptr ? 1 : 0; - new_rep->elements[0] = old_tagged_ptr; + new_rep->allocated_size = tagged_rep_or_elem_ != nullptr ? 1 : 0; + new_rep->elements[0] = tagged_rep_or_elem_; } else { - Rep* old_rep = - reinterpret_cast(reinterpret_cast(old_tagged_ptr) - 1); + Rep* old_rep = rep(); if (old_rep->allocated_size > 0) { memcpy(new_rep->elements, old_rep->elements, old_rep->allocated_size * ptr_size); } new_rep->allocated_size = old_rep->allocated_size; - size_t old_size = total_size_ * ptr_size + kRepHeaderSize; + size_t old_size = capacity * ptr_size + kRepHeaderSize; if (arena == nullptr) { internal::SizedDelete(old_rep, old_size); } else { @@ -76,13 +76,14 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { tagged_rep_or_elem_ = reinterpret_cast(reinterpret_cast(new_rep) + 1); - total_size_ = new_capacity; + capacity_proxy_ = new_capacity - kSSOCapacity; return &new_rep->elements[current_size_]; } void RepeatedPtrFieldBase::Reserve(int capacity) { - if (capacity > total_size_) { - InternalExtend(capacity - total_size_); + int delta = capacity - Capacity(); + if (delta > 0) { + InternalExtend(delta); } } @@ -98,7 +99,7 @@ void RepeatedPtrFieldBase::DestroyProtos() { for (int i = 0; i < n; i++) { delete static_cast(elements[i]); } - const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize; + const size_t size = Capacity() * sizeof(elements[0]) + kRepHeaderSize; internal::SizedDelete(r, size); } @@ -115,7 +116,9 @@ void* RepeatedPtrFieldBase::AddOutOfLineHelper(void* obj) { ExchangeCurrentSize(1); return tagged_rep_or_elem_ = obj; } - if (using_sso() || rep()->allocated_size == total_size_) { + // Not using `AllocatedSizeAtCapacity` because it's already known that + // `tagged_rep_or_elem_ != nullptr`. + if (using_sso() || rep()->allocated_size >= Capacity()) { InternalExtend(1); // Equivalent to "Reserve(total_size_ + 1)" } Rep* r = rep(); @@ -134,7 +137,7 @@ void* RepeatedPtrFieldBase::AddOutOfLineHelper(ElementFactory factory) { } else { absl::PrefetchToLocalCache(rep()); } - if (PROTOBUF_PREDICT_FALSE(current_size_ == total_size_)) { + if (PROTOBUF_PREDICT_FALSE(SizeAtCapacity())) { InternalExtend(1); } else { Rep* r = rep(); diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index 5894e777e2..fe38aac865 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -177,12 +177,12 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { constexpr RepeatedPtrFieldBase() : tagged_rep_or_elem_(nullptr), current_size_(0), - total_size_(kSSOCapacity), + capacity_proxy_(0), arena_(nullptr) {} explicit RepeatedPtrFieldBase(Arena* arena) : tagged_rep_or_elem_(nullptr), current_size_(0), - total_size_(kSSOCapacity), + capacity_proxy_(0), arena_(arena) {} RepeatedPtrFieldBase(const RepeatedPtrFieldBase&) = delete; @@ -198,7 +198,13 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { bool empty() const { return current_size_ == 0; } int size() const { return current_size_; } - int Capacity() const { return total_size_; } + // Returns the size of the buffer with pointers to elements. + // + // Note: + // + // * prefer `SizeAtCapacity()` to `size() == Capacity()`; + // * prefer `AllocatedSizeAtCapacity()` to `allocated_size() == Capacity()`. + int Capacity() const { return capacity_proxy_ + kSSOCapacity; } template const Value& at(int index) const { @@ -271,7 +277,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { } if (!using_sso()) { internal::SizedDelete(rep(), - total_size_ * sizeof(elems[0]) + kRepHeaderSize); + Capacity() * sizeof(elems[0]) + kRepHeaderSize); } } @@ -417,7 +423,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { size_t allocated_bytes = using_sso() ? 0 - : static_cast(total_size_) * sizeof(void*) + kRepHeaderSize; + : static_cast(Capacity()) * sizeof(void*) + kRepHeaderSize; const int n = allocated_size(); void* const* elems = elements(); for (int i = 0; i < n; ++i) { @@ -451,11 +457,11 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { void UnsafeArenaAddAllocated(Value* value) { ABSL_DCHECK_NE(value, nullptr); // Make room for the new pointer. - if (current_size_ == total_size_) { + if (SizeAtCapacity()) { // The array is completely full with no cleared objects, so grow it. - Reserve(total_size_ + 1); + InternalExtend(1); ++rep()->allocated_size; - } else if (allocated_size() == total_size_) { + } else if (AllocatedSizeAtCapacity()) { // There is no more space in the pointer array because it contains some // cleared objects awaiting reuse. We don't want to grow the array in // this case because otherwise a loop calling AddAllocated() followed by @@ -539,41 +545,41 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { void AddAllocatedInternal(Value* value, std::true_type) { Arena* element_arena = TypeHandler::GetArena(value); Arena* arena = GetArena(); - if (arena == element_arena && allocated_size() < total_size_) { - // Fast path: underlying arena representation (tagged pointer) is equal to - // our arena pointer, and we can add to array without resizing it (at - // least one slot that is not allocated). - void** elems = elements(); - if (current_size_ < allocated_size()) { - // Make space at [current] by moving first allocated element to end of - // allocated list. - elems[allocated_size()] = elems[current_size_]; - } - elems[ExchangeCurrentSize(current_size_ + 1)] = value; - if (!using_sso()) ++rep()->allocated_size; - } else { + if (arena != element_arena || AllocatedSizeAtCapacity()) { AddAllocatedSlowWithCopy(value, element_arena, arena); + return; + } + // Fast path: underlying arena representation (tagged pointer) is equal to + // our arena pointer, and we can add to array without resizing it (at + // least one slot that is not allocated). + void** elems = elements(); + if (current_size_ < allocated_size()) { + // Make space at [current] by moving first allocated element to end of + // allocated list. + elems[allocated_size()] = elems[current_size_]; } + elems[ExchangeCurrentSize(current_size_ + 1)] = value; + if (!using_sso()) ++rep()->allocated_size; } // AddAllocated version that does not implement arena-safe copying behavior. template void AddAllocatedInternal(Value* value, std::false_type) { - if (allocated_size() < total_size_) { - // Fast path: underlying arena representation (tagged pointer) is equal to - // our arena pointer, and we can add to array without resizing it (at - // least one slot that is not allocated). - void** elems = elements(); - if (current_size_ < allocated_size()) { - // Make space at [current] by moving first allocated element to end of - // allocated list. - elems[allocated_size()] = elems[current_size_]; - } - elems[ExchangeCurrentSize(current_size_ + 1)] = value; - if (!using_sso()) ++rep()->allocated_size; - } else { + if (AllocatedSizeAtCapacity()) { UnsafeArenaAddAllocated(value); + return; } + // Fast path: underlying arena representation (tagged pointer) is equal to + // our arena pointer, and we can add to array without resizing it (at + // least one slot that is not allocated). + void** elems = elements(); + if (current_size_ < allocated_size()) { + // Make space at [current] by moving first allocated element to end of + // allocated list. + elems[allocated_size()] = elems[current_size_]; + } + elems[ExchangeCurrentSize(current_size_ + 1)] = value; + if (!using_sso()) ++rep()->allocated_size; } // Slowpath handles all cases, copying if necessary. @@ -715,6 +721,25 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { inline int ExchangeCurrentSize(int new_size) { return std::exchange(current_size_, new_size); } + inline bool SizeAtCapacity() const { + // Harden invariant size() <= allocated_size() <= Capacity(). + ABSL_DCHECK_LE(size(), allocated_size()); + ABSL_DCHECK_LE(allocated_size(), Capacity()); + // This is equivalent to `current_size_ == Capacity()`. + // Assuming `Capacity()` function is inlined, compiler is likely to optimize + // away "+ kSSOCapacity" and reduce it to "current_size_ > capacity_proxy_" + // which is an instruction less than "current_size_ == capacity_proxy_ + 1". + return current_size_ >= Capacity(); + } + inline bool AllocatedSizeAtCapacity() const { + // Harden invariant size() <= allocated_size() <= Capacity(). + ABSL_DCHECK_LE(size(), allocated_size()); + ABSL_DCHECK_LE(allocated_size(), Capacity()); + // This combines optimization mentioned in `SizeAtCapacity()` and simplifies + // `allocated_size()` in sso case. + return using_sso() ? (tagged_rep_or_elem_ != nullptr) + : rep()->allocated_size >= Capacity(); + } void* const* elements() const { return using_sso() ? &tagged_rep_or_elem_ : +rep()->elements; @@ -800,8 +825,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // Ensures that capacity is big enough to store one more allocated element. inline void MaybeExtend() { - if (using_sso() ? (tagged_rep_or_elem_ != nullptr) - : (rep()->allocated_size == total_size_)) { + if (AllocatedSizeAtCapacity()) { ABSL_DCHECK_EQ(allocated_size(), Capacity()); InternalExtend(1); } else { @@ -812,11 +836,11 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // Ensures that capacity is at least `n` elements. // Returns a pointer to the element directly beyond the last element. inline void** InternalReserve(int n) { - if (n <= total_size_) { + if (n <= Capacity()) { void** elements = using_sso() ? &tagged_rep_or_elem_ : rep()->elements; return elements + current_size_; } - return InternalExtend(n - total_size_); + return InternalExtend(n - Capacity()); } // Internal helper for Add: adds "obj" as the next element in the @@ -838,7 +862,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // significant performance for memory-sensitive workloads. void* tagged_rep_or_elem_; int current_size_; - int total_size_; + int capacity_proxy_; // we store `capacity - kSSOCapacity` as an optimization Arena* arena_; }; From 4d921064518ee66fb1a1a27935d5d16c3aa7e402 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 24 Oct 2023 07:06:20 -0700 Subject: [PATCH 61/95] Make SpaceUsedLong non-virtual to reduce the size of the vtable. PiperOrigin-RevId: 576128619 --- src/google/protobuf/message.cc | 8 +++++++- src/google/protobuf/message.h | 11 ++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index eb81694daf..2cf07dbdf4 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -188,7 +188,13 @@ size_t Message::MaybeComputeUnknownFieldsSize( } size_t Message::SpaceUsedLong() const { - return GetReflection()->SpaceUsedLong(*this); + auto* reflection = GetReflection(); + if (PROTOBUF_PREDICT_TRUE(reflection != nullptr)) { + return reflection->SpaceUsedLong(*this); + } + // The only case that does not have reflection is RawMessage. + return internal::DownCast(*this) + .SpaceUsedLong(); } static std::string GetTypeNameImpl(const MessageLite& msg) { diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 83ba793e93..47f41b89ec 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -286,8 +286,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { void DiscardUnknownFields(); // Computes (an estimate of) the total number of bytes currently used for - // storing the message in memory. The default implementation calls the - // Reflection object's SpaceUsed() method. + // storing the message in memory. // // SpaceUsed() is noticeably slower than ByteSize(), as it is implemented // using reflection (rather than the generated code implementation for @@ -297,7 +296,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // Note: The precise value of this method should never be depended on, and can // change substantially due to internal details. In debug builds, this will // include a random fuzz factor to prevent these dependencies. - virtual size_t SpaceUsedLong() const; + size_t SpaceUsedLong() const; [[deprecated("Please use SpaceUsedLong() instead")]] int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); @@ -1573,6 +1572,12 @@ bool SplitFieldHasExtraIndirectionStatic(const FieldDescriptor* field) { return ret; } +class RawMessageBase : public Message { + public: + using Message::Message; + virtual size_t SpaceUsedLong() const = 0; +}; + } // namespace internal template From a14f29e40aa28cd9140d19f0f063752b44f9dd29 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 24 Oct 2023 07:32:19 -0700 Subject: [PATCH 62/95] Internal change PiperOrigin-RevId: 576133829 --- rust/test/shared/BUILD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rust/test/shared/BUILD b/rust/test/shared/BUILD index b2c4aaf164..73be626f76 100644 --- a/rust/test/shared/BUILD +++ b/rust/test/shared/BUILD @@ -257,11 +257,19 @@ rust_test( rust_test( name = "simple_nested_cpp_test", srcs = ["simple_nested_test.rs"], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], deps = ["//rust/test:nested_cc_rust_proto"], ) rust_test( name = "simple_nested_upb_test", srcs = ["simple_nested_test.rs"], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], deps = ["//rust/test:nested_upb_rust_proto"], ) From d76a6300d29d8d9feeeadddc28925ebd610b1f31 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 24 Oct 2023 10:50:34 -0700 Subject: [PATCH 63/95] Automated rollback of commit 4d921064518ee66fb1a1a27935d5d16c3aa7e402. PiperOrigin-RevId: 576194379 --- src/google/protobuf/message.cc | 8 +------- src/google/protobuf/message.h | 11 +++-------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 2cf07dbdf4..eb81694daf 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -188,13 +188,7 @@ size_t Message::MaybeComputeUnknownFieldsSize( } size_t Message::SpaceUsedLong() const { - auto* reflection = GetReflection(); - if (PROTOBUF_PREDICT_TRUE(reflection != nullptr)) { - return reflection->SpaceUsedLong(*this); - } - // The only case that does not have reflection is RawMessage. - return internal::DownCast(*this) - .SpaceUsedLong(); + return GetReflection()->SpaceUsedLong(*this); } static std::string GetTypeNameImpl(const MessageLite& msg) { diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 47f41b89ec..83ba793e93 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -286,7 +286,8 @@ class PROTOBUF_EXPORT Message : public MessageLite { void DiscardUnknownFields(); // Computes (an estimate of) the total number of bytes currently used for - // storing the message in memory. + // storing the message in memory. The default implementation calls the + // Reflection object's SpaceUsed() method. // // SpaceUsed() is noticeably slower than ByteSize(), as it is implemented // using reflection (rather than the generated code implementation for @@ -296,7 +297,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // Note: The precise value of this method should never be depended on, and can // change substantially due to internal details. In debug builds, this will // include a random fuzz factor to prevent these dependencies. - size_t SpaceUsedLong() const; + virtual size_t SpaceUsedLong() const; [[deprecated("Please use SpaceUsedLong() instead")]] int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); @@ -1572,12 +1573,6 @@ bool SplitFieldHasExtraIndirectionStatic(const FieldDescriptor* field) { return ret; } -class RawMessageBase : public Message { - public: - using Message::Message; - virtual size_t SpaceUsedLong() const = 0; -}; - } // namespace internal template From a286c9b56d6fd81984cb510f1db902ec96fd34c7 Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Wed, 25 Oct 2023 13:40:04 -0700 Subject: [PATCH 64/95] upb: create upb/reflection/BUILD PiperOrigin-RevId: 576631037 --- .github/workflows/test_upb.yml | 2 +- upb/BUILD | 215 +++++++-------------------------- upb/reflection/BUILD | 174 ++++++++++++++++++++++++++ upb_generator/BUILD | 22 ++-- 4 files changed, 227 insertions(+), 186 deletions(-) create mode 100644 upb/reflection/BUILD diff --git a/.github/workflows/test_upb.yml b/.github/workflows/test_upb.yml index 21ec308876..f2c1cfa2e4 100644 --- a/.github/workflows/test_upb.yml +++ b/.github/workflows/test_upb.yml @@ -76,7 +76,7 @@ jobs: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: "upb-bazel-windows" bazel: test --cxxopt=/std:c++17 --host_cxxopt=/std:c++17 //upb/... //upb_generator/... //python/... //protos/... //protos_generator/... - exclude-targets: -//python:conformance_test -//upb:def_builder_test + exclude-targets: -//python:conformance_test -//upb/reflection:def_builder_test macos: strategy: diff --git a/upb/BUILD b/upb/BUILD index 02d65bdee2..16c67b17e0 100644 --- a/upb/BUILD +++ b/upb/BUILD @@ -8,14 +8,7 @@ load("@rules_python//python:defs.bzl", "py_binary") load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") load("//bazel:build_defs.bzl", "UPB_DEFAULT_COPTS") -load("//bazel:upb_minitable_proto_library.bzl", "upb_minitable_proto_library") -load("//bazel:upb_proto_library.bzl", "upb_proto_reflection_library") load("//bazel:upb_proto_library_internal/copts.bzl", "upb_proto_library_copts") -load( - "//upb_generator:bootstrap_compiler.bzl", - "bootstrap_cc_library", - "bootstrap_upb_proto_library", -) # begin:google_only # load("//tools/build_defs/kotlin/native:rules.bzl", "kt_native_interop_hint") @@ -111,7 +104,7 @@ cc_library( hdrs = ["generated_code_support.h"], copts = UPB_DEFAULT_COPTS, textual_hdrs = [ - "//upb/port:inc", + ":port_inc", ], visibility = ["//visibility:public"], deps = [ @@ -133,176 +126,54 @@ cc_library( name = "generated_cpp_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", copts = UPB_DEFAULT_COPTS, textual_hdrs = [ - "//upb/port:inc", + ":port_inc", ], visibility = ["//visibility:public"], ) -cc_library( - name = "generated_reflection_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", - hdrs = [ - "reflection/def.h", - "reflection/internal/def_pool.h", - ], - copts = UPB_DEFAULT_COPTS, - textual_hdrs = [ - "//upb/port:inc", - ], - visibility = ["//visibility:public"], - deps = [ - ":mem", - ":mini_descriptor", - ":reflection_internal", - ], -) +# Aliases ###################################################################### +# TODO: Remove these. -bootstrap_upb_proto_library( - name = "descriptor_upb_proto", - base_dir = "reflection/", - # TODO: Export 'net/proto2/proto/descriptor.upb.h' and remove "-layering_check". - features = ["-layering_check"], - google3_src_files = ["net/proto2/proto/descriptor.proto"], - google3_src_rules = ["//net/proto2/proto:descriptor_proto_source"], - oss_src_files = ["google/protobuf/descriptor.proto"], - oss_src_rules = ["//:descriptor_proto_srcs"], - oss_strip_prefix = "third_party/protobuf/github/bootstrap/src", - proto_lib_deps = ["//:descriptor_proto"], +alias( + name = "base", + actual = "//upb/base", visibility = ["//visibility:public"], ) -upb_proto_reflection_library( - name = "descriptor_upb_proto_reflection", +alias( + name = "base_internal", + actual = "//upb/base:internal", visibility = ["//visibility:public"], - deps = ["//:descriptor_proto"], ) -upb_minitable_proto_library( - name = "descriptor_upb_minitable_proto", - visibility = [ - "//upb:__subpackages__", - # begin:github_only - "//python:__subpackages__", - # end:github_only - ], - deps = ["//:descriptor_proto"], -) - -# TODO: Once we can delete the deprecated forwarding headers -# (= everything in upb/) we can move this build target down into reflection/ -bootstrap_cc_library( - name = "reflection", - hdrs = [ - "reflection/def.h", - "reflection/def.hpp", - "reflection/message.h", - "reflection/message.hpp", - ], - bootstrap_deps = [":reflection_internal"], - copts = UPB_DEFAULT_COPTS, +alias( + name = "collections", + actual = "//upb/collections", + deprecation = "use upb:message instead", visibility = ["//visibility:public"], - deps = [ - ":base", - ":mem", - ":message", - ":message_types", - ":message_value", - ":port", - ], ) -bootstrap_cc_library( - name = "reflection_internal", - srcs = [ - "reflection/def_pool.c", - "reflection/def_type.c", - "reflection/desc_state.c", - "reflection/enum_def.c", - "reflection/enum_reserved_range.c", - "reflection/enum_value_def.c", - "reflection/extension_range.c", - "reflection/field_def.c", - "reflection/file_def.c", - "reflection/internal/def_builder.c", - "reflection/internal/def_builder.h", - "reflection/internal/strdup2.c", - "reflection/internal/strdup2.h", - "reflection/message.c", - "reflection/message_def.c", - "reflection/message_reserved_range.c", - "reflection/method_def.c", - "reflection/oneof_def.c", - "reflection/service_def.c", - ], - hdrs = [ - "reflection/common.h", - "reflection/def.h", - "reflection/def.hpp", - "reflection/def_pool.h", - "reflection/def_type.h", - "reflection/enum_def.h", - "reflection/enum_reserved_range.h", - "reflection/enum_value_def.h", - "reflection/extension_range.h", - "reflection/field_def.h", - "reflection/file_def.h", - "reflection/internal/def_pool.h", - "reflection/internal/desc_state.h", - "reflection/internal/enum_def.h", - "reflection/internal/enum_reserved_range.h", - "reflection/internal/enum_value_def.h", - "reflection/internal/extension_range.h", - "reflection/internal/field_def.h", - "reflection/internal/file_def.h", - "reflection/internal/message_def.h", - "reflection/internal/message_reserved_range.h", - "reflection/internal/method_def.h", - "reflection/internal/oneof_def.h", - "reflection/internal/service_def.h", - "reflection/message.h", - "reflection/message.hpp", - "reflection/message_def.h", - "reflection/message_reserved_range.h", - "reflection/method_def.h", - "reflection/oneof_def.h", - "reflection/service_def.h", - ], - bootstrap_deps = [":descriptor_upb_proto"], - copts = UPB_DEFAULT_COPTS, +alias( + name = "descriptor_upb_proto", + actual = "//upb/reflection:descriptor_upb_proto", visibility = ["//visibility:public"], - deps = [ - ":base", - ":hash", - ":mem", - ":message", - ":message_accessors", - ":message_types", - ":message_value", - ":mini_descriptor", - ":mini_descriptor_internal", - ":mini_table", - ":port", - ], ) -# Aliases ###################################################################### -# TODO: Remove these. - alias( - name = "base", - actual = "//upb/base", + name = "descriptor_upb_minitable_proto", + actual = "//upb/reflection:descriptor_upb_minitable_proto", visibility = ["//visibility:public"], ) alias( - name = "base_internal", - actual = "//upb/base:internal", + name = "descriptor_upb_proto_reflection", + actual = "//upb/reflection:descriptor_upb_proto_reflection", visibility = ["//visibility:public"], ) alias( - name = "collections", - actual = "//upb/collections", - deprecation = "use upb:message instead", + name = "generated_reflection_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", + actual = "//upb/reflection:generated_reflection_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", visibility = ["//visibility:public"], ) @@ -438,6 +309,24 @@ alias( visibility = ["//visibility:public"], ) +alias( + name = "port_inc", + actual = "//upb/port:inc", + visibility = ["//visibility:public"], +) + +alias( + name = "reflection", + actual = "//upb/reflection", + visibility = ["//visibility:public"], +) + +alias( + name = "reflection_internal", + actual = "//upb/reflection:internal", + visibility = ["//visibility:public"], +) + alias( name = "text", actual = "//upb/text", @@ -474,28 +363,6 @@ alias( visibility = ["//visibility:public"], ) -# Tests ######################################################################## - -cc_test( - name = "def_builder_test", - srcs = [ - "reflection/common.h", - "reflection/def_type.h", - "reflection/internal/def_builder.h", - "reflection/internal/def_builder_test.cc", - ], - deps = [ - ":descriptor_upb_proto", - ":hash", - ":mem", - ":port", - ":reflection", - ":reflection_internal", - "@com_google_googletest//:gtest_main", - "@com_google_absl//absl/strings", - ], -) - # Internal C/C++ libraries ##################################################### cc_binary( diff --git a/upb/reflection/BUILD b/upb/reflection/BUILD new file mode 100644 index 0000000000..380ae38e51 --- /dev/null +++ b/upb/reflection/BUILD @@ -0,0 +1,174 @@ +# Copyright (c) 2009-2021, Google LLC +# All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +load("//bazel:build_defs.bzl", "UPB_DEFAULT_COPTS") +load("//bazel:upb_minitable_proto_library.bzl", "upb_minitable_proto_library") +load("//bazel:upb_proto_library.bzl", "upb_proto_reflection_library") +load( + "//upb_generator:bootstrap_compiler.bzl", + "bootstrap_cc_library", + "bootstrap_upb_proto_library", +) + +bootstrap_upb_proto_library( + name = "descriptor_upb_proto", + base_dir = "", + # TODO: Export 'net/proto2/proto/descriptor.upb.h' and remove "-layering_check". + features = ["-layering_check"], + google3_src_files = ["net/proto2/proto/descriptor.proto"], + google3_src_rules = ["//net/proto2/proto:descriptor_proto_source"], + oss_src_files = ["google/protobuf/descriptor.proto"], + oss_src_rules = ["//:descriptor_proto_srcs"], + oss_strip_prefix = "third_party/protobuf/github/bootstrap/src", + proto_lib_deps = ["//:descriptor_proto"], + visibility = ["//visibility:public"], +) + +upb_proto_reflection_library( + name = "descriptor_upb_proto_reflection", + visibility = ["//visibility:public"], + deps = ["//:descriptor_proto"], +) + +upb_minitable_proto_library( + name = "descriptor_upb_minitable_proto", + visibility = ["//visibility:public"], + deps = ["//:descriptor_proto"], +) + +bootstrap_cc_library( + name = "reflection", + hdrs = [ + "def.h", + "def.hpp", + "message.h", + "message.hpp", + ], + bootstrap_deps = [":internal"], + copts = UPB_DEFAULT_COPTS, + visibility = ["//visibility:public"], + deps = [ + "//upb:base", + "//upb:mem", + "//upb:message", + "//upb:message_types", + "//upb:message_value", + "//upb:port", + ], +) + +bootstrap_cc_library( + name = "internal", + srcs = [ + "def_pool.c", + "def_type.c", + "desc_state.c", + "enum_def.c", + "enum_reserved_range.c", + "enum_value_def.c", + "extension_range.c", + "field_def.c", + "file_def.c", + "internal/def_builder.c", + "internal/def_builder.h", + "internal/strdup2.c", + "internal/strdup2.h", + "message.c", + "message_def.c", + "message_reserved_range.c", + "method_def.c", + "oneof_def.c", + "service_def.c", + ], + hdrs = [ + "common.h", + "def.h", + "def.hpp", + "def_pool.h", + "def_type.h", + "enum_def.h", + "enum_reserved_range.h", + "enum_value_def.h", + "extension_range.h", + "field_def.h", + "file_def.h", + "internal/def_pool.h", + "internal/desc_state.h", + "internal/enum_def.h", + "internal/enum_reserved_range.h", + "internal/enum_value_def.h", + "internal/extension_range.h", + "internal/field_def.h", + "internal/file_def.h", + "internal/message_def.h", + "internal/message_reserved_range.h", + "internal/method_def.h", + "internal/oneof_def.h", + "internal/service_def.h", + "message.h", + "message.hpp", + "message_def.h", + "message_reserved_range.h", + "method_def.h", + "oneof_def.h", + "service_def.h", + ], + bootstrap_deps = [":descriptor_upb_proto"], + copts = UPB_DEFAULT_COPTS, + visibility = ["//visibility:public"], + deps = [ + "//upb:base", + "//upb:hash", + "//upb:mem", + "//upb:message", + "//upb:message_accessors", + "//upb:message_types", + "//upb:message_value", + "//upb:mini_descriptor", + "//upb:mini_descriptor_internal", + "//upb:mini_table", + "//upb:port", + ], +) + +cc_library( + name = "generated_reflection_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", + hdrs = [ + "def.h", + "internal/def_pool.h", + ], + copts = UPB_DEFAULT_COPTS, + textual_hdrs = [ + "//upb:port_inc", + ], + visibility = ["//visibility:public"], + deps = [ + "//upb:mem", + "//upb:mini_descriptor", + "//upb:reflection_internal", + ], +) + +cc_test( + name = "def_builder_test", + srcs = [ + "common.h", + "def_type.h", + "internal/def_builder.h", + "internal/def_builder_test.cc", + ], + deps = [ + ":descriptor_upb_proto", + "@com_google_googletest//:gtest_main", + "//upb:hash", + "//upb:mem", + "//upb:port", + "//upb:reflection", + "//upb:reflection_internal", + "@com_google_absl//absl/strings", + ], +) diff --git a/upb_generator/BUILD b/upb_generator/BUILD index 79f2ac3649..723d490402 100644 --- a/upb_generator/BUILD +++ b/upb_generator/BUILD @@ -79,7 +79,7 @@ bootstrap_upb_proto_library( oss_strip_prefix = "third_party/protobuf/github/bootstrap/src", proto_lib_deps = ["//:compiler_plugin_proto"], visibility = ["//upb:friends"], - deps = ["//upb:descriptor_upb_proto"], + deps = ["//upb/reflection:descriptor_upb_proto"], ) upb_proto_reflection_library( @@ -97,7 +97,7 @@ bootstrap_cc_library( "common.h", ], bootstrap_deps = [ - "//upb:reflection", + "//upb/reflection:reflection", ], copts = UPB_DEFAULT_CPPOPTS, visibility = ["//protos_generator:__pkg__"], @@ -119,8 +119,8 @@ bootstrap_cc_library( ], bootstrap_deps = [ ":common", - "//upb:reflection", - "//upb:descriptor_upb_proto", + "//upb/reflection:reflection", + "//upb/reflection:descriptor_upb_proto", ], copts = UPB_DEFAULT_CPPOPTS, visibility = ["//visibility:public"], @@ -154,8 +154,8 @@ bootstrap_cc_library( ], bootstrap_deps = [ ":plugin_upb_proto", - "//upb:descriptor_upb_proto", - "//upb:reflection", + "//upb/reflection:descriptor_upb_proto", + "//upb/reflection:reflection", ], copts = UPB_DEFAULT_CPPOPTS, visibility = ["//protos_generator:__pkg__"], @@ -177,7 +177,7 @@ bootstrap_cc_library( "names.h", ], bootstrap_deps = [ - "//upb:reflection", + "//upb/reflection:reflection", ], copts = UPB_DEFAULT_CPPOPTS, visibility = ["//protos_generator:__pkg__"], @@ -244,8 +244,8 @@ bootstrap_cc_binary( ":names", ":plugin", ":plugin_upb_proto", - "//upb:descriptor_upb_proto", - "//upb:reflection", + "//upb/reflection:descriptor_upb_proto", + "//upb/reflection:reflection", ], copts = UPB_DEFAULT_CPPOPTS, visibility = ["//visibility:public"], @@ -283,8 +283,8 @@ bootstrap_cc_binary( ":names", ":plugin", ":plugin_upb_proto", - "//upb:descriptor_upb_proto", - "//upb:reflection", + "//upb/reflection:descriptor_upb_proto", + "//upb/reflection:reflection", ], copts = UPB_DEFAULT_CPPOPTS, visibility = ["//visibility:public"], From 6df7f0bbef9643f4fdf5c340a49988298044824d Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 25 Oct 2023 21:04:53 -0700 Subject: [PATCH 65/95] Internal changes PiperOrigin-RevId: 576731159 --- src/google/protobuf/descriptor.pb.cc | 18 +++++++++--------- src/google/protobuf/descriptor.pb.h | 10 +++++----- src/google/protobuf/descriptor.proto | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index ae02aa9a2d..88308d71f4 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -1864,8 +1864,8 @@ const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] AB "SED\020\002\"V\n\025RepeatedFieldEncoding\022#\n\037REPEAT" "ED_FIELD_ENCODING_UNKNOWN\020\000\022\n\n\006PACKED\020\001\022" "\014\n\010EXPANDED\020\002\"C\n\016Utf8Validation\022\033\n\027UTF8_" - "VALIDATION_UNKNOWN\020\000\022\010\n\004NONE\020\001\022\n\n\006VERIFY" - "\020\002\"S\n\017MessageEncoding\022\034\n\030MESSAGE_ENCODIN" + "VALIDATION_UNKNOWN\020\000\022\n\n\006VERIFY\020\002\022\010\n\004NONE" + "\020\003\"S\n\017MessageEncoding\022\034\n\030MESSAGE_ENCODIN" "G_UNKNOWN\020\000\022\023\n\017LENGTH_PREFIXED\020\001\022\r\n\tDELI" "MITED\020\002\"H\n\nJsonFormat\022\027\n\023JSON_FORMAT_UNK" "NOWN\020\000\022\t\n\005ALLOW\020\001\022\026\n\022LEGACY_BEST_EFFORT\020" @@ -2260,16 +2260,16 @@ const ::google::protobuf::EnumDescriptor* FeatureSet_Utf8Validation_descriptor() return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[12]; } PROTOBUF_CONSTINIT const uint32_t FeatureSet_Utf8Validation_internal_data_[] = { - 196608u, 0u, }; + 65536u, 32u, 6u, }; bool FeatureSet_Utf8Validation_IsValid(int value) { - return 0 <= value && value <= 2; + return 0 <= value && value <= 3 && ((13u >> value) & 1) != 0; } #if (__cplusplus < 201703) && \ (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) constexpr FeatureSet_Utf8Validation FeatureSet::UTF8_VALIDATION_UNKNOWN; -constexpr FeatureSet_Utf8Validation FeatureSet::NONE; constexpr FeatureSet_Utf8Validation FeatureSet::VERIFY; +constexpr FeatureSet_Utf8Validation FeatureSet::NONE; constexpr FeatureSet_Utf8Validation FeatureSet::Utf8Validation_MIN; constexpr FeatureSet_Utf8Validation FeatureSet::Utf8Validation_MAX; constexpr int FeatureSet::Utf8Validation_ARRAYSIZE; @@ -11687,8 +11687,8 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { {::_pbi::TcParser::FastEr0S1, {24, 2, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.repeated_field_encoding_)}}, // optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - {::_pbi::TcParser::FastEr0S1, - {32, 3, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_)}}, + {::_pbi::TcParser::FastEvS1, + {32, 3, 3, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_)}}, // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, {40, 4, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_)}}, @@ -11710,7 +11710,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_), _Internal::kHasBitsOffset + 3, 3, - (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, + (0 | ::_fl::kFcOptional | ::_fl::kEnum)}, // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_), _Internal::kHasBitsOffset + 4, 4, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, @@ -11721,7 +11721,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { {0, 4}, {0, 3}, {0, 3}, - {0, 3}, + {::_pbi::FieldAuxEnumData{}, ::google::protobuf::FeatureSet_Utf8Validation_internal_data_}, {0, 3}, {0, 3}, }}, {{ diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index ea38e1f3d0..fc613d584d 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -548,15 +548,15 @@ inline bool FeatureSet_RepeatedFieldEncoding_Parse(absl::string_view name, Featu } enum FeatureSet_Utf8Validation : int { FeatureSet_Utf8Validation_UTF8_VALIDATION_UNKNOWN = 0, - FeatureSet_Utf8Validation_NONE = 1, FeatureSet_Utf8Validation_VERIFY = 2, + FeatureSet_Utf8Validation_NONE = 3, }; PROTOBUF_EXPORT bool FeatureSet_Utf8Validation_IsValid(int value); PROTOBUF_EXPORT extern const uint32_t FeatureSet_Utf8Validation_internal_data_[]; constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MIN = static_cast(0); -constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MAX = static_cast(2); -constexpr int FeatureSet_Utf8Validation_Utf8Validation_ARRAYSIZE = 2 + 1; +constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MAX = static_cast(3); +constexpr int FeatureSet_Utf8Validation_Utf8Validation_ARRAYSIZE = 3 + 1; PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FeatureSet_Utf8Validation_descriptor(); template @@ -569,7 +569,7 @@ const std::string& FeatureSet_Utf8Validation_Name(T value) { template <> inline const std::string& FeatureSet_Utf8Validation_Name(FeatureSet_Utf8Validation value) { return ::google::protobuf::internal::NameOfDenseEnum( + 0, 3>( static_cast(value)); } inline bool FeatureSet_Utf8Validation_Parse(absl::string_view name, FeatureSet_Utf8Validation* value) { @@ -1817,8 +1817,8 @@ class PROTOBUF_EXPORT FeatureSet final : using Utf8Validation = FeatureSet_Utf8Validation; static constexpr Utf8Validation UTF8_VALIDATION_UNKNOWN = FeatureSet_Utf8Validation_UTF8_VALIDATION_UNKNOWN; - static constexpr Utf8Validation NONE = FeatureSet_Utf8Validation_NONE; static constexpr Utf8Validation VERIFY = FeatureSet_Utf8Validation_VERIFY; + static constexpr Utf8Validation NONE = FeatureSet_Utf8Validation_NONE; static inline bool Utf8Validation_IsValid(int value) { return FeatureSet_Utf8Validation_IsValid(value); } diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index 474864353a..fe66e71f58 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -974,8 +974,8 @@ message FeatureSet { enum Utf8Validation { UTF8_VALIDATION_UNKNOWN = 0; - NONE = 1; VERIFY = 2; + NONE = 3; } optional Utf8Validation utf8_validation = 4 [ retention = RETENTION_RUNTIME, From 137e5984aff3e7cbc26ce4bf5923ae438cd6ecef Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Thu, 26 Oct 2023 07:23:40 -0700 Subject: [PATCH 66/95] Rollback changes to Utf8Validation PiperOrigin-RevId: 576863528 --- src/google/protobuf/descriptor.pb.cc | 18 +++++++++--------- src/google/protobuf/descriptor.pb.h | 10 +++++----- src/google/protobuf/descriptor.proto | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 88308d71f4..ae02aa9a2d 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -1864,8 +1864,8 @@ const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] AB "SED\020\002\"V\n\025RepeatedFieldEncoding\022#\n\037REPEAT" "ED_FIELD_ENCODING_UNKNOWN\020\000\022\n\n\006PACKED\020\001\022" "\014\n\010EXPANDED\020\002\"C\n\016Utf8Validation\022\033\n\027UTF8_" - "VALIDATION_UNKNOWN\020\000\022\n\n\006VERIFY\020\002\022\010\n\004NONE" - "\020\003\"S\n\017MessageEncoding\022\034\n\030MESSAGE_ENCODIN" + "VALIDATION_UNKNOWN\020\000\022\010\n\004NONE\020\001\022\n\n\006VERIFY" + "\020\002\"S\n\017MessageEncoding\022\034\n\030MESSAGE_ENCODIN" "G_UNKNOWN\020\000\022\023\n\017LENGTH_PREFIXED\020\001\022\r\n\tDELI" "MITED\020\002\"H\n\nJsonFormat\022\027\n\023JSON_FORMAT_UNK" "NOWN\020\000\022\t\n\005ALLOW\020\001\022\026\n\022LEGACY_BEST_EFFORT\020" @@ -2260,16 +2260,16 @@ const ::google::protobuf::EnumDescriptor* FeatureSet_Utf8Validation_descriptor() return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[12]; } PROTOBUF_CONSTINIT const uint32_t FeatureSet_Utf8Validation_internal_data_[] = { - 65536u, 32u, 6u, }; + 196608u, 0u, }; bool FeatureSet_Utf8Validation_IsValid(int value) { - return 0 <= value && value <= 3 && ((13u >> value) & 1) != 0; + return 0 <= value && value <= 2; } #if (__cplusplus < 201703) && \ (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) constexpr FeatureSet_Utf8Validation FeatureSet::UTF8_VALIDATION_UNKNOWN; -constexpr FeatureSet_Utf8Validation FeatureSet::VERIFY; constexpr FeatureSet_Utf8Validation FeatureSet::NONE; +constexpr FeatureSet_Utf8Validation FeatureSet::VERIFY; constexpr FeatureSet_Utf8Validation FeatureSet::Utf8Validation_MIN; constexpr FeatureSet_Utf8Validation FeatureSet::Utf8Validation_MAX; constexpr int FeatureSet::Utf8Validation_ARRAYSIZE; @@ -11687,8 +11687,8 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { {::_pbi::TcParser::FastEr0S1, {24, 2, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.repeated_field_encoding_)}}, // optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - {::_pbi::TcParser::FastEvS1, - {32, 3, 3, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_)}}, + {::_pbi::TcParser::FastEr0S1, + {32, 3, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_)}}, // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, {40, 4, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_)}}, @@ -11710,7 +11710,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_), _Internal::kHasBitsOffset + 3, 3, - (0 | ::_fl::kFcOptional | ::_fl::kEnum)}, + (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_), _Internal::kHasBitsOffset + 4, 4, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, @@ -11721,7 +11721,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { {0, 4}, {0, 3}, {0, 3}, - {::_pbi::FieldAuxEnumData{}, ::google::protobuf::FeatureSet_Utf8Validation_internal_data_}, + {0, 3}, {0, 3}, {0, 3}, }}, {{ diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index fc613d584d..ea38e1f3d0 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -548,15 +548,15 @@ inline bool FeatureSet_RepeatedFieldEncoding_Parse(absl::string_view name, Featu } enum FeatureSet_Utf8Validation : int { FeatureSet_Utf8Validation_UTF8_VALIDATION_UNKNOWN = 0, + FeatureSet_Utf8Validation_NONE = 1, FeatureSet_Utf8Validation_VERIFY = 2, - FeatureSet_Utf8Validation_NONE = 3, }; PROTOBUF_EXPORT bool FeatureSet_Utf8Validation_IsValid(int value); PROTOBUF_EXPORT extern const uint32_t FeatureSet_Utf8Validation_internal_data_[]; constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MIN = static_cast(0); -constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MAX = static_cast(3); -constexpr int FeatureSet_Utf8Validation_Utf8Validation_ARRAYSIZE = 3 + 1; +constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MAX = static_cast(2); +constexpr int FeatureSet_Utf8Validation_Utf8Validation_ARRAYSIZE = 2 + 1; PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FeatureSet_Utf8Validation_descriptor(); template @@ -569,7 +569,7 @@ const std::string& FeatureSet_Utf8Validation_Name(T value) { template <> inline const std::string& FeatureSet_Utf8Validation_Name(FeatureSet_Utf8Validation value) { return ::google::protobuf::internal::NameOfDenseEnum( + 0, 2>( static_cast(value)); } inline bool FeatureSet_Utf8Validation_Parse(absl::string_view name, FeatureSet_Utf8Validation* value) { @@ -1817,8 +1817,8 @@ class PROTOBUF_EXPORT FeatureSet final : using Utf8Validation = FeatureSet_Utf8Validation; static constexpr Utf8Validation UTF8_VALIDATION_UNKNOWN = FeatureSet_Utf8Validation_UTF8_VALIDATION_UNKNOWN; - static constexpr Utf8Validation VERIFY = FeatureSet_Utf8Validation_VERIFY; static constexpr Utf8Validation NONE = FeatureSet_Utf8Validation_NONE; + static constexpr Utf8Validation VERIFY = FeatureSet_Utf8Validation_VERIFY; static inline bool Utf8Validation_IsValid(int value) { return FeatureSet_Utf8Validation_IsValid(value); } diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index fe66e71f58..474864353a 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -974,8 +974,8 @@ message FeatureSet { enum Utf8Validation { UTF8_VALIDATION_UNKNOWN = 0; + NONE = 1; VERIFY = 2; - NONE = 3; } optional Utf8Validation utf8_validation = 4 [ retention = RETENTION_RUNTIME, From f69f40e3f6dda0d3fc998bb00be6df35fb12bfa6 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 26 Oct 2023 08:38:30 -0700 Subject: [PATCH 67/95] Internal change PiperOrigin-RevId: 576883351 --- src/google/protobuf/extension_set.cc | 3 +++ src/google/protobuf/extension_set.h | 16 +++++++++++----- .../protobuf/generated_message_reflection.cc | 5 +++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 4b54d7a3b6..7fde2cf8de 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -11,6 +11,7 @@ #include "google/protobuf/extension_set.h" +#include #include #include #include @@ -1933,6 +1934,8 @@ LazyEagerVerifyFnType FindExtensionLazyEagerVerifyFn( return nullptr; } +std::atomic + ExtensionSet::maybe_create_lazy_extension_; } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index f45a1c858c..dd4a473ebc 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -16,6 +16,7 @@ #define GOOGLE_PROTOBUF_EXTENSION_SET_H__ #include +#include #include #include #include @@ -57,6 +58,7 @@ class FeatureSet; namespace internal { class FieldSkipper; // wire_format_lite.h class WireFormat; +void InitializeLazyExtensionSet(); } // namespace internal } // namespace protobuf } // namespace google @@ -508,6 +510,8 @@ class PROTOBUF_EXPORT ExtensionSet { friend class google::protobuf::Reflection; friend class google::protobuf::internal::WireFormat; + friend void internal::InitializeLazyExtensionSet(); + const int32_t& GetRefInt32(int number, const int32_t& default_value) const; const int64_t& GetRefInt64(int number, const int64_t& default_value) const; const uint32_t& GetRefUInt32(int number, const uint32_t& default_value) const; @@ -579,7 +583,13 @@ class PROTOBUF_EXPORT ExtensionSet { virtual void UnusedKeyMethod(); // Dummy key method to avoid weak vtable. }; // Give access to function defined below to see LazyMessageExtension. - friend LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena); + static LazyMessageExtension* MaybeCreateLazyExtensionImpl(Arena* arena); + static LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena) { + auto* f = maybe_create_lazy_extension_.load(std::memory_order_relaxed); + return f != nullptr ? f(arena) : nullptr; + } + static std::atomic + maybe_create_lazy_extension_; struct Extension { // The order of these fields packs Extension into 24 bytes when using 8 // byte alignment. Consider this when adding or removing fields here. @@ -1529,10 +1539,6 @@ class ExtensionIdentifier { // Generated accessors -// Used to retrieve a lazy extension, may return nullptr in some environments. -extern PROTOBUF_ATTRIBUTE_WEAK ExtensionSet::LazyMessageExtension* -MaybeCreateLazyExtension(Arena* arena); - // Define a specialization of ExtensionIdentifier for bootstrapped extensions // that we need to register lazily. template <> diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 452fd5240d..84272163fe 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include "absl/base/call_once.h" #include "absl/base/casts.h" @@ -93,6 +94,9 @@ void InitializeFileDescriptorDefaultInstances() { #endif // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) } +void InitializeLazyExtensionSet() { +} + bool ParseNamedEnum(const EnumDescriptor* descriptor, absl::string_view name, int* value) { const EnumValueDescriptor* d = descriptor->FindValueByName(name); @@ -3660,6 +3664,7 @@ void AddDescriptorsImpl(const DescriptorTable* table) { // Reflection refers to the default fields so make sure they are initialized. internal::InitProtobufDefaults(); internal::InitializeFileDescriptorDefaultInstances(); + internal::InitializeLazyExtensionSet(); // Ensure all dependent descriptors are registered to the generated descriptor // pool and message factory. From c20b337221fb1c8fb02b4ea3d9363adbc2ef0ad3 Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Thu, 26 Oct 2023 08:40:45 -0700 Subject: [PATCH 68/95] upb: remove redundant #includes from the foo.upbdefs.h gencode PiperOrigin-RevId: 576883852 --- upb_generator/protoc-gen-upbdefs.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/upb_generator/protoc-gen-upbdefs.cc b/upb_generator/protoc-gen-upbdefs.cc index 69682c4e78..58234150a2 100644 --- a/upb_generator/protoc-gen-upbdefs.cc +++ b/upb_generator/protoc-gen-upbdefs.cc @@ -70,17 +70,13 @@ void WriteDefHeader(upb::FileDefPtr file, Output& output) { "#define $0_UPBDEFS_H_\n\n" "#include \"upb/reflection/def.h\"\n" "#include \"upb/reflection/internal/def_pool.h\"\n" - "#include \"upb/port/def.inc\"\n" + "\n" + "#include \"upb/port/def.inc\" // Must be last.\n" "#ifdef __cplusplus\n" "extern \"C\" {\n" "#endif\n\n", ToPreproc(file.name())); - output("#include \"upb/reflection/def.h\"\n"); - output("\n"); - output("#include \"upb/port/def.inc\"\n"); - output("\n"); - output("extern _upb_DefPool_Init $0;\n", DefInitSymbol(file)); output("\n"); From 8d67a40d30553f275b28f55ab5b5dd358eacaefa Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Thu, 26 Oct 2023 10:55:23 -0700 Subject: [PATCH 69/95] upb: fix wheels build errors PiperOrigin-RevId: 576925248 --- python/dist/BUILD.bazel | 1 + upb/cmake/BUILD.bazel | 1 + upb/reflection/BUILD | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/python/dist/BUILD.bazel b/python/dist/BUILD.bazel index 4330fe1c4f..ba549acb25 100644 --- a/python/dist/BUILD.bazel +++ b/python/dist/BUILD.bazel @@ -246,6 +246,7 @@ pkg_files( "//upb/mini_descriptor:source_files", "//upb/mini_table:source_files", "//upb/port:source_files", + "//upb/reflection:source_files", "//upb/text:source_files", "//upb/util:source_files", "//upb/wire:source_files", diff --git a/upb/cmake/BUILD.bazel b/upb/cmake/BUILD.bazel index b2a5e5a7f8..3e40380e8b 100644 --- a/upb/cmake/BUILD.bazel +++ b/upb/cmake/BUILD.bazel @@ -96,6 +96,7 @@ sh_test( "//upb/mini_descriptor:source_files", "//upb/mini_table:source_files", "//upb/port:source_files", + "//upb/reflection:source_files", "//upb/text:source_files", "//upb/wire:source_files", "@utf8_range//:utf8_range_srcs", diff --git a/upb/reflection/BUILD b/upb/reflection/BUILD index 380ae38e51..0e92276c44 100644 --- a/upb/reflection/BUILD +++ b/upb/reflection/BUILD @@ -172,3 +172,21 @@ cc_test( "@com_google_absl//absl/strings", ], ) + +# begin:github_only +filegroup( + name = "source_files", + srcs = glob( + [ + "**/*.c", + "**/*.h", + "**/*.hpp", + ], + exclude = ["stage0/**"], + ), + visibility = [ + "//upb/cmake:__pkg__", + "//python/dist:__pkg__", + ] +) +# end:github_only From e9953d2155f48fbd203ea666caf352b5e5488897 Mon Sep 17 00:00:00 2001 From: Jie Luo Date: Thu, 26 Oct 2023 13:15:41 -0700 Subject: [PATCH 70/95] internal change PiperOrigin-RevId: 576966982 --- python/google/protobuf/internal/api_implementation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py index 65caf63f8b..09af96e67c 100755 --- a/python/google/protobuf/internal/api_implementation.py +++ b/python/google/protobuf/internal/api_implementation.py @@ -13,6 +13,8 @@ import os import sys import warnings +_GOOGLE3_PYTHON_UPB_DEFAULT = False + def _ApiVersionToImplementationType(api_version): if api_version == 2: From 37cae2d2e1320f32f64b1e9552dd3763469a1aa7 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Fri, 27 Oct 2023 02:10:28 -0700 Subject: [PATCH 71/95] Internal change PiperOrigin-RevId: 577125921 --- upb/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upb/BUILD b/upb/BUILD index 16c67b17e0..1e52a8092b 100644 --- a/upb/BUILD +++ b/upb/BUILD @@ -97,7 +97,7 @@ cc_library( # implementation, but depends on :upb and exposes a few more hdrs. # # This is public only because we have no way of visibility-limiting it to -# upb_proto_library() only. This interface is not stable and by using it you +# upb_c_proto_library() only. This interface is not stable and by using it you # give up any backward compatibility guarantees. cc_library( name = "generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", From b2efcdc1c50b204e2b612eacf5db599f74153376 Mon Sep 17 00:00:00 2001 From: Chris Kennelly Date: Fri, 27 Oct 2023 12:29:24 -0700 Subject: [PATCH 72/95] Internal Code Change PiperOrigin-RevId: 577274352 --- src/google/protobuf/arenaz_sampler_test.cc | 1 + src/google/protobuf/compiler/cpp/unittest.inc | 1 - src/google/protobuf/repeated_field_unittest.cc | 6 +++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/google/protobuf/arenaz_sampler_test.cc b/src/google/protobuf/arenaz_sampler_test.cc index c71162467a..20a0473207 100644 --- a/src/google/protobuf/arenaz_sampler_test.cc +++ b/src/google/protobuf/arenaz_sampler_test.cc @@ -401,6 +401,7 @@ TEST(ThreadSafeArenazSamplerTest, InitialBlockReportsZeroUsedAndWasted) { for (int i = 0; i < 10; ++i) { char block[kSize]; google::protobuf::Arena arena(/*initial_block=*/block, /*initial_block_size=*/kSize); + benchmark::DoNotOptimize(&arena); sampler.Iterate([&](const ThreadSafeArenaStats& h) { const auto& histbin = h.block_histogram[ThreadSafeArenaStats::FindBin(kSize)]; diff --git a/src/google/protobuf/compiler/cpp/unittest.inc b/src/google/protobuf/compiler/cpp/unittest.inc index 169fbb6021..56109d3913 100644 --- a/src/google/protobuf/compiler/cpp/unittest.inc +++ b/src/google/protobuf/compiler/cpp/unittest.inc @@ -926,7 +926,6 @@ TEST(GENERATED_MESSAGE_TEST_NAME, TestOneofSpaceUsed) { #endif // !PROTOBUF_TEST_NO_DESCRIPTORS TEST(GENERATED_MESSAGE_TEST_NAME, FieldConstantValues) { - UNITTEST::TestRequired message; EXPECT_EQ(UNITTEST::TestAllTypes_NestedMessage::kBbFieldNumber, 1); EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalInt32FieldNumber, 1); EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalgroupFieldNumber, 16); diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 529d872284..814f0c8d79 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -704,9 +704,9 @@ TEST(RepeatedField, CopyConstructIntegers) { EXPECT_EQ(2, fields1.Get(1)); RepeatedType fields2(token, nullptr, original); - ASSERT_EQ(2, fields1.size()); - EXPECT_EQ(1, fields1.Get(0)); - EXPECT_EQ(2, fields1.Get(1)); + ASSERT_EQ(2, fields2.size()); + EXPECT_EQ(1, fields2.Get(0)); + EXPECT_EQ(2, fields2.Get(1)); } TEST(RepeatedField, CopyConstructCords) { From 57bb1e55f1e439399491fe762465120fbf1c09a3 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Sat, 28 Oct 2023 12:54:21 -0700 Subject: [PATCH 73/95] Set up editions codegen tests for python These tests aren't super useful for python because of how little codegen we actually do, but the pyi ones specifically will guard against major editions regressions. PiperOrigin-RevId: 577495652 --- .../protobuf/compiler/python/generator.cc | 157 ++++++++---------- .../protobuf/compiler/python/generator.h | 6 + .../protobuf/compiler/python/pyi_generator.cc | 7 + .../protobuf/compiler/python/pyi_generator.h | 8 + 4 files changed, 86 insertions(+), 92 deletions(-) diff --git a/src/google/protobuf/compiler/python/generator.cc b/src/google/protobuf/compiler/python/generator.cc index f3cce736d6..6430459c6a 100644 --- a/src/google/protobuf/compiler/python/generator.cc +++ b/src/google/protobuf/compiler/python/generator.cc @@ -22,6 +22,8 @@ #include "google/protobuf/compiler/python/generator.h" #include +#include +#include #include #include #include @@ -35,10 +37,12 @@ #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" #include "absl/strings/str_replace.h" #include "absl/strings/string_view.h" #include "absl/strings/strip.h" #include "absl/strings/substitute.h" +#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/python/helpers.h" #include "google/protobuf/compiler/python/pyi_generator.h" #include "google/protobuf/compiler/retention.h" @@ -49,6 +53,7 @@ #include "google/protobuf/io/printer.h" #include "google/protobuf/io/strtod.h" #include "google/protobuf/io/zero_copy_stream.h" +#include "google/protobuf/message.h" namespace google { namespace protobuf { @@ -152,21 +157,6 @@ std::string StringifyDefaultValue(const FieldDescriptor& field) { return ""; } -std::string StringifySyntax(FileDescriptorLegacy::Syntax syntax) { - switch (syntax) { - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2: - return "proto2"; - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3: - return "proto3"; - case FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN: - default: - ABSL_LOG(FATAL) - << "Unsupported syntax; this generator only supports proto2 " - "and proto3 syntax."; - return ""; - } -} - } // namespace Generator::Generator() : file_(nullptr) {} @@ -194,6 +184,8 @@ GeneratorOptions Generator::ParseParameter(absl::string_view parameter, options.generate_pyi = true; } else if (option.first == "annotate_code") { options.annotate_pyi = true; + } else if (option.first == "experimental_strip_nonfunctional_codegen") { + options.strip_nonfunctional_codegen = true; } else { *error = absl::StrCat("Unknown generator option: ", option.first); } @@ -211,8 +203,15 @@ bool Generator::Generate(const FileDescriptor* file, // Generate pyi typing information if (options.generate_pyi) { python::PyiGenerator pyi_generator; - std::string pyi_options = options.annotate_pyi ? "annotate_code" : ""; - if (!pyi_generator.Generate(file, pyi_options, context, error)) { + std::vector pyi_options; + if (options.annotate_pyi) { + pyi_options.push_back("annotate_code"); + } + if (options.strip_nonfunctional_codegen) { + pyi_options.push_back("experimental_strip_nonfunctional_codegen"); + } + if (!pyi_generator.Generate(file, absl::StrJoin(pyi_options, ","), context, + error)) { return false; } } @@ -423,7 +422,8 @@ void Generator::PrintFileDescriptor() const { m["descriptor_name"] = kDescriptorKey; m["name"] = file_->name(); m["package"] = file_->package(); - m["syntax"] = StringifySyntax(FileDescriptorLegacy(file_).syntax()); + m["syntax"] = std::string( + FileDescriptorLegacy::SyntaxName(FileDescriptorLegacy(file_).syntax())); m["options"] = OptionsValue( StripLocalSourceRetentionOptions(*file_).SerializeAsString()); m["serialized_descriptor"] = absl::CHexEscape(file_descriptor_serialized_); @@ -677,8 +677,7 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { "options_value", OptionsValue(options_string), "extendable", message_descriptor.extension_range_count() > 0 ? "True" : "False", "syntax", - StringifySyntax( - FileDescriptorLegacy(message_descriptor.file()).syntax())); + FileDescriptorLegacy::SyntaxName(FileDescriptorLegacy(file_).syntax())); printer_->Print(",\n"); // Extension ranges @@ -1167,7 +1166,7 @@ void Generator::PrintSerializedPbInterval( const DescriptorProtoT& descriptor_proto, absl::string_view name) const { std::string sp; descriptor_proto.SerializeToString(&sp); - int offset = file_descriptor_serialized_.find(sp); + size_t offset = file_descriptor_serialized_.find(sp); ABSL_CHECK_GE(offset, 0); printer_->Print( @@ -1177,26 +1176,34 @@ void Generator::PrintSerializedPbInterval( absl::StrCat(offset + sp.size())); } -namespace { -void PrintDescriptorOptionsFixingCode(absl::string_view descriptor, - absl::string_view options, - io::Printer* printer) { +template +bool Generator::PrintDescriptorOptionsFixingCode( + const DescriptorT& descriptor, absl::string_view descriptor_str) const { + std::string options = OptionsValue( + StripLocalSourceRetentionOptions(descriptor).SerializeAsString()); + // Reset the _options to None thus DescriptorBase.GetOptions() can // parse _options again after extensions are registered. - size_t dot_pos = descriptor.find('.'); + size_t dot_pos = descriptor_str.find('.'); std::string descriptor_name; if (dot_pos == std::string::npos) { - descriptor_name = absl::StrCat("_globals['", descriptor, "']"); + descriptor_name = absl::StrCat("_globals['", descriptor_str, "']"); } else { - descriptor_name = absl::StrCat("_globals['", descriptor.substr(0, dot_pos), - "']", descriptor.substr(dot_pos)); + descriptor_name = + absl::StrCat("_globals['", descriptor_str.substr(0, dot_pos), "']", + descriptor_str.substr(dot_pos)); + } + + if (options == "None") { + return false; } - printer->Print( + + printer_->Print( "$descriptor_name$._options = None\n" "$descriptor_name$._serialized_options = $serialized_value$\n", "descriptor_name", descriptor_name, "serialized_value", options); + return true; } -} // namespace // Generates the start and end offsets for each entity in the serialized file // descriptor. The file argument must exactly match what was serialized into @@ -1246,11 +1253,7 @@ void Generator::SetMessagePbInterval(const DescriptorProto& message_proto, // Prints expressions that set the options field of all descriptors. void Generator::FixAllDescriptorOptions() const { // Prints an expression that sets the file descriptor's options. - std::string file_options = OptionsValue( - StripLocalSourceRetentionOptions(*file_).SerializeAsString()); - if (file_options != "None") { - PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_); - } else { + if (!PrintDescriptorOptionsFixingCode(*file_, kDescriptorKey)) { printer_->Print("DESCRIPTOR._options = None\n"); } // Prints expressions that set the options for all top level enums. @@ -1275,35 +1278,23 @@ void Generator::FixAllDescriptorOptions() const { } void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const { - std::string oneof_options = - OptionsValue(StripLocalSourceRetentionOptions(oneof).SerializeAsString()); - if (oneof_options != "None") { - std::string oneof_name = absl::Substitute( - "$0.$1['$2']", ModuleLevelDescriptorName(*oneof.containing_type()), - "oneofs_by_name", oneof.name()); - PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_); - } + std::string oneof_name = absl::Substitute( + "$0.$1['$2']", ModuleLevelDescriptorName(*oneof.containing_type()), + "oneofs_by_name", oneof.name()); + PrintDescriptorOptionsFixingCode(oneof, oneof_name); } // Prints expressions that set the options for an enum descriptor and its // value descriptors. void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { std::string descriptor_name = ModuleLevelDescriptorName(enum_descriptor); - std::string enum_options = OptionsValue( - StripLocalSourceRetentionOptions(enum_descriptor).SerializeAsString()); - if (enum_options != "None") { - PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_); - } + PrintDescriptorOptionsFixingCode(enum_descriptor, descriptor_name); for (int i = 0; i < enum_descriptor.value_count(); ++i) { const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i); - std::string value_options = OptionsValue( - StripLocalSourceRetentionOptions(value_descriptor).SerializeAsString()); - if (value_options != "None") { - PrintDescriptorOptionsFixingCode( - absl::StrFormat("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), - value_descriptor.name().c_str()), - value_options, printer_); - } + PrintDescriptorOptionsFixingCode( + value_descriptor, + absl::StrFormat("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), + value_descriptor.name().c_str())); } } @@ -1313,46 +1304,33 @@ void Generator::FixOptionsForService( const ServiceDescriptor& service_descriptor) const { std::string descriptor_name = ModuleLevelServiceDescriptorName(service_descriptor); - std::string service_options = OptionsValue( - StripLocalSourceRetentionOptions(service_descriptor).SerializeAsString()); - if (service_options != "None") { - PrintDescriptorOptionsFixingCode(descriptor_name, service_options, - printer_); - } + PrintDescriptorOptionsFixingCode(service_descriptor, descriptor_name); for (int i = 0; i < service_descriptor.method_count(); ++i) { const MethodDescriptor* method = service_descriptor.method(i); - std::string method_options = OptionsValue( - StripLocalSourceRetentionOptions(*method).SerializeAsString()); - if (method_options != "None") { - std::string method_name = absl::StrCat( - descriptor_name, ".methods_by_name['", method->name(), "']"); - PrintDescriptorOptionsFixingCode(method_name, method_options, printer_); - } + PrintDescriptorOptionsFixingCode( + *method, absl::StrCat(descriptor_name, ".methods_by_name['", + method->name(), "']")); } } // Prints expressions that set the options for field descriptors (including // extensions). void Generator::FixOptionsForField(const FieldDescriptor& field) const { - std::string field_options = - OptionsValue(StripLocalSourceRetentionOptions(field).SerializeAsString()); - if (field_options != "None") { - std::string field_name; - if (field.is_extension()) { - if (field.extension_scope() == nullptr) { - // Top level extensions. - field_name = field.name(); - } else { - field_name = FieldReferencingExpression(field.extension_scope(), field, - "extensions_by_name"); - } + std::string field_name; + if (field.is_extension()) { + if (field.extension_scope() == nullptr) { + // Top level extensions. + field_name = field.name(); } else { - field_name = FieldReferencingExpression(field.containing_type(), field, - "fields_by_name"); + field_name = FieldReferencingExpression(field.extension_scope(), field, + "extensions_by_name"); } - PrintDescriptorOptionsFixingCode(field_name, field_options, printer_); + } else { + field_name = FieldReferencingExpression(field.containing_type(), field, + "fields_by_name"); } + PrintDescriptorOptionsFixingCode(field, field_name); } // Prints expressions that set the options for a message and all its inner @@ -1381,13 +1359,8 @@ void Generator::FixOptionsForMessage(const Descriptor& descriptor) const { FixOptionsForField(field); } // Message option for this message. - std::string message_options = OptionsValue( - StripLocalSourceRetentionOptions(descriptor).SerializeAsString()); - if (message_options != "None") { - std::string descriptor_name = ModuleLevelDescriptorName(descriptor); - PrintDescriptorOptionsFixingCode(descriptor_name, message_options, - printer_); - } + PrintDescriptorOptionsFixingCode(descriptor, + ModuleLevelDescriptorName(descriptor)); } // If a dependency forwards other files through public dependencies, let's diff --git a/src/google/protobuf/compiler/python/generator.h b/src/google/protobuf/compiler/python/generator.h index 2c73140d9c..3a4ff665ad 100644 --- a/src/google/protobuf/compiler/python/generator.h +++ b/src/google/protobuf/compiler/python/generator.h @@ -12,6 +12,7 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ #define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ +#include #include #include @@ -49,6 +50,7 @@ struct GeneratorOptions { bool generate_pyi = false; bool annotate_pyi = false; bool bootstrap = false; + bool strip_nonfunctional_codegen = false; }; class PROTOC_EXPORT Generator : public CodeGenerator { @@ -141,6 +143,10 @@ class PROTOC_EXPORT Generator : public CodeGenerator { void PrintSerializedPbInterval(const DescriptorProtoT& descriptor_proto, absl::string_view name) const; + template + bool PrintDescriptorOptionsFixingCode(const DescriptorT& descriptor, + absl::string_view descriptor_str) const; + void FixAllDescriptorOptions() const; void FixOptionsForField(const FieldDescriptor& field) const; void FixOptionsForOneof(const OneofDescriptor& oneof) const; diff --git a/src/google/protobuf/compiler/python/pyi_generator.cc b/src/google/protobuf/compiler/python/pyi_generator.cc index 35a4e4ec2d..7f7bfeda08 100644 --- a/src/google/protobuf/compiler/python/pyi_generator.cc +++ b/src/google/protobuf/compiler/python/pyi_generator.cc @@ -18,6 +18,7 @@ #include "absl/strings/match.h" #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" +#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/python/helpers.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" @@ -169,6 +170,9 @@ void PyiGenerator::PrintImports() const { bool has_importlib = false; for (int i = 0; i < file_->dependency_count(); ++i) { const FileDescriptor* dep = file_->dependency(i); + if (strip_nonfunctional_codegen_ && IsKnownFeatureProto(dep->name())) { + continue; + } PrintImportForDescriptor(*dep, &seen_aliases, &has_importlib); for (int j = 0; j < dep->public_dependency_count(); ++j) { PrintImportForDescriptor(*dep->public_dependency(j), &seen_aliases, @@ -570,11 +574,14 @@ bool PyiGenerator::Generate(const FileDescriptor* file, std::string filename; bool annotate_code = false; + strip_nonfunctional_codegen_ = false; for (const std::pair& option : options) { if (option.first == "annotate_code") { annotate_code = true; } else if (absl::EndsWith(option.first, ".pyi")) { filename = option.first; + } else if (option.first == "experimental_strip_nonfunctional_codegen") { + strip_nonfunctional_codegen_ = true; } else { *error = absl::StrCat("Unknown generator option: ", option.first); return false; diff --git a/src/google/protobuf/compiler/python/pyi_generator.h b/src/google/protobuf/compiler/python/pyi_generator.h index 84c802bee8..495b296900 100644 --- a/src/google/protobuf/compiler/python/pyi_generator.h +++ b/src/google/protobuf/compiler/python/pyi_generator.h @@ -13,6 +13,7 @@ #define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ #include +#include #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" @@ -53,6 +54,12 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera GeneratorContext* generator_context, std::string* error) const override; + Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; } + Edition GetMaximumEdition() const override { return Edition::EDITION_2023; } + std::vector GetFeatureExtensions() const override { + return {}; + } + private: void PrintImportForDescriptor(const FileDescriptor& desc, absl::flat_hash_set* seen_aliases, @@ -83,6 +90,7 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera mutable absl::Mutex mutex_; mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. mutable io::Printer* printer_; // Set in Generate(). Under mutex_. + mutable bool strip_nonfunctional_codegen_ = false; // Set in Generate(). // import_map will be a mapping from filename to module alias, e.g. // "google3/foo/bar.py" -> "_bar" mutable absl::flat_hash_map import_map_; From 63f4c503a2762abaec136209ee5b62452ecf206e Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Sat, 28 Oct 2023 12:57:37 -0700 Subject: [PATCH 74/95] Editions: Embed resolved features of descriptor.proto for pure python. Because pure python builds all descriptors at runtime via reflection, it's unable to parse options during the build of descriptor.proto (i.e. before we've built the options schemas). We always lazily parse these options to avoid this, but that still means options can't be *used* during this build. Since the current build process makes heavy use of features (which previously just relied on syntax), this poses a problem for editions. To get around this, we just embed the resolved features directly into the gencode for this one file. This will allow us to skip feature resolution for these descriptors and still consider features in their build. PiperOrigin-RevId: 577495949 --- .../protobuf/internal/descriptor_test.py | 67 ++++++++++- .../protobuf/compiler/python/generator.cc | 109 ++++++++++++++++++ .../protobuf/compiler/python/generator.h | 3 + 3 files changed, 175 insertions(+), 4 deletions(-) diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py index 1adbad286e..56ca079f34 100755 --- a/python/google/protobuf/internal/descriptor_test.py +++ b/python/google/protobuf/internal/descriptor_test.py @@ -12,13 +12,15 @@ __author__ = 'robinson@google.com (Will Robinson)' import unittest import warnings -from google.protobuf import descriptor_pb2 -from google.protobuf.internal import api_implementation -from google.protobuf.internal import test_util from google.protobuf import descriptor +from google.protobuf import descriptor_pb2 from google.protobuf import descriptor_pool from google.protobuf import symbol_database from google.protobuf import text_format +from google.protobuf.internal import api_implementation +from google.protobuf.internal import test_util + +from google.protobuf.internal import _parameterized from google.protobuf import unittest_custom_options_pb2 from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_pb2 @@ -1169,7 +1171,6 @@ class MakeDescriptorTest(unittest.TestCase): self.assertEqual(result.fields[0].cpp_type, descriptor.FieldDescriptor.CPPTYPE_UINT64) - def testMakeDescriptorWithOptions(self): descriptor_proto = descriptor_pb2.DescriptorProto() aggregate_message = unittest_custom_options_pb2.AggregateMessage @@ -1214,5 +1215,63 @@ class MakeDescriptorTest(unittest.TestCase): json_names[index]) +class FeaturesTest(_parameterized.TestCase): + + # TODO Add _features for upb and C++. + @_parameterized.named_parameters([ + ('File', lambda: descriptor_pb2.DESCRIPTOR), + ('Message', lambda: descriptor_pb2.FeatureSet.DESCRIPTOR), + ( + 'Enum', + lambda: descriptor_pb2.FeatureSet.FieldPresence.DESCRIPTOR, + ), + ( + 'Field', + lambda: descriptor_pb2.FeatureSet.DESCRIPTOR.fields_by_name[ + 'enum_type' + ], + ), + ]) + @unittest.skipIf( + api_implementation.Type() != 'python', + 'Features field is only available with the pure python implementation', + ) + def testDescriptorProtoDefaultFeatures(self, desc): + self.assertEqual( + desc()._features.field_presence, + descriptor_pb2.FeatureSet.FieldPresence.EXPLICIT, + ) + self.assertEqual( + desc()._features.enum_type, + descriptor_pb2.FeatureSet.EnumType.CLOSED, + ) + self.assertEqual( + desc()._features.repeated_field_encoding, + descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED, + ) + + # TODO Add _features for upb and C++. + @unittest.skipIf( + api_implementation.Type() != 'python', + 'Features field is only available with the pure python implementation', + ) + def testDescriptorProtoOverrideFeatures(self): + desc = descriptor_pb2.SourceCodeInfo.Location.DESCRIPTOR.fields_by_name[ + 'path' + ] + self.assertEqual( + desc._features.field_presence, + descriptor_pb2.FeatureSet.FieldPresence.EXPLICIT, + ) + self.assertEqual( + desc._features.enum_type, + descriptor_pb2.FeatureSet.EnumType.CLOSED, + ) + self.assertEqual( + desc._features.repeated_field_encoding, + descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED, + ) + + if __name__ == '__main__': unittest.main() diff --git a/src/google/protobuf/compiler/python/generator.cc b/src/google/protobuf/compiler/python/generator.cc index 6430459c6a..3f3410e3cd 100644 --- a/src/google/protobuf/compiler/python/generator.cc +++ b/src/google/protobuf/compiler/python/generator.cc @@ -33,6 +33,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" +#include "absl/memory/memory.h" #include "absl/strings/ascii.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" @@ -50,6 +51,8 @@ #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor_legacy.h" +#include "google/protobuf/descriptor_visitor.h" +#include "google/protobuf/dynamic_message.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/io/strtod.h" #include "google/protobuf/io/zero_copy_stream.h" @@ -285,6 +288,7 @@ bool Generator::Generate(const FileDescriptor* file, PrintAllEnumsInFile(); PrintMessageDescriptors(); FixForeignFieldsInDescriptors(); + PrintResolvedFeatures(); printer_->Outdent(); printer_->Print("else:\n"); printer_->Indent(); @@ -416,6 +420,111 @@ void Generator::PrintImports() const { printer_->Print("\n"); } +template +std::string Generator::GetResolvedFeatures( + const DescriptorT& descriptor) const { + if (!GeneratingDescriptorProto()) { + // Everything but descriptor.proto can handle proper feature resolution. + return "None"; + } + + // Load the resolved features from our pool. + const Descriptor* feature_set = file_->pool()->FindMessageTypeByName( + FeatureSet::GetDescriptor()->full_name()); + auto message_factory = absl::make_unique(); + auto features = + absl::WrapUnique(message_factory->GetPrototype(feature_set)->New()); + features->ParseFromString( + GetResolvedSourceFeatures(descriptor).SerializeAsString()); + + // Collect all of the resolved features. + std::vector feature_args; + const Reflection* reflection = features->GetReflection(); + std::vector fields; + reflection->ListFields(*features, &fields); + for (const auto* field : fields) { + // Assume these are all enums. If we add non-enum global features or any + // python-specific features, we will need to come back and improve this + // logic. + ABSL_CHECK(field->enum_type() != nullptr) + << "Unexpected non-enum field found!"; + if (field->options().retention() == FieldOptions::RETENTION_SOURCE) { + // Skip any source-retention features. + continue; + } + const EnumDescriptor* enm = field->enum_type(); + const EnumValueDescriptor* value = + enm->FindValueByNumber(reflection->GetEnumValue(*features, field)); + + feature_args.emplace_back(absl::StrCat( + field->name(), "=", + absl::StrFormat("%s.values_by_name[\"%s\"].number", + ModuleLevelDescriptorName(*enm), value->name()))); + } + return absl::StrCat("_ResolvedFeatures(", absl::StrJoin(feature_args, ","), + ")"); +} + +void Generator::PrintResolvedFeatures() const { + // Since features are used during the descriptor build, it's impossible to do + // feature resolution at the normal point for descriptor.proto. Instead, we do + // feature resolution here in the generator, and embed a custom object on all + // of the generated descriptors. This object should act like any other + // FeatureSet message on normal descriptors, but will never have to be + // resolved by the python runtime. + ABSL_CHECK(GeneratingDescriptorProto()); + printer_->Emit({{"resolved_features", GetResolvedFeatures(*file_)}, + {"descriptor_name", kDescriptorKey}}, + R"py( + class _ResolvedFeatures: + def __init__(self, features = None, **kwargs): + if features: + for k, v in features.FIELDS.items(): + setattr(self, k, getattr(features, k)) + else: + for k, v in kwargs.items(): + setattr(self, k, v) + $descriptor_name$._features = $resolved_features$ + )py"); + +#define MAKE_NESTED(desc, CPP_FIELD, PY_FIELD) \ + [&] { \ + for (int i = 0; i < desc.CPP_FIELD##_count(); ++i) { \ + printer_->Emit( \ + {{"resolved_subfeatures", GetResolvedFeatures(*desc.CPP_FIELD(i))}, \ + {"index", absl::StrCat(i)}, \ + {"field", PY_FIELD}}, \ + "$descriptor_name$.$field$[$index$]._features = " \ + "$resolved_subfeatures$\n"); \ + } \ + } + + internal::VisitDescriptors(*file_, [&](const Descriptor& msg) { + printer_->Emit( + {{"resolved_features", GetResolvedFeatures(msg)}, + {"descriptor_name", ModuleLevelDescriptorName(msg)}, + {"field_features", MAKE_NESTED(msg, field, "fields")}, + {"oneof_features", MAKE_NESTED(msg, oneof_decl, "oneofs")}, + {"ext_features", MAKE_NESTED(msg, extension, "extensions")}}, + R"py( + $descriptor_name$._features = $resolved_features$ + $field_features$ + $oneof_features$ + $ext_features$ + )py"); + }); + internal::VisitDescriptors(*file_, [&](const EnumDescriptor& enm) { + printer_->Emit({{"resolved_features", GetResolvedFeatures(enm)}, + {"descriptor_name", ModuleLevelDescriptorName(enm)}, + {"value_features", MAKE_NESTED(enm, value, "values")}}, + R"py( + $descriptor_name$._features = $resolved_features$ + $value_features$ + )py"); + }); +#undef MAKE_NESTED +} + // Prints the single file descriptor for this file. void Generator::PrintFileDescriptor() const { absl::flat_hash_map m; diff --git a/src/google/protobuf/compiler/python/generator.h b/src/google/protobuf/compiler/python/generator.h index 3a4ff665ad..c5beeeea35 100644 --- a/src/google/protobuf/compiler/python/generator.h +++ b/src/google/protobuf/compiler/python/generator.h @@ -75,6 +75,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { GeneratorOptions ParseParameter(absl::string_view parameter, std::string* error) const; void PrintImports() const; + template + std::string GetResolvedFeatures(const DescriptorT& descriptor) const; + void PrintResolvedFeatures() const; void PrintFileDescriptor() const; void PrintAllEnumsInFile() const; void PrintNestedEnums(const Descriptor& descriptor) const; From ebdd7e3eb6f00659014672bbb901c73cbc4c5ec2 Mon Sep 17 00:00:00 2001 From: Jakob Buchgraber Date: Mon, 30 Oct 2023 01:02:10 -0700 Subject: [PATCH 75/95] Add private accessors for maps to be used by Rust's Map implementation. PiperOrigin-RevId: 577749942 --- upb/test/test_generated_code.cc | 15 +++++++++++ upb_generator/names.cc | 4 +++ upb_generator/names.h | 4 +++ upb_generator/protoc-gen-upb.cc | 45 ++++++++++++++++++++++++--------- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/upb/test/test_generated_code.cc b/upb/test/test_generated_code.cc index 2a2d723654..4169d5d865 100644 --- a/upb/test/test_generated_code.cc +++ b/upb/test/test_generated_code.cc @@ -706,6 +706,21 @@ TEST(GeneratedCode, Int32Map) { check_int32_map_empty(msg); + EXPECT_EQ( + _protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_upb_map( + msg), + nullptr); + + upb_Map* mut_map = + _protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_mutable_upb_map( + msg, arena); + EXPECT_NE(mut_map, nullptr); + + const upb_Map* const_map = + _protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_upb_map( + msg); + EXPECT_EQ(mut_map, const_map); + /* Set map[test_int32] = test_int32_2 */ protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set( msg, test_int32, test_int32_2, arena); diff --git a/upb_generator/names.cc b/upb_generator/names.cc index 847c8f1b18..31f8c6457f 100644 --- a/upb_generator/names.cc +++ b/upb_generator/names.cc @@ -55,6 +55,10 @@ ABSL_CONST_INIT const absl::string_view kRepeatedFieldArrayGetterPostfix = ABSL_CONST_INIT const absl::string_view kRepeatedFieldMutableArrayGetterPostfix = "mutable_upb_array"; +ABSL_CONST_INIT const absl::string_view kMapGetterPostfix = "upb_map"; +ABSL_CONST_INIT const absl::string_view kMutableMapGetterPostfix = + "mutable_upb_map"; + // List of generated accessor prefixes to check against. // Example: // optional repeated string phase = 236; diff --git a/upb_generator/names.h b/upb_generator/names.h index 7eef159451..1694dde454 100644 --- a/upb_generator/names.h +++ b/upb_generator/names.h @@ -69,6 +69,10 @@ ABSL_CONST_INIT extern const absl::string_view kRepeatedFieldArrayGetterPostfix; ABSL_CONST_INIT extern const absl::string_view kRepeatedFieldMutableArrayGetterPostfix; +// Private getter name postfix for map fields. +ABSL_CONST_INIT extern const absl::string_view kMapGetterPostfix; +ABSL_CONST_INIT extern const absl::string_view kMutableMapGetterPostfix; + } // namespace generator } // namespace upb diff --git a/upb_generator/protoc-gen-upb.cc b/upb_generator/protoc-gen-upb.cc index eb839790c2..7678f99a62 100644 --- a/upb_generator/protoc-gen-upb.cc +++ b/upb_generator/protoc-gen-upb.cc @@ -487,6 +487,27 @@ void GenerateMapGetters(upb::FieldDefPtr field, const DefPoolPair& pools, )cc", CTypeConst(field), msg_name, resolved_name, FieldInitializer(pools, field, options)); + // Generate private getter returning a upb_Map or NULL for immutable and + // a upb_Map for mutable. + // + // Example: + // UPB_INLINE const upb_Map* _name_immutable_upb_map(Foo* msg) + // UPB_INLINE upb_Map* _name_mutable_upb_map(Foo* msg, upb_Arena* a) + output( + R"cc( + UPB_INLINE const upb_Map* _$0_$1_$2($0* msg) { + const upb_MiniTableField field = $4; + return upb_Message_GetMap(msg, &field); + } + UPB_INLINE upb_Map* _$0_$1_$3($0* msg, upb_Arena* a) { + const upb_MiniTableField field = $4; + return _upb_Message_GetOrCreateMutableMap(msg, &field, $5, $6, a); + } + )cc", + msg_name, resolved_name, kMapGetterPostfix, kMutableMapGetterPostfix, + FieldInitializer(pools, field, options), + MapKeySize(field, MapKeyCType(field)), + MapValueSize(field, MapValueCType(field))); } void GenerateMapEntryGetters(upb::FieldDefPtr field, absl::string_view msg_name, @@ -1137,17 +1158,17 @@ int main(int argc, char** argv) { upb::generator::Plugin plugin; upb::generator::Options options; if (!ParseOptions(&plugin, &options)) return 0; - plugin.GenerateFilesRaw([&](const UPB_DESC(FileDescriptorProto) * file_proto, - bool generate) { - upb::Status status; - upb::FileDefPtr file = pools.AddFile(file_proto, &status); - if (!file) { - absl::string_view name = upb::generator::ToStringView( - UPB_DESC(FileDescriptorProto_name)(file_proto)); - ABSL_LOG(FATAL) << "Couldn't add file " << name - << " to DefPool: " << status.error_message(); - } - if (generate) GenerateFile(pools, file, options, &plugin); - }); + plugin.GenerateFilesRaw( + [&](const UPB_DESC(FileDescriptorProto) * file_proto, bool generate) { + upb::Status status; + upb::FileDefPtr file = pools.AddFile(file_proto, &status); + if (!file) { + absl::string_view name = upb::generator::ToStringView( + UPB_DESC(FileDescriptorProto_name)(file_proto)); + ABSL_LOG(FATAL) << "Couldn't add file " << name + << " to DefPool: " << status.error_message(); + } + if (generate) GenerateFile(pools, file, options, &plugin); + }); return 0; } From c8d2abe43da2b63f9b5bf13f3d5cb06b1bad0dc9 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 30 Oct 2023 07:16:29 -0700 Subject: [PATCH 76/95] Automated rollback of commit d76a6300d29d8d9feeeadddc28925ebd610b1f31. PiperOrigin-RevId: 577833443 --- src/google/protobuf/message.cc | 8 +++++++- src/google/protobuf/message.h | 11 ++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index eb81694daf..2cf07dbdf4 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -188,7 +188,13 @@ size_t Message::MaybeComputeUnknownFieldsSize( } size_t Message::SpaceUsedLong() const { - return GetReflection()->SpaceUsedLong(*this); + auto* reflection = GetReflection(); + if (PROTOBUF_PREDICT_TRUE(reflection != nullptr)) { + return reflection->SpaceUsedLong(*this); + } + // The only case that does not have reflection is RawMessage. + return internal::DownCast(*this) + .SpaceUsedLong(); } static std::string GetTypeNameImpl(const MessageLite& msg) { diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 83ba793e93..47f41b89ec 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -286,8 +286,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { void DiscardUnknownFields(); // Computes (an estimate of) the total number of bytes currently used for - // storing the message in memory. The default implementation calls the - // Reflection object's SpaceUsed() method. + // storing the message in memory. // // SpaceUsed() is noticeably slower than ByteSize(), as it is implemented // using reflection (rather than the generated code implementation for @@ -297,7 +296,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // Note: The precise value of this method should never be depended on, and can // change substantially due to internal details. In debug builds, this will // include a random fuzz factor to prevent these dependencies. - virtual size_t SpaceUsedLong() const; + size_t SpaceUsedLong() const; [[deprecated("Please use SpaceUsedLong() instead")]] int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); @@ -1573,6 +1572,12 @@ bool SplitFieldHasExtraIndirectionStatic(const FieldDescriptor* field) { return ret; } +class RawMessageBase : public Message { + public: + using Message::Message; + virtual size_t SpaceUsedLong() const = 0; +}; + } // namespace internal template From c9f9d991720392c6f7a438a92c93b145417fffcf Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 30 Oct 2023 07:19:27 -0700 Subject: [PATCH 77/95] Use GetArena() instead of GetOwningArena() #6. PiperOrigin-RevId: 577833979 --- src/google/protobuf/arena.h | 43 +------------------------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 83beb8f9b4..c4f8f5fc2c 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -389,32 +389,9 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // mutually exclusive fashion, we use implicit conversions to base classes // to force an explicit ranking for our preferences. The lowest ranked // version that compiles will be accepted. - struct Rank2 {}; - struct Rank1 : Rank2 {}; + struct Rank1 {}; struct Rank0 : Rank1 {}; - static Arena* GetOwningArena(const T* p) { - return GetOwningArena(Rank0{}, p); - } - - template - static auto GetOwningArena(Rank0, const U* p) - -> EnableIfArenaGetOwningArena())> { - return p->GetOwningArena(); - } - - // TODO: remove this function. - template - static auto GetOwningArena(Rank1, const U* p) - -> EnableIfArenaGetArena())> { - return p->GetArena(); - } - - template - static Arena* GetOwningArena(Rank2, const U*) { - return nullptr; - } - static void InternalSwap(T* a, T* b) { a->InternalSwap(b); } static Arena* GetArena(T* p) { return GetArena(Rank0{}, p); } @@ -466,28 +443,10 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { friend class TestUtil::ReflectionTester; }; - // Provides access to protected GetOwningArena to generated messages. For - // internal use only. - template - static Arena* InternalGetOwningArena(T* p) { - ABSL_DCHECK_EQ(InternalHelper::GetOwningArena(p), - InternalHelper::GetArena(p)); - return InternalHelper::GetOwningArena(p); - } - - // Wraps InternalGetArena() and will be removed soon. - // For internal use only. - template - static Arena* InternalGetArenaForAllocation(T* p) { - return InternalHelper::GetArena(p); - } - // Provides access to protected GetArena to generated messages. // For internal use only. template static Arena* InternalGetArena(T* p) { - ABSL_DCHECK_EQ(InternalHelper::GetOwningArena(p), - InternalHelper::GetArena(p)); return InternalHelper::GetArena(p); } From 6a16ab614704967b80f91b0c2b0fa886c55116e7 Mon Sep 17 00:00:00 2001 From: Jason Lunn Date: Mon, 30 Oct 2023 07:36:09 -0700 Subject: [PATCH 78/95] Check that ffi-compiler loads before using it to define tasks. (#14538) Fixes #14509 Closes #14538 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/14538 from JasonLunn:fix_14509 a3f9d0bd4f1f8036253c7a794a61e8cc84b4483c PiperOrigin-RevId: 577837541 --- ruby/lib/google/tasks/ffi.rake | 82 +++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/ruby/lib/google/tasks/ffi.rake b/ruby/lib/google/tasks/ffi.rake index 00e665fee2..c7b2a8e547 100644 --- a/ruby/lib/google/tasks/ffi.rake +++ b/ruby/lib/google/tasks/ffi.rake @@ -1,5 +1,3 @@ -require "ffi-compiler/compile_task" - # # @param task [FFI::Compiler::CompileTask] task to configure def configure_common_compile_task(task) if FileUtils.pwd.include? 'ext' @@ -49,46 +47,56 @@ def with_generated_files end end -desc "Compile Protobuf library for FFI" -namespace "ffi-protobuf" do - with_generated_files do - # Compile Ruby UPB separately in order to limit use of -DUPB_BUILD_API to one - # compilation unit. - desc "Compile UPB library for FFI" - namespace "ffi-upb" do - with_generated_files do - FFI::Compiler::CompileTask.new('ruby-upb') do |c| - configure_common_compile_task c - c.add_define "UPB_BUILD_API" - c.exclude << "/glue.c" - c.exclude << "/shared_message.c" - c.exclude << "/shared_convert.c" - if RbConfig::CONFIG['target_os'] =~ /darwin|linux/ - c.cflags << "-fvisibility=hidden" +begin + require "ffi-compiler/compile_task" + + desc "Compile Protobuf library for FFI" + namespace "ffi-protobuf" do + with_generated_files do + # Compile Ruby UPB separately in order to limit use of -DUPB_BUILD_API to one + # compilation unit. + desc "Compile UPB library for FFI" + namespace "ffi-upb" do + with_generated_files do + FFI::Compiler::CompileTask.new('ruby-upb') do |c| + configure_common_compile_task c + c.add_define "UPB_BUILD_API" + c.exclude << "/glue.c" + c.exclude << "/shared_message.c" + c.exclude << "/shared_convert.c" + if RbConfig::CONFIG['target_os'] =~ /darwin|linux/ + c.cflags << "-fvisibility=hidden" + end end end end - end - FFI::Compiler::CompileTask.new 'protobuf_c_ffi' do |c| - configure_common_compile_task c - # Ruby UPB was already compiled with different flags. - c.exclude << "/range2-neon.c" - c.exclude << "/range2-sse.c" - c.exclude << "/naive.c" - c.exclude << "/ruby-upb.c" - end + FFI::Compiler::CompileTask.new 'protobuf_c_ffi' do |c| + configure_common_compile_task c + # Ruby UPB was already compiled with different flags. + c.exclude << "/range2-neon.c" + c.exclude << "/range2-sse.c" + c.exclude << "/naive.c" + c.exclude << "/ruby-upb.c" + end - # Setup dependencies so that the .o files generated by building ffi-upb are - # available to link here. - # TODO Can this be simplified? Can the single shared library be used - # instead of the object files? - protobuf_c_task = Rake::Task[:default] - protobuf_c_shared_lib_task = Rake::Task[protobuf_c_task.prereqs.last] - ruby_upb_shared_lib_task = Rake::Task[:"ffi-upb:default"].prereqs.first - Rake::Task[ruby_upb_shared_lib_task].prereqs.each do |dependency| - protobuf_c_shared_lib_task.prereqs.prepend dependency + # Setup dependencies so that the .o files generated by building ffi-upb are + # available to link here. + # TODO Can this be simplified? Can the single shared library be used + # instead of the object files? + protobuf_c_task = Rake::Task[:default] + protobuf_c_shared_lib_task = Rake::Task[protobuf_c_task.prereqs.last] + ruby_upb_shared_lib_task = Rake::Task[:"ffi-upb:default"].prereqs.first + Rake::Task[ruby_upb_shared_lib_task].prereqs.each do |dependency| + protobuf_c_shared_lib_task.prereqs.prepend dependency + end + end + end +rescue LoadError + desc "Compile Protobuf library for FFI" + namespace "ffi-protobuf" do + task :default do + warn "Skipping build of FFI; `gem install ffi-compiler` to enable." end end end - From e56a9099f0dad5980d1990dc6a164402abaa470c Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Mon, 30 Oct 2023 09:39:19 -0700 Subject: [PATCH 79/95] upb: minimize uses of :message_types PiperOrigin-RevId: 577872176 --- upb/mini_table/BUILD | 1 - upb/reflection/BUILD | 2 -- upb/reflection/message.h | 2 +- upb/util/BUILD | 1 - upb/util/required_fields.c | 2 +- 5 files changed, 2 insertions(+), 6 deletions(-) diff --git a/upb/mini_table/BUILD b/upb/mini_table/BUILD index ecf2bbbb1c..f4b2ffe845 100644 --- a/upb/mini_table/BUILD +++ b/upb/mini_table/BUILD @@ -51,7 +51,6 @@ cc_library( "//upb:base", "//upb:hash", "//upb:mem", - "//upb:message_types", "//upb:port", ], ) diff --git a/upb/reflection/BUILD b/upb/reflection/BUILD index 0e92276c44..bf0c0e4dbe 100644 --- a/upb/reflection/BUILD +++ b/upb/reflection/BUILD @@ -55,7 +55,6 @@ bootstrap_cc_library( "//upb:base", "//upb:mem", "//upb:message", - "//upb:message_types", "//upb:message_value", "//upb:port", ], @@ -126,7 +125,6 @@ bootstrap_cc_library( "//upb:mem", "//upb:message", "//upb:message_accessors", - "//upb:message_types", "//upb:message_value", "//upb:mini_descriptor", "//upb:mini_descriptor_internal", diff --git a/upb/reflection/message.h b/upb/reflection/message.h index 9e57c1a16e..54af6f15af 100644 --- a/upb/reflection/message.h +++ b/upb/reflection/message.h @@ -12,7 +12,7 @@ #include "upb/mem/arena.h" #include "upb/message/map.h" -#include "upb/message/types.h" +#include "upb/message/message.h" #include "upb/message/value.h" // IWYU pragma: export #include "upb/reflection/common.h" diff --git a/upb/util/BUILD b/upb/util/BUILD index f15f351017..f354be10d8 100644 --- a/upb/util/BUILD +++ b/upb/util/BUILD @@ -99,7 +99,6 @@ cc_library( deps = [ "//upb:base", "//upb:message", - "//upb:message_types", "//upb:port", "//upb:reflection", ], diff --git a/upb/util/required_fields.c b/upb/util/required_fields.c index 4e66cdd9e6..c6616ecdd3 100644 --- a/upb/util/required_fields.c +++ b/upb/util/required_fields.c @@ -19,7 +19,7 @@ #include "upb/base/descriptor_constants.h" #include "upb/message/array.h" #include "upb/message/map.h" -#include "upb/message/types.h" +#include "upb/message/message.h" #include "upb/port/vsnprintf_compat.h" #include "upb/reflection/def.h" #include "upb/reflection/message.h" From 3667102d91bba05afcb777aa685b1014f521e9bc Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 30 Oct 2023 10:11:32 -0700 Subject: [PATCH 80/95] Remove `virtual` keyword. There are no overrides. PiperOrigin-RevId: 577881969 --- src/google/protobuf/message.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 47f41b89ec..6ddbaec21c 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -257,7 +257,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // messages which will be merged. Repeated fields will be concatenated. // The given message must be of the same type as this message (i.e. the // exact same class). - virtual void MergeFrom(const Message& from); + void MergeFrom(const Message& from); // Verifies that IsInitialized() returns true. ABSL_CHECK-fails otherwise, // with a nice error message. From 30f157529d660bdb36ec3ed5abeaa50cec2d4e5f Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Tue, 31 Oct 2023 11:47:43 -0700 Subject: [PATCH 81/95] feat: add protons extension (#14505) Adds an extension id to the registry for use by the [protons](https://www.npmjs.com/package/protons) protobuf encoder/decoder. Closes #14505 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/14505 from achingbrain:patch-1 1a80ee9b566943ff227e8a2075c6803d9562b9ae PiperOrigin-RevId: 578254102 --- docs/options.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/options.md b/docs/options.md index 18b6b410fa..aee889ecdf 100644 --- a/docs/options.md +++ b/docs/options.md @@ -486,3 +486,8 @@ with info about your project (name and website) so we can add an entry for you. * Website: https://square.github.io/wire/ * Extensions: 1185 + +1. Protons + + * Website: https://github.com/ipfs/protons + * Extensions: 1186 From 88249acbfdfd34dd24c04b032c4ae3578a481d2e Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Tue, 31 Oct 2023 13:46:24 -0700 Subject: [PATCH 82/95] Internal change PiperOrigin-RevId: 578290521 --- python/google/protobuf/internal/reflection_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index 2230d0c94d..1f22b86458 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -1462,6 +1462,7 @@ class Proto2ReflectionTest(unittest.TestCase): if api_implementation.Type() != 'python': return + file = descriptor.FileDescriptor(name='foo.proto', package='') FieldDescriptor = descriptor.FieldDescriptor foo_field_descriptor = FieldDescriptor( name='foo_field', full_name='MyProto.foo_field', @@ -1470,7 +1471,7 @@ class Proto2ReflectionTest(unittest.TestCase): label=FieldDescriptor.LABEL_OPTIONAL, default_value=0, containing_type=None, message_type=None, enum_type=None, is_extension=False, extension_scope=None, - options=descriptor_pb2.FieldOptions(), + options=descriptor_pb2.FieldOptions(), file=file, # pylint: disable=protected-access create_key=descriptor._internal_create_key) mydescriptor = descriptor.Descriptor( @@ -1478,6 +1479,7 @@ class Proto2ReflectionTest(unittest.TestCase): containing_type=None, nested_types=[], enum_types=[], fields=[foo_field_descriptor], extensions=[], options=descriptor_pb2.MessageOptions(), + file=file, # pylint: disable=protected-access create_key=descriptor._internal_create_key) From 712badffb14f6f6a4a3b12d659219fe90585f9e0 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Tue, 31 Oct 2023 16:17:23 -0700 Subject: [PATCH 83/95] Include .inc files directly instead of through a filegroup gRPC auto-generates CMake and other build configs from the Bazel build graph, but the logic for doing this does not know how to handle filegroups. This change works around that problem by making the `:port` target refer directly to the `.inc` files instead of going through a filegroup. This solution is not ideal but I think it's probably the best way to unblock progress for now. PiperOrigin-RevId: 578333954 --- upb/port/BUILD | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/upb/port/BUILD b/upb/port/BUILD index dc1c343c7a..fe20c085e5 100644 --- a/upb/port/BUILD +++ b/upb/port/BUILD @@ -14,7 +14,15 @@ cc_library( "vsnprintf_compat.h", ], copts = UPB_DEFAULT_COPTS, - textual_hdrs = [":inc"], + textual_hdrs = [ + # We must list the headers explicitly here instead of relying on the + # :inc filegroup below. gRPC auto-generates various build configs from + # the Bazel graph, and this logic does not know how to handle + # filegroups. We might be able to replace these headers with just + # ":inc" after gRPC starts using upb's CMake build. + "def.inc", + "undef.inc", + ], visibility = ["//visibility:public"], ) From abdcd6524635f71200ac5f8434680eaf10dcec2a Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 1 Nov 2023 08:54:52 -0700 Subject: [PATCH 84/95] Extract field descriptor enums into descriptor_lite.h, which can be included by protobuf_lite code. PiperOrigin-RevId: 578533045 --- src/google/protobuf/BUILD.bazel | 1 + src/google/protobuf/descriptor.h | 109 ++++++++++++++------------ src/google/protobuf/descriptor_lite.h | 87 ++++++++++++++++++++ 3 files changed, 145 insertions(+), 52 deletions(-) create mode 100644 src/google/protobuf/descriptor_lite.h diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index f85e88b16c..3bb21ad0ab 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -389,6 +389,7 @@ cc_library( "arena.h", "arenastring.h", "arenaz_sampler.h", + "descriptor_lite.h", "endian.h", "explicitly_constructed.h", "extension_set.h", diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index ff178c31c9..115a1f86a5 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -49,6 +49,7 @@ #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/types/optional.h" +#include "google/protobuf/descriptor_lite.h" #include "google/protobuf/extension_set.h" #include "google/protobuf/port.h" @@ -731,7 +732,8 @@ PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor, 152); // - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber() or // DescriptorPool::FindExtensionByPrintableName(). // Use DescriptorPool to construct your own descriptors. -class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase { +class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase, + public internal::FieldDescriptorLite { public: typedef FieldDescriptorProto Proto; @@ -742,64 +744,67 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase { // Identifies a field type. 0 is reserved for errors. The order is weird // for historical reasons. Types 12 and up are new in proto2. - enum Type { - TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. - TYPE_FLOAT = 2, // float, exactly four bytes on the wire. - TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers - // take 10 bytes. Use TYPE_SINT64 if negative - // values are likely. - TYPE_UINT64 = 4, // uint64, varint on the wire. - TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers - // take 10 bytes. Use TYPE_SINT32 if negative - // values are likely. - TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. - TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. - TYPE_BOOL = 8, // bool, varint on the wire. - TYPE_STRING = 9, // UTF-8 text. - TYPE_GROUP = 10, // Tag-delimited message. Deprecated. - TYPE_MESSAGE = 11, // Length-delimited message. - - TYPE_BYTES = 12, // Arbitrary byte array. - TYPE_UINT32 = 13, // uint32, varint on the wire - TYPE_ENUM = 14, // Enum, varint on the wire - TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire - TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire - TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire - TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire - - MAX_TYPE = 18, // Constant useful for defining lookup tables - // indexed by Type. - }; + // Inherited from FieldDescriptorLite: + // enum Type { + // TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. + // TYPE_FLOAT = 2, // float, exactly four bytes on the wire. + // TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers + // // take 10 bytes. Use TYPE_SINT64 if negative + // // values are likely. + // TYPE_UINT64 = 4, // uint64, varint on the wire. + // TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers + // // take 10 bytes. Use TYPE_SINT32 if negative + // // values are likely. + // TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. + // TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. + // TYPE_BOOL = 8, // bool, varint on the wire. + // TYPE_STRING = 9, // UTF-8 text. + // TYPE_GROUP = 10, // Tag-delimited message. Deprecated. + // TYPE_MESSAGE = 11, // Length-delimited message. + + // TYPE_BYTES = 12, // Arbitrary byte array. + // TYPE_UINT32 = 13, // uint32, varint on the wire + // TYPE_ENUM = 14, // Enum, varint on the wire + // TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire + // TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire + // TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire + // TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire + + // MAX_TYPE = 18, // Constant useful for defining lookup tables + // // indexed by Type. + // }; // Specifies the C++ data type used to represent the field. There is a // fixed mapping from Type to CppType where each Type maps to exactly one // CppType. 0 is reserved for errors. - enum CppType { - CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 - CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 - CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 - CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 - CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE - CPPTYPE_FLOAT = 6, // TYPE_FLOAT - CPPTYPE_BOOL = 7, // TYPE_BOOL - CPPTYPE_ENUM = 8, // TYPE_ENUM - CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES - CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP - - MAX_CPPTYPE = 10, // Constant useful for defining lookup tables - // indexed by CppType. - }; + // Inherited from FieldDescriptorLite: + // enum CppType { + // CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 + // CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 + // CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 + // CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 + // CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE + // CPPTYPE_FLOAT = 6, // TYPE_FLOAT + // CPPTYPE_BOOL = 7, // TYPE_BOOL + // CPPTYPE_ENUM = 8, // TYPE_ENUM + // CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES + // CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP + + // MAX_CPPTYPE = 10, // Constant useful for defining lookup tables + // // indexed by CppType. + // }; // Identifies whether the field is optional, required, or repeated. 0 is // reserved for errors. - enum Label { - LABEL_OPTIONAL = 1, // optional - LABEL_REQUIRED = 2, // required - LABEL_REPEATED = 3, // repeated - - MAX_LABEL = 3, // Constant useful for defining lookup tables - // indexed by Label. - }; + // Inherited from FieldDescriptorLite: + // enum Label { + // LABEL_OPTIONAL = 1, // optional + // LABEL_REQUIRED = 2, // required + // LABEL_REPEATED = 3, // repeated + + // MAX_LABEL = 3, // Constant useful for defining lookup tables + // // indexed by Label. + // }; // Valid field numbers are positive integers up to kMaxNumber. static const int kMaxNumber = (1 << 29) - 1; diff --git a/src/google/protobuf/descriptor_lite.h b/src/google/protobuf/descriptor_lite.h new file mode 100644 index 0000000000..db5805affe --- /dev/null +++ b/src/google/protobuf/descriptor_lite.h @@ -0,0 +1,87 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd +// +// This file contains definitions for the descriptors, so they can be used +// without importing descriptor.h + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_LITE_H__ +#define GOOGLE_PROTOBUF_DESCRIPTOR_LITE_H__ + +namespace google { +namespace protobuf { +namespace internal { + +class FieldDescriptorLite { + public: + // Identifies a field type. 0 is reserved for errors. + // The order is weird for historical reasons. + // Types 12 and up are new in proto2. + enum Type { + TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. + TYPE_FLOAT = 2, // float, exactly four bytes on the wire. + TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT64 if negative + // values are likely. + TYPE_UINT64 = 4, // uint64, varint on the wire. + TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT32 if negative + // values are likely. + TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. + TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. + TYPE_BOOL = 8, // bool, varint on the wire. + TYPE_STRING = 9, // UTF-8 text. + TYPE_GROUP = 10, // Tag-delimited message. Deprecated. + TYPE_MESSAGE = 11, // Length-delimited message. + + TYPE_BYTES = 12, // Arbitrary byte array. + TYPE_UINT32 = 13, // uint32, varint on the wire + TYPE_ENUM = 14, // Enum, varint on the wire + TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire + TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire + TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire + TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire + + MAX_TYPE = 18, // Constant useful for defining lookup tables + // indexed by Type. + }; + + // Specifies the C++ data type used to represent the field. There is a + // fixed mapping from Type to CppType where each Type maps to exactly one + // CppType. 0 is reserved for errors. + enum CppType { + CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 + CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 + CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 + CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 + CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE + CPPTYPE_FLOAT = 6, // TYPE_FLOAT + CPPTYPE_BOOL = 7, // TYPE_BOOL + CPPTYPE_ENUM = 8, // TYPE_ENUM + CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES + CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP + + MAX_CPPTYPE = 10, // Constant useful for defining lookup tables + // indexed by CppType. + }; + + // Identifies whether the field is optional, required, or repeated. 0 is + // reserved for errors. + enum Label { + LABEL_OPTIONAL = 1, // optional + LABEL_REQUIRED = 2, // required + LABEL_REPEATED = 3, // repeated + + MAX_LABEL = 3, // Constant useful for defining lookup tables + // indexed by Label. + }; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_DESCRIPTOR_LITE_H__ From f083530a0655338b5a1b8dfa0d46727cf1048dd9 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Wed, 1 Nov 2023 10:26:00 -0700 Subject: [PATCH 85/95] Allow string + bytes fields in oneofs (now that the underyling accessors match the expected shape) PiperOrigin-RevId: 578561161 --- rust/test/shared/accessors_proto3_test.rs | 5 ++--- rust/test/shared/accessors_test.rs | 5 ++--- src/google/protobuf/compiler/rust/accessors/accessors.cc | 4 ++-- src/google/protobuf/compiler/rust/oneof.cc | 7 +++++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/rust/test/shared/accessors_proto3_test.rs b/rust/test/shared/accessors_proto3_test.rs index 3260c0d11d..3eb6e5df61 100644 --- a/rust/test/shared/accessors_proto3_test.rs +++ b/rust/test/shared/accessors_proto3_test.rs @@ -200,9 +200,8 @@ fn test_oneof_accessors() { assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); msg.oneof_uint32_set(Some(7)); - msg.oneof_bytes_mut().set(b""); + msg.oneof_bytes_mut().set(b"123"); assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0))); - // This should show it set to the OneofBytes but its not supported yet. - assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); + assert_that!(msg.oneof_field(), matches_pattern!(OneofBytes(eq(b"123")))); } diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs index f1f55f663d..2b207ac11c 100644 --- a/rust/test/shared/accessors_test.rs +++ b/rust/test/shared/accessors_test.rs @@ -690,11 +690,10 @@ fn test_oneof_accessors() { assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); msg.oneof_uint32_set(Some(7)); - msg.oneof_bytes_mut().set(b""); + msg.oneof_bytes_mut().set(b"123"); assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0))); - // This should show it set to the OneofBytes but its not supported yet. - assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); + assert_that!(msg.oneof_field(), matches_pattern!(OneofBytes(eq(b"123")))); } macro_rules! generate_repeated_numeric_test { diff --git a/src/google/protobuf/compiler/rust/accessors/accessors.cc b/src/google/protobuf/compiler/rust/accessors/accessors.cc index fa5c876bf9..807eb478b3 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessors.cc +++ b/src/google/protobuf/compiler/rust/accessors/accessors.cc @@ -23,8 +23,8 @@ namespace { std::unique_ptr AccessorGeneratorFor( const FieldDescriptor& desc) { - // We do not support [ctype=FOO] (used to set the field type in C++ to - // cord or string_piece) in V0 API. + // TODO: We do not support [ctype=FOO] (used to set the field + // type in C++ to cord or string_piece) in V0.6 API. if (desc.options().has_ctype()) { return std::make_unique(); } diff --git a/src/google/protobuf/compiler/rust/oneof.cc b/src/google/protobuf/compiler/rust/oneof.cc index 2cdeeac203..41f5bb9a1c 100644 --- a/src/google/protobuf/compiler/rust/oneof.cc +++ b/src/google/protobuf/compiler/rust/oneof.cc @@ -92,12 +92,15 @@ std::string oneofCaseEnumName(const OneofDescriptor& desc) { // TODO: Promote up to naming.h once all types can be spelled. std::string RsTypeName(const FieldDescriptor& desc) { + // TODO: Fields with a ctype set not supported in v0.6 api. + if (desc.options().has_ctype()) { + return ""; + } + switch (desc.type()) { case FieldDescriptor::TYPE_MESSAGE: case FieldDescriptor::TYPE_ENUM: case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: return ""; default: return PrimitiveRsTypeName(desc); From b0eeb356b84fb7e8773c9a0dd76b354ae2e3f218 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 1 Nov 2023 10:33:11 -0700 Subject: [PATCH 86/95] Fixed Python memory leak in map lookup. Previously we were allocating memory on the message's arena every time we performed a `map[key]` or `map.get(key)` operation. This is unnecessary, as the key's data is only needed ephemerally, for the duration of the lookup, and we can therefore alias the Python object's string data instead of copying it. This required fixing a bug in the convert.c operation. Previously in the `arena==NULL` case, if the user passes a bytes object instead of a unicode string, the code would return a pointer to a temporary Python object that had already been freed, leading to use-after-free. I fixed this by referencing the bytes object's data directly, and using utf8_range to verify the UTF-8. Fixes: https://github.com/protocolbuffers/protobuf/issues/14571 PiperOrigin-RevId: 578563555 --- python/BUILD | 1 + python/convert.c | 32 ++++++++++++------- .../google/protobuf/internal/message_test.py | 1 - python/map.c | 8 ++--- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/python/BUILD b/python/BUILD index 92e9c496c5..ea1dac3160 100644 --- a/python/BUILD +++ b/python/BUILD @@ -203,5 +203,6 @@ py_extension( "//upb/util:compare", "//upb/util:def_to_proto", "//upb/util:required_fields", + "@utf8_range", ], ) diff --git a/python/convert.c b/python/convert.c index 413c42f735..0c1174ba6b 100644 --- a/python/convert.c +++ b/python/convert.c @@ -35,6 +35,7 @@ #include "upb/message/map.h" #include "upb/reflection/message.h" #include "upb/util/compare.h" +#include "utf8_range.h" // Must be last. #include "upb/port/def.inc" @@ -259,20 +260,27 @@ bool PyUpb_PyToUpb(PyObject* obj, const upb_FieldDef* f, upb_MessageValue* val, } case kUpb_CType_String: { Py_ssize_t size; - const char* ptr; - PyObject* unicode = NULL; if (PyBytes_Check(obj)) { - unicode = obj = PyUnicode_FromEncodedObject(obj, "utf-8", NULL); - if (!obj) return false; + // Use the object's bytes if they are valid UTF-8. + char* ptr; + if (PyBytes_AsStringAndSize(obj, &ptr, &size) < 0) return false; + if (utf8_range2((const unsigned char*)ptr, size) != 0) { + // Invalid UTF-8. Try to convert the message to a Python Unicode + // object, even though we know this will fail, just to get the + // idiomatic Python error message. + obj = PyUnicode_FromEncodedObject(obj, "utf-8", NULL); + assert(!obj); + return false; + } + *val = PyUpb_MaybeCopyString(ptr, size, arena); + return true; + } else { + const char* ptr; + ptr = PyUnicode_AsUTF8AndSize(obj, &size); + if (PyErr_Occurred()) return false; + *val = PyUpb_MaybeCopyString(ptr, size, arena); + return true; } - ptr = PyUnicode_AsUTF8AndSize(obj, &size); - if (PyErr_Occurred()) { - Py_XDECREF(unicode); - return false; - } - *val = PyUpb_MaybeCopyString(ptr, size, arena); - Py_XDECREF(unicode); - return true; } case kUpb_CType_Message: PyErr_Format(PyExc_ValueError, "Message objects may not be assigned"); diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index 0bac00da02..b0f1ae784f 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -48,7 +48,6 @@ UCS2_MAXUNICODE = 65535 warnings.simplefilter('error', DeprecationWarning) - @_parameterized.named_parameters(('_proto2', unittest_pb2), ('_proto3', unittest_proto3_arena_pb2)) @testing_refleaks.TestCase diff --git a/python/map.c b/python/map.c index a1d75de9a1..6bf12af438 100644 --- a/python/map.c +++ b/python/map.c @@ -179,7 +179,7 @@ int PyUpb_MapContainer_AssignSubscript(PyObject* _self, PyObject* key, const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1); upb_Arena* arena = PyUpb_Arena_Get(self->arena); upb_MessageValue u_key, u_val; - if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return -1; + if (!PyUpb_PyToUpb(key, key_f, &u_key, NULL)) return -1; if (val) { if (!PyUpb_PyToUpb(val, val_f, &u_val, arena)) return -1; @@ -200,9 +200,8 @@ PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) { const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f); const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0); const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1); - upb_Arena* arena = PyUpb_Arena_Get(self->arena); upb_MessageValue u_key, u_val; - if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return NULL; + if (!PyUpb_PyToUpb(key, key_f, &u_key, NULL)) return NULL; if (!map || !upb_Map_Get(map, u_key, &u_val)) { map = PyUpb_MapContainer_EnsureReified(_self); upb_Arena* arena = PyUpb_Arena_Get(self->arena); @@ -256,9 +255,8 @@ static PyObject* PyUpb_MapContainer_Get(PyObject* _self, PyObject* args, const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f); const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0); const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1); - upb_Arena* arena = PyUpb_Arena_Get(self->arena); upb_MessageValue u_key, u_val; - if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return NULL; + if (!PyUpb_PyToUpb(key, key_f, &u_key, NULL)) return NULL; if (map && upb_Map_Get(map, u_key, &u_val)) { return PyUpb_UpbToPy(u_val, val_f, self->arena); } From f2ce105a484475a5195ed6d66689fa74c90aad2d Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 1 Nov 2023 12:17:02 -0700 Subject: [PATCH 87/95] Migrate tests to windows 2022 by default. For the windows 2019 test, we need to upgrade python for the latest gcloud to work. PiperOrigin-RevId: 578600130 --- .github/workflows/test_cpp.yml | 44 ++++++++++++++++++++-------------- .github/workflows/test_upb.yml | 2 +- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/.github/workflows/test_cpp.yml b/.github/workflows/test_cpp.yml index 62f8296ad5..54b28006a9 100644 --- a/.github/workflows/test_cpp.yml +++ b/.github/workflows/test_cpp.yml @@ -324,8 +324,8 @@ jobs: # for Apple Silicon to detect issues there. bazel: build --cpu=darwin_arm64 //src/... - name: Windows - os: windows-2019 - cache_key: windows-2019 + os: windows-2022 + cache_key: windows-2022 bazel: test //src/... @com_google_protobuf_examples//... --test_tag_filters=-conformance --build_tag_filters=-conformance name: ${{ matrix.name }} Bazel runs-on: ${{ matrix.os }} @@ -351,14 +351,6 @@ jobs: flags: -DCMAKE_CXX_STANDARD=14 cache-prefix: macos-cmake - name: Windows CMake - os: windows-2019 - flags: >- - -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF - -Dprotobuf_BUILD_SHARED_LIBS=OFF - -Dprotobuf_BUILD_EXAMPLES=ON - vsversion: '2019' - cache-prefix: windows-2019-cmake - - name: Windows CMake 2022 os: windows-2022 flags: >- -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF @@ -366,29 +358,38 @@ jobs: -Dprotobuf_BUILD_EXAMPLES=ON vsversion: '2022' cache-prefix: windows-2022-cmake - - name: Windows CMake 32-bit + - name: Windows CMake 2019 os: windows-2019 flags: >- -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF + -Dprotobuf_BUILD_SHARED_LIBS=OFF + -Dprotobuf_BUILD_EXAMPLES=ON vsversion: '2019' + cache-prefix: windows-2019-cmake + python-version: '3.8' + - name: Windows CMake 32-bit + os: windows-2022 + flags: >- + -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF + vsversion: '2022' windows-arch: 'win32' - cache-prefix: windows-2019-win32-cmake + cache-prefix: windows-2022-win32-cmake - name: Windows CMake Shared - os: windows-2019 + os: windows-2022 flags: >- -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_BUILD_SHARED_LIBS=ON - vsversion: '2019' - cache-prefix: windows-2019-cmake + vsversion: '2022' + cache-prefix: windows-2022-cmake - name: Windows CMake Install - os: windows-2019 + os: windows-2022 install-flags: -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_BUILD_TESTS=OFF flags: >- -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_REMOVE_INSTALLED_HEADERS=ON -Dprotobuf_BUILD_PROTOBUF_BINARIES=OFF - vsversion: '2019' - cache-prefix: windows-2019-cmake + vsversion: '2022' + cache-prefix: windows-2022-cmake name: ${{ matrix.name }} runs-on: ${{ matrix.os }} steps: @@ -398,6 +399,13 @@ jobs: ref: ${{ inputs.safe-checkout }} submodules: recursive + - name: Install Python + if: ${{ matrix.python-version }} + uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 + with: + python-version: ${{ matrix.python-version }} + cache: pip + - name: Setup MSVC if: ${{ runner.os == 'Windows' }} uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1 diff --git a/.github/workflows/test_upb.yml b/.github/workflows/test_upb.yml index f2c1cfa2e4..a8454bfe78 100644 --- a/.github/workflows/test_upb.yml +++ b/.github/workflows/test_upb.yml @@ -64,7 +64,7 @@ jobs: strategy: fail-fast: false # Don't cancel all jobs if one fails. name: Windows - runs-on: windows-2019 + runs-on: windows-2022 steps: - name: Checkout pending changes uses: protocolbuffers/protobuf-ci/checkout@v2 From b4c9546467563038a2db97ef268837cbcf110cd8 Mon Sep 17 00:00:00 2001 From: Cong Liu Date: Wed, 1 Nov 2023 15:11:35 -0700 Subject: [PATCH 88/95] Cluster non cold subtables in aux entries to the top. PiperOrigin-RevId: 578656159 --- src/google/protobuf/compiler/cpp/options.h | 1 + .../compiler/cpp/parse_function_generator.cc | 8 ++- .../protobuf/generated_message_reflection.cc | 1 + .../protobuf/generated_message_tctable_gen.cc | 50 ++++++++++++++++--- .../protobuf/generated_message_tctable_gen.h | 2 + src/google/protobuf/message_unittest.inc | 3 +- 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/options.h b/src/google/protobuf/compiler/cpp/options.h index 5ae95353fb..30be9c0bb2 100644 --- a/src/google/protobuf/compiler/cpp/options.h +++ b/src/google/protobuf/compiler/cpp/options.h @@ -54,6 +54,7 @@ struct Options { bool opensource_runtime = false; bool annotate_accessor = false; bool force_split = false; + bool profile_driven_cluster_aux_subtable = false; #ifdef PROTOBUF_STABLE_EXPERIMENTS bool force_eagerly_verified_lazy = true; bool force_inline_string = true; diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index 6fb3aa85e3..a8074dfce7 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -116,11 +116,9 @@ ParseFunctionGenerator::ParseFunctionGenerator( if (should_generate_tctable()) { tc_table_info_.reset(new TailCallTableInfo( descriptor_, ordered_fields_, - { - /* is_lite */ GetOptimizeFor(descriptor->file(), options_) == - FileOptions::LITE_RUNTIME, - /* uses_codegen */ true, - }, + {/* is_lite */ GetOptimizeFor(descriptor->file(), options_) == + FileOptions::LITE_RUNTIME, + /* uses_codegen */ true, options_.profile_driven_cluster_aux_subtable}, GeneratedOptionProvider(this), has_bit_indices, inlined_string_indices)); } diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 84272163fe..a2e9c7cb83 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -3416,6 +3416,7 @@ const internal::TcParseTableBase* Reflection::CreateTcParseTable() const { { /* is_lite */ false, /* uses_codegen */ false, + /* should_profile_driven_cluster_aux_table */ false, }, ReflectionOptionProvider(*this), has_bit_indices, inlined_string_indices); diff --git a/src/google/protobuf/generated_message_tctable_gen.cc b/src/google/protobuf/generated_message_tctable_gen.cc index 7c1736d63e..6740e35b50 100644 --- a/src/google/protobuf/generated_message_tctable_gen.cc +++ b/src/google/protobuf/generated_message_tctable_gen.cc @@ -8,6 +8,7 @@ #include "google/protobuf/generated_message_tctable_gen.h" #include +#include #include #include #include @@ -756,6 +757,35 @@ TailCallTableInfo::TailCallTableInfo( } } + auto is_non_cold = [](PerFieldOptions options) { + return options.presence_probability >= 0.005; + }; + size_t num_non_cold_subtables = 0; + if (message_options.should_profile_driven_cluster_aux_subtable) { + // We found that clustering non-cold subtables to the top of aux_entries + // achieves the best load tests results than other strategies (e.g., + // clustering all non-cold entries). + auto is_non_cold_subtable = [&](const FieldDescriptor* field) { + auto options = option_provider.GetForField(field); + // In the following code where we assign kSubTable to aux entries, only + // the following typed fields are supported. + return (field->type() == FieldDescriptor::TYPE_MESSAGE || + field->type() == FieldDescriptor::TYPE_GROUP) && + !field->is_map() && !HasLazyRep(field, options) && + !options.is_implicitly_weak && options.use_direct_tcparser_table && + is_non_cold(options); + }; + for (const FieldDescriptor* field : ordered_fields) { + if (is_non_cold_subtable(field)) { + num_non_cold_subtables++; + } + } + } + + size_t subtable_aux_idx_begin = aux_entries.size(); + size_t subtable_aux_idx = aux_entries.size(); + aux_entries.resize(aux_entries.size() + num_non_cold_subtables); + // Fill in mini table entries. for (const FieldDescriptor* field : ordered_fields) { auto options = option_provider.GetForField(field); @@ -797,12 +827,18 @@ TailCallTableInfo::TailCallTableInfo( TcParseTableBase::FieldEntry::kNoAuxIdx; } } else { - field_entries.back().aux_idx = aux_entries.size(); - aux_entries.push_back({options.is_implicitly_weak ? kSubMessageWeak - : options.use_direct_tcparser_table - ? kSubTable - : kSubMessage, - {field}}); + AuxType type = options.is_implicitly_weak ? kSubMessageWeak + : options.use_direct_tcparser_table ? kSubTable + : kSubMessage; + if (message_options.should_profile_driven_cluster_aux_subtable && + type == kSubTable && is_non_cold(options)) { + aux_entries[subtable_aux_idx] = {type, {field}}; + field_entries.back().aux_idx = subtable_aux_idx; + ++subtable_aux_idx; + } else { + field_entries.back().aux_idx = aux_entries.size(); + aux_entries.push_back({type, {field}}); + } } } else if (field->type() == FieldDescriptor::TYPE_ENUM && !cpp::HasPreservingUnknownEnumSemantics(field)) { @@ -845,6 +881,8 @@ TailCallTableInfo::TailCallTableInfo( entry.inlined_string_idx = idx; } } + ABSL_CHECK_EQ(subtable_aux_idx - subtable_aux_idx_begin, + num_non_cold_subtables); table_size_log2 = 0; // fallback value int num_fast_fields = -1; diff --git a/src/google/protobuf/generated_message_tctable_gen.h b/src/google/protobuf/generated_message_tctable_gen.h index bf202712a4..514f590a57 100644 --- a/src/google/protobuf/generated_message_tctable_gen.h +++ b/src/google/protobuf/generated_message_tctable_gen.h @@ -38,6 +38,8 @@ struct PROTOBUF_EXPORT TailCallTableInfo { struct MessageOptions { bool is_lite; bool uses_codegen; + // TODO: remove this after A/B test is done. + bool should_profile_driven_cluster_aux_subtable; }; struct PerFieldOptions { // For presence awareness (e.g. PDProto). diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index 4e07c69367..0dae9657fa 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -1937,9 +1937,10 @@ TEST(MESSAGE_TEST_NAME, TestRegressionInlinedStringAuxIdxMismatchOnFastParser) { if (table != nullptr && table->fast_entry(1)->target() == internal::TcParser::FastSiS1) { // optional string str1 = 1; + // The aux_idx points to the inlined_string_idx and not the actual aux_idx. EXPECT_EQ(table->fast_entry(1)->bits.aux_idx(), 1); // optional InlinedStringIdxRegressionProto sub = 2; - EXPECT_EQ(table->fast_entry(2)->bits.aux_idx(), 2); + EXPECT_EQ(table->fast_entry(2)->bits.aux_idx(), 1); // optional string str2 = 3; // The aux_idx points to the inlined_string_idx and not the actual aux_idx. EXPECT_EQ(table->fast_entry(3)->bits.aux_idx(), 2); From 769ab10e3b9f5b9ccf9a46c786091960812938c2 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 1 Nov 2023 16:18:47 -0700 Subject: [PATCH 89/95] Fix windows 2019 build. setup-gcloud doesn't honor the environment variables set by setup-python, so we need to manually set CLOUDSDK_PYTHON before running it. PiperOrigin-RevId: 578674246 --- .github/workflows/test_cpp.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test_cpp.yml b/.github/workflows/test_cpp.yml index 54b28006a9..55c061bc1b 100644 --- a/.github/workflows/test_cpp.yml +++ b/.github/workflows/test_cpp.yml @@ -366,6 +366,7 @@ jobs: -Dprotobuf_BUILD_EXAMPLES=ON vsversion: '2019' cache-prefix: windows-2019-cmake + # windows-2019 has python3.7 installed, which is incompatible with the latest gcloud python-version: '3.8' - name: Windows CMake 32-bit os: windows-2022 @@ -399,13 +400,6 @@ jobs: ref: ${{ inputs.safe-checkout }} submodules: recursive - - name: Install Python - if: ${{ matrix.python-version }} - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 - with: - python-version: ${{ matrix.python-version }} - cache: pip - - name: Setup MSVC if: ${{ runner.os == 'Windows' }} uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1 @@ -413,6 +407,17 @@ jobs: arch: ${{ matrix.windows-arch || 'x64' }} vsversion: ${{ matrix.vsversion }} + # Workaround for incompatibility between gcloud and windows-2019 runners. + - name: Install Python + if: ${{ matrix.python-version }} + uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 + with: + python-version: ${{ matrix.python-version }} + - name: Use custom python for gcloud + if: ${{ matrix.python-version }} + run: echo "CLOUDSDK_PYTHON=${Python3_ROOT_DIR}\\python3" >> $GITHUB_ENV + shell: bash + - name: Setup sccache uses: protocolbuffers/protobuf-ci/sccache@v2 with: From 5f146f8dfefd136eb969ed3bb73bdd95a462c4f3 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 1 Nov 2023 22:17:29 -0700 Subject: [PATCH 90/95] Enable caching of pip dependencies PiperOrigin-RevId: 578740011 --- .github/workflows/test_python.yml | 1 + .github/workflows/test_upb.yml | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_python.yml b/.github/workflows/test_python.yml index e207ee3a92..0bec9a06c3 100644 --- a/.github/workflows/test_python.yml +++ b/.github/workflows/test_python.yml @@ -76,6 +76,7 @@ jobs: with: python-version: ${{ matrix.version }} cache: pip + cache-dependency-path: 'python/requirements.txt' - name: Validate version run: python3 --version | grep ${{ matrix.version }} || (echo "Invalid Python version - $(python3 --version)" && exit 1) diff --git a/.github/workflows/test_upb.yml b/.github/workflows/test_upb.yml index a8454bfe78..32b9ff8251 100644 --- a/.github/workflows/test_upb.yml +++ b/.github/workflows/test_upb.yml @@ -70,6 +70,10 @@ jobs: uses: protocolbuffers/protobuf-ci/checkout@v2 with: ref: ${{ inputs.safe-checkout }} + - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 + with: + cache: pip + cache-dependency-path: 'python/requirements.txt' - name: Run tests uses: protocolbuffers/protobuf-ci/bazel@v2 with: @@ -92,6 +96,10 @@ jobs: uses: protocolbuffers/protobuf-ci/checkout@v2 with: ref: ${{ inputs.safe-checkout }} + - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 + with: + cache: pip + cache-dependency-path: 'python/requirements.txt' - name: Run tests uses: protocolbuffers/protobuf-ci/bazel@v2 with: @@ -195,7 +203,7 @@ jobs: with: name: requirements path: requirements - - uses: actions/setup-python@v2 + - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 with: python-version: ${{ matrix.python-version }} architecture: ${{ matrix.architecture }} @@ -250,7 +258,7 @@ jobs: path: wheels - name: Delete Binary Wheels run: find wheels -type f | grep -v none-any | xargs rm - - uses: actions/setup-python@v2 + - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 with: python-version: ${{ matrix.python-version }} - name: Setup Python venv From 725b477032a9806d28cf7774d5504b7832f7c6ba Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 2 Nov 2023 05:27:53 -0700 Subject: [PATCH 91/95] Adds "Editions: Feature Extension Layout" to the GitHub code repository. PiperOrigin-RevId: 578819110 --- docs/design/editions/README.md | 1 + .../editions-feature-extension-layout.md | 150 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 docs/design/editions/editions-feature-extension-layout.md diff --git a/docs/design/editions/README.md b/docs/design/editions/README.md index 483ce860c0..c551f91ab0 100644 --- a/docs/design/editions/README.md +++ b/docs/design/editions/README.md @@ -36,3 +36,4 @@ The following topics are in this repository: * [Edition Naming](edition-naming.md) * [Editions Feature Visibility](editions-feature-visibility.md) * [Legacy Syntax Editions](legacy-syntax-editions.md) +* [Editions: Feature Extension Layout](editions-feature-extension-layout.md) \ No newline at end of file diff --git a/docs/design/editions/editions-feature-extension-layout.md b/docs/design/editions/editions-feature-extension-layout.md new file mode 100644 index 0000000000..67626a4388 --- /dev/null +++ b/docs/design/editions/editions-feature-extension-layout.md @@ -0,0 +1,150 @@ +# Editions: Feature Extension Layout + +**Author:** [@mkruskal-google](https://github.com/mkruskal-google), +[@zhangskz](https://github.com/zhangskz) + +**Approved:** 2023-08-23 + +## Background + +"[What are Protobuf Editions](what-are-protobuf-editions.md)" lays out a plan +for allowing for more targeted features not owned by the protobuf team. It uses +extensions of the global features proto to implement this. One thing that was +left a bit ambiguous was *who* should own these extensions. Language, code +generator, and runtime implementations are all similar but not identical +distinctions. + +"Editions Zero Feature: utf8_validation" (not available externally, though a +later version, +"[Editions Zero: utf8_validation Without Problematic Options](editions-zero-utf8_validation.md)" +is) is a recent plan to add a new set of generator features for utf8 validation. +While the sole feature we had originally created (`legacy_closed_enum` in Java +and C++) didn't have any ambiguity here, this one did. Specifically in Python, +the current behaviors across proto2/proto3 are distinct for all 3 +implementations: pure python, Python/C++, Python/upb. + +## Overview + +In meetings, we've discussed various alternatives, captured below. The original +plan was to make feature extensions runtime implementation-specific (e.g. C++, +Java, Python, upb). There are some notable complications that came up though: + +1. **Polyglot** - it's not clear how upb or C++ runtimes should behave in + multi-language situations. Which feature sets do they consider for runtime + behaviors? *Note: this is already a serious issue today, where all proto2 + strings and many proto3 strings are completely unsafe across languages.* + +2. **Shared Implementations** - Runtimes like upb and C++ are used as backing + implementations of multiple other languages (e.g. Python, Rust, Ruby, PHP). + If we have a single set of `upb` or `cpp` features, migrating to those + shared implementations would be more difficult (since there's no independent + switches per-language). *Note: this is already the situation we're in today, + where switching the runtime implementation can cause subtle and dangerous + behavior changes.* + +Given that we only have two behaviors, and one of them is unambiguous, it seems +reasonable to punt on this decision until we have more information. We may +encounter more edge cases that require feature extensions (and give us more +information) during the rollout of edition zero. We also have a lot of freedom +to re-model features in later editions, so keeping the initial implementation as +simple as possible seems best (i.e. Alternative 2). + +## Alternatives + +### Alternative 1: Runtime Implementation Features + +Features would be per-runtime implementation as originally described in +"Editions Zero Feature: utf8_validation." For example, Protobuf Python users +would set different features depending on the backing implementation (e.g. +`features.(pb.cpp).`, `features.(pb.upb).`). + +#### Pros + +* Most consistent with range of behaviors expressible pre-Editions + +#### Cons + +* Implementation may / should not be obvious to users. +* Lack of levers specifically for language / implementation combos. For + example, there is no way to set Python-C++ behavior independently of C++ + behavior which may make migration harder from other Python implementations. + +### Alternative 2: Generator Features + +Features would be per-generator only (i.e. each protoc plugin would own one set +of features). This was the second decision we made in later discussions, and +while very similar to the above alternative, it's more inline with our goal of +making features primarily for codegen. + +For example, all Python implementations would share the same set of features +(e.g. `features.(pb.python).`). However, certain features could be +targeted to specific implementations (e.g. +`features.(pb.python).upb_utf8_validation` would only be used by Python/upb). + +#### Pros + +* Allows independent controls of shared implementations in different target + languages (e.g. Python's upb feature won't affect PHP). + +#### Cons + +* Possible complexity in upb to understand which language's features to + respect. UPB is not currently aware of what language it is being used for. +* Limits in-process sharing across languages with shared implementations (e.g. + Python upb, PHP upb) in the case of conflicting behaviors. + * Additional checks may be needed. + +### Alternative 3: Migrate to bytes + +Since this whole discussion revolves around the utf8 validation feature, one +option would be to just remove it from edition zero. Instead of adding a new +toggle for UTF8 behavior, we could simply migrate everyone who doesn't enforce +utf8 today to `bytes`. This would likely need another new *codegen* feature for +generating byte getters/setters as strings, but that wouldn't have any of the +ambiguity we're seeing today. + +Unfortunately, this doesn't seem feasible because of all the different behaviors +laid out in "Editions Zero Feature: utf8_validation." UTF8 validation isn't +really a binary on/off decision, and it can vary widely between languages. There +are many cases where UTF8 is validated in **some** languages but not others, and +there's also the C++ "hint" behavior that logs errors but allows invalid UTF8. + +**Note:** This could still be partially done in a follow-up LSC by targeting +specific combinations of the new feature that disable validation in all relevant +languages. + +#### Pros + +* Punts on the issue, we wouldn't need any upb features and C++ features would + all be code-gen only +* Simplifies the situation, avoids adding a very complicated feature in + edition zero + +#### Cons + +* Not really possible given the current complexity +* There are O(10M) proto2 string fields that would be blindly changed to bytes + +### Alternative 4: Nested Features + +Another option is to allow for shared feature set messages. For example, upb +would define a feature message, but *not* make it an extension of the global +`FeatureSet`. Instead, languages with upb implementations would have a field of +this type to allow for finer-grained controls. C++ would both extend the global +`FeatureSet` and also be allowed as a field in other languages. + +For example, python utf8 validation could be specified as: + +We could have checks during feature validation that enforce that impossible +combinations aren't specified. For example, with our current implementation +`features.(pb.python).cpp` should always be identical to `features.(pb.cpp)`, +since we don't have any mechanism for distinguishing them. + +#### Pros + +* Much more explicit than options 1 and 2 + +#### Cons + +* Maybe too explicit? Proto owners would be forced to duplicate a lot of + features From 7daa16947b01b9c82d90e7a33294a9ed0dcb4668 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 2 Nov 2023 07:31:50 -0700 Subject: [PATCH 92/95] Emit a reason for why a field was unsupported. PiperOrigin-RevId: 578846947 --- .../rust/accessors/accessor_generator.h | 6 ++++++ .../compiler/rust/accessors/accessors.cc | 17 ++++++++++++----- .../rust/accessors/unsupported_field.cc | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/google/protobuf/compiler/rust/accessors/accessor_generator.h b/src/google/protobuf/compiler/rust/accessors/accessor_generator.h index 3bf1dca06d..8b26d19dc8 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessor_generator.h +++ b/src/google/protobuf/compiler/rust/accessors/accessor_generator.h @@ -9,6 +9,8 @@ #define GOOGLE_PROTOBUF_COMPILER_RUST_ACCESSORS_ACCESSOR_GENERATOR_H__ #include +#include +#include #include "absl/log/absl_check.h" #include "google/protobuf/compiler/rust/context.h" @@ -96,8 +98,12 @@ class RepeatedScalar final : public AccessorGenerator { class UnsupportedField final : public AccessorGenerator { public: + explicit UnsupportedField(std::string reason) : reason_(std::move(reason)) {} ~UnsupportedField() override = default; void InMsgImpl(Context field) const override; + + private: + std::string reason_; }; } // namespace rust diff --git a/src/google/protobuf/compiler/rust/accessors/accessors.cc b/src/google/protobuf/compiler/rust/accessors/accessors.cc index 807eb478b3..e963e9e075 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessors.cc +++ b/src/google/protobuf/compiler/rust/accessors/accessors.cc @@ -9,6 +9,7 @@ #include +#include "absl/log/absl_log.h" #include "google/protobuf/compiler/rust/accessors/accessor_generator.h" #include "google/protobuf/compiler/rust/context.h" #include "google/protobuf/descriptor.h" @@ -26,7 +27,8 @@ std::unique_ptr AccessorGeneratorFor( // TODO: We do not support [ctype=FOO] (used to set the field // type in C++ to cord or string_piece) in V0.6 API. if (desc.options().has_ctype()) { - return std::make_unique(); + return std::make_unique( + "fields with ctype not supported"); } switch (desc.type()) { @@ -50,18 +52,23 @@ std::unique_ptr AccessorGeneratorFor( case FieldDescriptor::TYPE_BYTES: case FieldDescriptor::TYPE_STRING: if (desc.is_repeated()) { - return std::make_unique(); + return std::make_unique("repeated str not supported"); } return std::make_unique(); case FieldDescriptor::TYPE_MESSAGE: if (desc.is_repeated()) { - return std::make_unique(); + return std::make_unique("repeated msg not supported"); } return std::make_unique(); - default: - return std::make_unique(); + case FieldDescriptor::TYPE_ENUM: + return std::make_unique("enum not supported"); + + case FieldDescriptor::TYPE_GROUP: + return std::make_unique("group not supported"); } + + ABSL_LOG(FATAL) << "Unexpected field type: " << desc.type(); } } // namespace diff --git a/src/google/protobuf/compiler/rust/accessors/unsupported_field.cc b/src/google/protobuf/compiler/rust/accessors/unsupported_field.cc index ad0a98901c..e6bce02171 100644 --- a/src/google/protobuf/compiler/rust/accessors/unsupported_field.cc +++ b/src/google/protobuf/compiler/rust/accessors/unsupported_field.cc @@ -16,8 +16,8 @@ namespace compiler { namespace rust { void UnsupportedField::InMsgImpl(Context field) const { - field.Emit(R"rs( - // Unsupported! :( + field.Emit({{"reason", reason_}}, R"rs( + // Unsupported! :( Reason: $reason$ )rs"); field.printer().PrintRaw("\n"); } From 9a610f02f8a50395852033a5f1f28084cfa29841 Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Thu, 2 Nov 2023 09:08:56 -0700 Subject: [PATCH 93/95] upb: delete unused function in the C code generator PiperOrigin-RevId: 578873644 --- upb_generator/protoc-gen-upb.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/upb_generator/protoc-gen-upb.cc b/upb_generator/protoc-gen-upb.cc index 7678f99a62..dac5bd6383 100644 --- a/upb_generator/protoc-gen-upb.cc +++ b/upb_generator/protoc-gen-upb.cc @@ -835,15 +835,6 @@ void GenerateMessageInHeader(upb::MessageDefPtr message, output("\n"); } -void ForwardDeclareMiniTableInit(upb::MessageDefPtr message, - const Options& options, Output& output) { - if (options.bootstrap) { - output("extern const upb_MiniTable* $0();\n", MessageInitName(message)); - } else { - output("extern const upb_MiniTable $0;\n", MessageInitName(message)); - } -} - std::vector SortedForwardMessages( const std::vector& this_file_messages, const std::vector& this_file_exts) { From f78f9c51fa2470070e5d4b49649800971c789224 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 2 Nov 2023 09:13:31 -0700 Subject: [PATCH 94/95] Workaround false positive warning in MSVC. Fixes https://github.com/protocolbuffers/protobuf/issues/14602 PiperOrigin-RevId: 578875053 --- src/google/protobuf/map_field.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 8aa9e45fe3..8388f8a2e5 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -678,7 +678,7 @@ class MapField final : public TypeDefinedMapFieldBase { template -constexpr MapFieldBase::VTable +PROTOBUF_CONSTINIT const MapFieldBase::VTable MapField::kVTable = MapField::template MakeVTable(); From 76305620a173d1428c5a00c7c50826c8c6dbc389 Mon Sep 17 00:00:00 2001 From: Deanna Garcia Date: Thu, 2 Nov 2023 10:40:33 -0700 Subject: [PATCH 95/95] Add a job to the janitor GHA to annotate any issues/PRs that have been inactive for the past 90 days with the `inactive` label (which has been added to github). The job will then close an issue if it has been marked inactive for 14 days. Most of this is taken from https://github.com/carbon-language/carbon-lang/blob/trunk/.github/workflows/stale.yaml with a few adjustments, most importantly allowing the bot to auto-close issues. PiperOrigin-RevId: 578906074 --- .github/workflows/janitor.yml | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/.github/workflows/janitor.yml b/.github/workflows/janitor.yml index e6dcc06979..992d4b7113 100644 --- a/.github/workflows/janitor.yml +++ b/.github/workflows/janitor.yml @@ -28,3 +28,47 @@ jobs: echo "Closing #$pr..." gh pr close --comment "Auto-closing Copybara pull request" --delete-branch "$pr" done + + stale-others: + name: Close stale non-copybara PRs and issues + runs-on: ubuntu-latest + steps: + - uses: actions/stale@b69b346013879cedbf50c69f572cd85439a41936 + with: + stale-issue-message: > + We triage inactive PRs and issues in order to make it easier to find + active work. If this issue should remain active or becomes active + again, please add a comment. + + + This issue is labeled `inactive` because the last activity was over + 90 days ago. + close-pr-message: > + We triage inactive PRs and issues in order to make it easier to find + active work. If this issue should remain active or becomes active + again, please reopen it. + + + This issue was closed and archived because there has been no new + activity in the 14 days since the `inactive` label was added. + stale-pr-message: > + We triage inactive PRs and issues in order to make it easier to find + active work. If this PR should remain active, please add a comment. + + + This PR is labeled `inactive` because the last activity was over 90 + days ago. This PR will be closed and archived after 14 additional + days without activity. + close-pr-message: > + We triage inactive PRs and issues in order to make it easier to find + active work. If this PR should remain active or becomes active + again, please reopen it. + + + This PR was closed and archived because there has been no new + activity in the 14 days since the `inactive` label was added. + stale-issue-label: 'inactive' + stale-pr-label: 'inactive' + days-before-stale: 90 + days-before-close: 14 + operations-per-run: 100