Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions editions/golden/compare_cpp_codegen_failure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<testsuites tests="1" name="AllTests">
<testsuite name="EditionsCodegenTests">
<testcase name="third_party/protobuf/editions/golden/simple_proto3.pb.cc" status="run" result="completed" classname="DiffTest">
<failure message="Value of: third_party/protobuf/editions/golden/simple_proto3.pb.cc&#x0A;Expected: &#x0A;// Generated by the protocol buffer compiler. DO NOT EDIT!&#x0A;// NO CHECKED-IN PROTOBUF GENCODE&#x0A;// source: third_party/protobuf/editions/golden/simple_proto3.proto&#x0A;&#x0A;#include &quot;third_party/protobuf/editions/golden/simple_proto3.pb.h&quot;&#x0A;&#x0A;#include &lt;algorithm&gt;&#x0A;#include &lt;type_traits&gt;&#x0A;#include &quot;third_party/protobuf/io/coded_stream.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_tctable_impl.h&quot;&#x0A;#include &quot;third_party/protobuf/internal_visibility.h&quot;&#x0A;#include &quot;third_party/protobuf/extension_set.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_util.h&quot;&#x0A;#include &quot;third_party/protobuf/wire_format_lite.h&quot;&#x0A;#include &quot;third_party/protobuf/io/zero_copy_stream_impl_lite.h&quot;&#x0A;#include &quot;third_party/protobuf/v2/generated_message_table_impl.h&quot;&#x0A;// @@protoc_insertion_point(includes)&#x0A;&#x0A;// Must be included last.&#x0A;, with the difference:&#x0A;@@ @@&#x0A; ::_pbi::TcParser::GetTable&lt;::protobuf_editions_test::golden::SimpleProto3&gt;(), // to_prefetch&#x0A; #endif // PROTOBUF_PREFETCH_PARSE_TABLE&#x0A; }, {{&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; {::_pbi::TcParser::FastV32S1,&#x0A; {8, 0, 0,&#x0A; PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_)}},&#x0A; }}, {{&#x0A; 65535, 65535&#x0A; }}, {{&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; {PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)},&#x0A; }},&#x0A; // no aux_entries&#x0A;@@ @@&#x0A; (void)cached_has_bits;&#x0A; &#x0A; cached_has_bits = this_._impl_._has_bits_[0];&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; if (CheckHasBit(cached_has_bits, 0x00000001U)) {&#x0A; target =&#x0A; ::proto2::internal::WireFormatLite::WriteInt32ToArrayWithField&lt;1&gt;(&#x0A;@@ @@&#x0A; (void)cached_has_bits;&#x0A; &#x0A; {&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; cached_has_bits = this_._impl_._has_bits_[0];&#x0A; if (CheckHasBit(cached_has_bits, 0x00000001U)) {&#x0A; total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(" type=""></failure>
<failure message="Value of: third_party/protobuf/editions/golden/simple_proto3.pb.cc&#x0A;Expected: &#x0A;// Generated by the protocol buffer compiler. DO NOT EDIT!&#x0A;// NO CHECKED-IN PROTOBUF GENCODE&#x0A;// source: third_party/protobuf/editions/golden/simple_proto3.proto&#x0A;&#x0A;#include &quot;third_party/protobuf/editions/golden/simple_proto3.pb.h&quot;&#x0A;&#x0A;#include &lt;algorithm&gt;&#x0A;#include &lt;type_traits&gt;&#x0A;#include &quot;third_party/protobuf/io/coded_stream.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_tctable_impl.h&quot;&#x0A;#include &quot;third_party/protobuf/internal_visibility.h&quot;&#x0A;#include &quot;third_party/protobuf/extension_set.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_util.h&quot;&#x0A;#include &quot;third_party/protobuf/wire_format_lite.h&quot;&#x0A;#include &quot;third_party/protobuf/io/zero_copy_stream_impl_lite.h&quot;&#x0A;// @@protoc_insertion_point(includes)&#x0A;&#x0A;// Must be included last.&#x0A;, with the difference:&#x0A;@@ @@&#x0A; ::_pbi::TcParser::GetTable&lt;::protobuf_editions_test::golden::SimpleProto3&gt;(), // to_prefetch&#x0A; #endif // PROTOBUF_PREFETCH_PARSE_TABLE&#x0A; }, {{&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; {::_pbi::TcParser::FastV32S1,&#x0A; {8, 0, 0,&#x0A; PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_)}},&#x0A; }}, {{&#x0A; 65535, 65535&#x0A; }}, {{&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; {PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)},&#x0A; }},&#x0A; // no aux_entries&#x0A;@@ @@&#x0A; (void)cached_has_bits;&#x0A; &#x0A; cached_has_bits = this_._impl_._has_bits_[0];&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; if (CheckHasBit(cached_has_bits, 0x00000001U)) {&#x0A; target =&#x0A; ::proto2::internal::WireFormatLite::WriteInt32ToArrayWithField&lt;1&gt;(&#x0A;@@ @@&#x0A; (void)cached_has_bits;&#x0A; &#x0A; {&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; cached_has_bits = this_._impl_._has_bits_[0];&#x0A; if (CheckHasBit(cached_has_bits, 0x00000001U)) {&#x0A; total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(" type=""></failure>
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.pb.h" status="run" result="completed" classname="DiffTest">
<failure message="Value of: third_party/protobuf/editions/golden/simple_proto3.pb.h&#x0A;Expected: &#x0A;// Generated by the protocol buffer compiler. DO NOT EDIT!&#x0A;// NO CHECKED-IN PROTOBUF GENCODE&#x0A;// source: third_party/protobuf/editions/golden/simple_proto3.proto&#x0A;&#x0A;#ifndef third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;#define third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;&#x0A;#include &lt;limits&gt;&#x0A;#include &lt;string&gt;&#x0A;#include &lt;type_traits&gt;&#x0A;#include &lt;utility&gt;&#x0A;&#x0A;// clang-format off&#x0A;#include &quot;third_party/protobuf/runtime_version.h&quot;&#x0A;#include &quot;third_party/protobuf/io/coded_stream.h&quot;&#x0A;#include &quot;third_party/protobuf/arena.h&quot;&#x0A;#include &quot;third_party/protobuf/arenastring.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_tctable_decl.h&quot;&#x0A;#include &quot;third_party/protobuf/v2/generated_message_table.h&quot;&#x0A;#include &quot;third_party/protobuf/v2/generated_message_table_impl.h&quot;&#x0A;#include &quot;third_party/protobuf/v2/batch_builder.h&quot;&#x0A;#include &quot;third_party/protobuf/v2/batch_wire_format.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_util.h&quot;&#x0A;#include &quot;third_party/protobuf/metadata_lite.h&quot;&#x0A;#include &quot;third_party/protobuf/message_lite.h&quot;&#x0A;// @@protoc_insertion_point(includes)&#x0A;&#x0A;// Must be included last.&#x0A;// clang-format on&#x0A;&#x0A;#endif // third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;, with the difference:&#x0A;@@ @@&#x0A; enum : int {&#x0A; kInt32FieldFieldNumber = 1,&#x0A; };&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; [[nodiscard]] bool has_int32_field()&#x0A; const;&#x0A; void clear_int32_field() ;&#x0A;@@ @@&#x0A; &#x0A; // SimpleProto3&#x0A; &#x0A;-// optional int32 int32_field = 1;&#x0A;+// int32 int32_field = 1;&#x0A; inline bool SimpleProto3::has_int32_field() const {&#x0A; bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000001U);&#x0A; return value;" type=""></failure>
<failure message="Value of: third_party/protobuf/editions/golden/simple_proto3.pb.h&#x0A;Expected: &#x0A;// Generated by the protocol buffer compiler. DO NOT EDIT!&#x0A;// NO CHECKED-IN PROTOBUF GENCODE&#x0A;// source: third_party/protobuf/editions/golden/simple_proto3.proto&#x0A;&#x0A;#ifndef third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;#define third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;&#x0A;#include &lt;limits&gt;&#x0A;#include &lt;string&gt;&#x0A;#include &lt;type_traits&gt;&#x0A;#include &lt;utility&gt;&#x0A;&#x0A;// clang-format off&#x0A;#include &quot;third_party/protobuf/runtime_version.h&quot;&#x0A;#include &quot;third_party/protobuf/io/coded_stream.h&quot;&#x0A;#include &quot;third_party/protobuf/arena.h&quot;&#x0A;#include &quot;third_party/protobuf/arenastring.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_tctable_decl.h&quot;&#x0A;#include &quot;third_party/protobuf/v2/batch_builder.h&quot;&#x0A;#include &quot;third_party/protobuf/v2/batch_wire_format.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_util.h&quot;&#x0A;#include &quot;third_party/protobuf/metadata_lite.h&quot;&#x0A;#include &quot;third_party/protobuf/message_lite.h&quot;&#x0A;// @@protoc_insertion_point(includes)&#x0A;&#x0A;// Must be included last.&#x0A;// clang-format on&#x0A;&#x0A;#endif // third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;, with the difference:&#x0A;@@ @@&#x0A; enum : int {&#x0A; kInt32FieldFieldNumber = 1,&#x0A; };&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1;&#x0A; [[nodiscard]] bool has_int32_field()&#x0A; const;&#x0A; void clear_int32_field() ;&#x0A;@@ @@&#x0A; &#x0A; // SimpleProto3&#x0A; &#x0A;-// optional int32 int32_field = 1;&#x0A;+// int32 int32_field = 1;&#x0A; inline bool SimpleProto3::has_int32_field() const {&#x0A; bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000001U);&#x0A; return value;" type=""></failure>
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h" status="run" result="completed" classname="DiffTest">
</testcase>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ void SingularEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const {
}
}


