diff --git a/editions/golden/compare_cpp_codegen_failure.xml b/editions/golden/compare_cpp_codegen_failure.xml index 80b43841e1bbd..ddf32a20e2da6 100644 --- a/editions/golden/compare_cpp_codegen_failure.xml +++ b/editions/golden/compare_cpp_codegen_failure.xml @@ -2,10 +2,10 @@ - + - + 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 5333e0125c183..bb412071890e5 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc @@ -216,6 +216,7 @@ void SingularEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const { } } + class RepeatedEnum : public FieldGeneratorBase { public: RepeatedEnum(const FieldDescriptor* field, const Options& opts, @@ -584,6 +585,7 @@ void RepeatedEnum::GenerateByteSize(io::Printer* p) const { total_size += data_size + tag_size; )cc"); } + } // namespace std::unique_ptr MakeSinguarEnumGenerator( 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 1eb2f3e96abff..ead14ae9d0931 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc @@ -423,6 +423,9 @@ class RepeatedPrimitive final : public FieldGeneratorBase { void GenerateByteSize(io::Printer* p) const override; private: + template + void GenerateByteSizeV2Impl(io::Printer* p, bool try_batch) const; + bool HasCachedSize() const { bool is_packed_varint = field_->is_packed() && !FixedSize(field_->type()).has_value(); @@ -668,6 +671,7 @@ void RepeatedPrimitive::GenerateByteSize(io::Printer* p) const { total_size += tag_size + data_size; )cc"); } + } // namespace std::unique_ptr MakeSinguarPrimitiveGenerator( diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc index c0499d85cc868..cad38192a3035 100644 --- a/src/google/protobuf/compiler/cpp/helpers.cc +++ b/src/google/protobuf/compiler/cpp/helpers.cc @@ -243,6 +243,20 @@ bool HasV2Table(const Descriptor* descriptor, const Options& options) { } // namespace +bool EligibleForCompactV2Fields(const Descriptor* desc) { + for (int i = 0; i < desc->field_count(); ++i) { + if (desc->field(i)->number() >= std::numeric_limits::max()) { + return false; + } + } + for (int i = 0; i < desc->extension_count(); ++i) { + if (desc->extension(i)->number() >= std::numeric_limits::max()) { + return false; + } + } + return true; +} + bool IsLazy(const FieldDescriptor* field, const Options& options, MessageSCCAnalyzer* scc_analyzer) { return IsLazilyVerifiedLazy(field, options) || diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index 2f2d3e40e1061..db7461f5e0173 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -46,6 +46,10 @@ namespace compiler { namespace cpp { enum class ArenaDtorNeeds { kNone = 0, kOnDemand = 1, kRequired = 2 }; +// Returns true if the message is eligible for compact v2 fields, i.e. all field +// numbers can be stored in a uint8_t. +bool EligibleForCompactV2Fields(const Descriptor* desc); + inline absl::string_view ProtobufNamespace(const Options& opts) { // This won't be transformed by copybara, since copybara looks for google::protobuf::. constexpr absl::string_view kGoogle3Ns = "proto2"; diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index c386df3bba2a9..76bc2018d4430 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -1377,7 +1377,8 @@ class AccessorVerifier { template void MessageGenerator::EmitCheckAndUpdateByteSizeForField( - const FieldDescriptor* field, io::Printer* p, bool try_batch) const { + const FieldDescriptor* field, io::Printer* p, bool try_batch, + bool use_compact_field_numbers) const { absl::AnyInvocable emit_body = [&] { const auto& gen = field_generators_.get(field); if constexpr (!kIsV2) { @@ -1447,7 +1448,8 @@ void MessageGenerator::EmitUpdateByteSizeForField( {"check_and_update_byte_size_for_field", [&]() { EmitCheckAndUpdateByteSizeForField( - field, p, /*try_batch=*/false); + field, p, /*try_batch=*/false, + /*use_compact_field_numbers=*/false); }}}, R"cc( $comment$; diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index 91cf215c6212a..6e4e5bd940019 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -214,7 +214,8 @@ class MessageGenerator { // Helper functions to reduce nesting levels of deep Emit calls. template void EmitCheckAndUpdateByteSizeForField(const FieldDescriptor* field, - io::Printer* p, bool try_batch) const; + io::Printer* p, bool try_batch, + bool compact_field_numbers) const; void EmitUpdateByteSizeForField(const FieldDescriptor* field, io::Printer* p, int& cached_has_word_index) const;