diff --git a/editions/golden/compare_cpp_codegen_failure.txt b/editions/golden/compare_cpp_codegen_failure.txt index ff5fbdaffc3b..ab0bad33f176 100644 --- a/editions/golden/compare_cpp_codegen_failure.txt +++ b/editions/golden/compare_cpp_codegen_failure.txt @@ -30,9 +30,9 @@ { - // optional int32 int32_field = 1; + // int32 int32_field = 1; - cached_has_bits = - this_._impl_._has_bits_[0]; + cached_has_bits = this_._impl_._has_bits_[0]; if (cached_has_bits & 0x00000001u) { + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( [ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.cc [ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h @@ @@ diff --git a/editions/golden/compare_cpp_codegen_failure.xml b/editions/golden/compare_cpp_codegen_failure.xml index a432b5a01135..f992058c2cb8 100644 --- a/editions/golden/compare_cpp_codegen_failure.xml +++ b/editions/golden/compare_cpp_codegen_failure.xml @@ -2,7 +2,7 @@ - + diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 9a3a3ba80a98..8384a5c70e27 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -1213,6 +1213,55 @@ class AccessorVerifier { } // namespace +void MessageGenerator::EmitUpdateByteSizeForField( + const FieldDescriptor* field, io::Printer* p, + int& cached_has_word_index) const { + p->Emit( + {{"comment", [&] { PrintFieldComment(Formatter{p}, field, options_); }}, + {"update_byte_size_for_field", + [&] { field_generators_.get(field).GenerateByteSize(p); }}, + {"update_cached_has_bits", + [&] { + if (!HasHasbit(field) || field->options().weak()) return; + + int has_bit_index = has_bit_indices_[field->index()]; + + if (cached_has_word_index == (has_bit_index / 32)) return; + + cached_has_word_index = (has_bit_index / 32); + p->Emit({{"index", cached_has_word_index}}, + R"cc( + cached_has_bits = this_.$has_bits$[$index$]; + )cc"); + }}, + {"check_if_field_present", + [&] { + if (!HasHasbit(field)) { + MayEmitIfNonDefaultCheck(p, "this_.", field); + return; + } + + if (field->options().weak()) { + p->Emit("if (has_$name$())"); + return; + } + + int has_bit_index = has_bit_indices_[field->index()]; + p->Emit( + {{"mask", absl::StrFormat("0x%08xu", + uint32_t{1} << (has_bit_index % 32))}}, + "if (cached_has_bits & $mask$)"); + }}}, + R"cc( + $comment$; + $update_cached_has_bits$; + $check_if_field_present$ { + //~ Force newline. + $update_byte_size_for_field$; + } + )cc"); +} + void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* p) { p->Emit("// $classname$\n\n"); @@ -4748,62 +4797,8 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) { // Go back and emit checks for each of the fields we // processed. for (const auto* field : fields) { - p->Emit( - {{"comment", - [&] { - PrintFieldComment(Formatter{p}, field, - options_); - }}, - {"update_byte_size_for_field", - [&] { - field_generators_.get(field).GenerateByteSize( - p); - }}, - {"update_cached_has_bits", - [&] { - if (!HasHasbit(field) || - field->options().weak()) - return; - int has_bit_index = - has_bit_indices_[field->index()]; - if (cached_has_word_index == - (has_bit_index / 32)) - return; - cached_has_word_index = (has_bit_index / 32); - p->Emit({{"index", cached_has_word_index}}, - R"cc( - cached_has_bits = - this_.$has_bits$[$index$]; - )cc"); - }}, - {"check_if_field_present", - [&] { - if (!HasHasbit(field)) { - MayEmitIfNonDefaultCheck(p, "this_.", field); - return; - } - - if (field->options().weak()) { - p->Emit("if (has_$name$())"); - return; - } - - int has_bit_index = - has_bit_indices_[field->index()]; - p->Emit( - {{"mask", absl::StrFormat( - "0x%08xu", - 1u << (has_bit_index % 32))}}, - "if (cached_has_bits & $mask$)"); - }}}, - R"cc( - $comment$; - $update_cached_has_bits$; - $check_if_field_present$ { - //~ Force newline. - $update_byte_size_for_field$; - } - )cc"); + EmitUpdateByteSizeForField(field, p, + cached_has_word_index); } }}, {"may_update_cached_has_word_index", diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index 4e5afb10843c..11db273a0844 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -186,6 +186,10 @@ class MessageGenerator { int HasWordIndex(const FieldDescriptor* field) const; std::vector RequiredFieldsBitMask() const; + // Helper function to reduce nesting levels of deep Emit calls. + void EmitUpdateByteSizeForField(const FieldDescriptor* field, io::Printer* p, + int& cached_has_word_index) const; + const Descriptor* descriptor_; int index_in_file_messages_; Options options_; diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 4b3f6ce1b5ce..63caf0878521 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -10530,8 +10530,7 @@ PROTOBUF_NOINLINE void OneofOptions::Clear() { } { // optional .google.protobuf.FeatureSet features = 1; - cached_has_bits = - this_._impl_._has_bits_[0]; + cached_has_bits = this_._impl_._has_bits_[0]; if (cached_has_bits & 0x00000001u) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSize(*this_._impl_.features_);