class RepeatedEnum : public FieldGeneratorBase {
public:
RepeatedEnum(const FieldDescriptor* field, const Options& opts,
Expand Down Expand Up @@ -584,6 +585,7 @@ void RepeatedEnum::GenerateByteSize(io::Printer* p) const {
total_size += data_size + tag_size;
)cc");
}

} // namespace

std::unique_ptr<FieldGeneratorBase> MakeSinguarEnumGenerator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ class RepeatedPrimitive final : public FieldGeneratorBase {
void GenerateByteSize(io::Printer* p) const override;

private:
template <bool kUseCompactFieldNumbers>
void GenerateByteSizeV2Impl(io::Printer* p, bool try_batch) const;

bool HasCachedSize() const {
bool is_packed_varint =
field_->is_packed() && !FixedSize(field_->type()).has_value();
Expand Down Expand Up @@ -668,6 +671,7 @@ void RepeatedPrimitive::GenerateByteSize(io::Printer* p) const {
total_size += tag_size + data_size;
)cc");
}

} // namespace

std::unique_ptr<FieldGeneratorBase> MakeSinguarPrimitiveGenerator(
Expand Down
14 changes: 14 additions & 0 deletions src/google/protobuf/compiler/cpp/helpers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint8_t>::max()) {
return false;
}
}
for (int i = 0; i < desc->extension_count(); ++i) {
if (desc->extension(i)->number() >= std::numeric_limits<uint8_t>::max()) {
return false;
}
}
return true;
}

bool IsLazy(const FieldDescriptor* field, const Options& options,
MessageSCCAnalyzer* scc_analyzer) {
return IsLazilyVerifiedLazy(field, options) ||
Expand Down
4 changes: 4 additions & 0 deletions src/google/protobuf/compiler/cpp/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
6 changes: 4 additions & 2 deletions src/google/protobuf/compiler/cpp/message.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,8 @@ class AccessorVerifier {

template <bool kIsV2>
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<void()> emit_body = [&] {
const auto& gen = field_generators_.get(field);
if constexpr (!kIsV2) {
Expand Down Expand Up @@ -1447,7 +1448,8 @@ void MessageGenerator::EmitUpdateByteSizeForField(
{"check_and_update_byte_size_for_field",
[&]() {
EmitCheckAndUpdateByteSizeForField</*kIsV2=*/false>(
field, p, /*try_batch=*/false);
field, p, /*try_batch=*/false,
/*use_compact_field_numbers=*/false);
}}},
R"cc(
$comment$;
Expand Down
3 changes: 2 additions & 1 deletion src/google/protobuf/compiler/cpp/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ class MessageGenerator {
// Helper functions to reduce nesting levels of deep Emit calls.
template <bool kIsV2 = false>
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;

Expand Down
Loading