Skip to content
Draft
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
66 changes: 34 additions & 32 deletions src/google/protobuf/compiler/cpp/field.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/span.h"
#include "google/protobuf/compiler/cpp/field_generators/generators.h"
#include "google/protobuf/compiler/cpp/field_layout.h"
Expand All @@ -44,8 +43,9 @@ namespace cpp {
using ::google::protobuf::internal::WireFormat;
using Sub = ::google::protobuf::io::Printer::Sub;

std::vector<Sub> FieldVars(const FieldDescriptor* field, const Options& opts) {
bool split = ShouldSplit(field, opts);
std::vector<Sub> FieldVars(const FieldDescriptor* field, const Options& opts,
const FieldLayout& field_layout) {
bool split = field_layout.IsSplit(field);
std::vector<Sub> vars = {
// This will eventually be renamed to "field", once the existing "field"
// variable is replaced with "field_" everywhere.
Expand Down Expand Up @@ -110,10 +110,11 @@ std::vector<Sub> FieldVars(const FieldDescriptor* field, const Options& opts) {
}

FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* field,
const Options& options)
: field_(field), options_(options) {
const Options& options,
const FieldLayout& field_layout)
: field_(field), options_(options), field_layout_(field_layout) {
bool is_repeated_or_map = field->is_repeated();
should_split_ = ShouldSplit(field, options);
should_split_ = field_layout_.IsSplit(field);
is_oneof_ = field->real_containing_oneof() != nullptr;
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_ENUM:
Expand Down Expand Up @@ -165,7 +166,7 @@ void FieldGeneratorBase::GenerateMemberConstexprConstructor(
void FieldGeneratorBase::GenerateMemberConstructor(io::Printer* p) const {
ABSL_CHECK(!field_->is_extension());
if (field_->is_repeated() || field_->is_map()) {
if (ShouldSplit(field_, options_)) {
if (field_layout_.IsSplit(field_)) {
ABSL_CHECK(!field_->is_map());
p->Emit("$name$_{}"); // RawPtr<Repeated>
} else {
Expand Down Expand Up @@ -202,7 +203,7 @@ void FieldGeneratorBase::GenerateOneofCopyConstruct(io::Printer* p) const {
}

void FieldGeneratorBase::GenerateAggregateInitializer(io::Printer* p) const {
if (ShouldSplit(field_, options_)) {
if (field_layout_.IsSplit(field_)) {
p->Emit(R"cc(
decltype(Impl_::Split::$name$_){arena},
)cc");
Expand Down Expand Up @@ -255,68 +256,70 @@ Sub FieldGeneratorBase::InternalMetadataOffsetSub(io::Printer* p) {
}

namespace {
std::unique_ptr<FieldGeneratorBase> MakeGenerator(const FieldDescriptor* field,
const Options& options) {
std::unique_ptr<FieldGeneratorBase> MakeGenerator(
const FieldDescriptor* field, const Options& options,
const FieldLayout& field_layout) {

if (field->is_map()) {
ABSL_CHECK(
!(field->options().lazy() || field->options().unverified_lazy()));
return MakeMapGenerator(field, options);
return MakeMapGenerator(field, options, field_layout);
}
if (field->is_repeated()) {
ABSL_CHECK(!field->options().unverified_lazy());

switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
return MakeRepeatedMessageGenerator(field, options);
return MakeRepeatedMessageGenerator(field, options, field_layout);
case FieldDescriptor::CPPTYPE_STRING: {
if (field->cpp_string_type() == FieldDescriptor::CppStringType::kView) {
return MakeRepeatedStringViewGenerator(field, options);
return MakeRepeatedStringViewGenerator(field, options, field_layout);
} else {
return MakeRepeatedStringGenerator(field, options);
return MakeRepeatedStringGenerator(field, options, field_layout);
}
}
case FieldDescriptor::CPPTYPE_ENUM:
return MakeRepeatedEnumGenerator(field, options);
return MakeRepeatedEnumGenerator(field, options, field_layout);
default:
return MakeRepeatedPrimitiveGenerator(field, options);
return MakeRepeatedPrimitiveGenerator(field, options, field_layout);
}
}

if (field->real_containing_oneof() &&
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
return MakeOneofMessageGenerator(field, options);
return MakeOneofMessageGenerator(field, options, field_layout);
}

switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
return MakeSinguarMessageGenerator(field, options);
return MakeSinguarMessageGenerator(field, options, field_layout);
case FieldDescriptor::CPPTYPE_ENUM:
return MakeSinguarEnumGenerator(field, options);
return MakeSinguarEnumGenerator(field, options, field_layout);
case FieldDescriptor::CPPTYPE_STRING: {
switch (field->cpp_string_type()) {
case FieldDescriptor::CppStringType::kView:
return MakeSingularStringViewGenerator(field, options);
return MakeSingularStringViewGenerator(field, options, field_layout);
case FieldDescriptor::CppStringType::kCord:
if (field->type() == FieldDescriptor::TYPE_BYTES) {
if (field->real_containing_oneof()) {
return MakeOneofCordGenerator(field, options);
return MakeOneofCordGenerator(field, options, field_layout);
} else {
return MakeSingularCordGenerator(field, options);
return MakeSingularCordGenerator(field, options, field_layout);
}
}
ABSL_FALLTHROUGH_INTENDED;
default:
return MakeSinguarStringGenerator(field, options);
return MakeSinguarStringGenerator(field, options, field_layout);
}
}
default:
return MakeSinguarPrimitiveGenerator(field, options);
return MakeSinguarPrimitiveGenerator(field, options, field_layout);
}
}

void HasBitVars(const FieldDescriptor* field, const Options& opts,
absl::optional<uint32_t> idx, std::vector<Sub>& vars) {
const FieldLayout& field_layout, std::vector<Sub>& vars) {
const auto idx = field_layout.GetHasBitIndex(field);
if (!idx.has_value()) {
vars.emplace_back(Sub("set_hasbit", "").WithSuffix(";"));
vars.emplace_back(Sub("clear_hasbit", "").WithSuffix(";"));
Expand Down Expand Up @@ -350,21 +353,20 @@ void HasBitVars(const FieldDescriptor* field, const Options& opts,

FieldGenerator::FieldGenerator(const FieldDescriptor* field,
const Options& options,
absl::optional<uint32_t> hasbit_index)
: impl_(MakeGenerator(field, options)),
field_vars_(FieldVars(field, options)),
tracker_vars_(MakeTrackerCalls(field, options)),
const FieldLayout& field_layout)
: impl_(MakeGenerator(field, options, field_layout)),
field_vars_(FieldVars(field, options, field_layout)),
tracker_vars_(MakeTrackerCalls(field, options, field_layout)),
per_generator_vars_(impl_->MakeVars()) {
HasBitVars(field, options, hasbit_index, field_vars_);
HasBitVars(field, options, field_layout, field_vars_);
}

void FieldGeneratorTable::Build(const Options& options,
const FieldLayout& field_layout) {
// Construct all the FieldGenerators.
fields_.reserve(static_cast<size_t>(descriptor_->field_count()));
for (const auto* field : internal::FieldRange(descriptor_)) {
fields_.push_back(
FieldGenerator(field, options, field_layout.GetHasBitIndex(field)));
fields_.push_back(FieldGenerator(field, options, field_layout));
}
}

Expand Down
14 changes: 9 additions & 5 deletions src/google/protobuf/compiler/cpp/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@
#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__

#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/log/absl_check.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/span.h"
#include "google/protobuf/compiler/cpp/field_layout.h"
#include "google/protobuf/compiler/cpp/helpers.h"
Expand Down Expand Up @@ -52,7 +50,8 @@ class FieldGeneratorBase {
// variable instead of calling GetArena()'
enum class GeneratorFunction { kMergeFrom };

FieldGeneratorBase(const FieldDescriptor* field, const Options& options);
FieldGeneratorBase(const FieldDescriptor* field, const Options& options,
const FieldLayout& field_layout);

FieldGeneratorBase(const FieldGeneratorBase&) = delete;
FieldGeneratorBase& operator=(const FieldGeneratorBase&) = delete;
Expand Down Expand Up @@ -198,6 +197,8 @@ class FieldGeneratorBase {
}

protected:
const FieldLayout& field_layout() const { return field_layout_; }

const FieldDescriptor* field_;
const Options& options_;
absl::flat_hash_map<absl::string_view, std::string> variables_;
Expand All @@ -207,6 +208,8 @@ class FieldGeneratorBase {
static io::Printer::Sub InternalMetadataOffsetSub(io::Printer* p);

private:
const FieldLayout& field_layout_;

bool should_split_ = false;
bool is_trivial_ = false;
bool has_trivial_value_ = false;
Expand Down Expand Up @@ -499,7 +502,7 @@ class FieldGenerator {
private:
friend class FieldGeneratorTable;
FieldGenerator(const FieldDescriptor* field, const Options& options,
absl::optional<uint32_t> hasbit_index);
const FieldLayout& field_layout);

std::unique_ptr<FieldGeneratorBase> impl_;
std::vector<io::Printer::Sub> field_vars_;
Expand Down Expand Up @@ -533,7 +536,8 @@ class FieldGeneratorTable {
//
// TODO: Make this function .cc-private.
std::vector<io::Printer::Sub> FieldVars(const FieldDescriptor* field,
const Options& opts);
const Options& opts,
const FieldLayout& field_layout);
} // namespace cpp
} // namespace compiler
} // namespace protobuf
Expand Down
5 changes: 3 additions & 2 deletions src/google/protobuf/compiler/cpp/field_chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ struct AlwaysTruePred {
template <typename Predicate, typename Filter = AlwaysTruePred>
std::vector<FieldChunk> CollectFields(
absl::Span<const FieldDescriptor* const> fields, const Options& options,
const Predicate& equivalent, const Filter filter = {}) {
const SplitMap& split_map, const Predicate& equivalent,
const Filter filter = {}) {
std::vector<FieldChunk> chunks;
bool force_new_chunk = true;
for (auto field : fields) {
Expand All @@ -66,7 +67,7 @@ std::vector<FieldChunk> CollectFields(
force_new_chunk = false;
chunks.emplace_back(HasHasbit(field, options),
IsRarelyPresent(field, options),
ShouldSplit(field, options));
split_map.IsSplit(field));
}
chunks.back().fields.push_back(field);
}
Expand Down
12 changes: 7 additions & 5 deletions src/google/protobuf/compiler/cpp/field_chunk_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ std::vector<const google::protobuf::FieldDescriptor*> CreateFieldArray(
template <typename ProtoT, typename PredT>
std::vector<FieldChunk> CreateAndCollectFields(
absl::Span<const char*> field_names, PredT&& predicate) {
return CollectFields(CreateFieldArray<ProtoT>(field_names), {}, predicate);
return CollectFields(CreateFieldArray<ProtoT>(field_names), /*options=*/{},
/*split_map=*/{}, predicate);
}

TEST(CollectFieldsTest, SingleChunk) {
Expand Down Expand Up @@ -70,10 +71,11 @@ TEST(CollectFieldsTest, RepeatedAndSingular) {
"optional_int64"};

auto fields = CreateFieldArray<TestAllTypes>(field_names);
auto chunks = CollectFields(
fields, {}, [](const FieldDescriptor* lhs, const FieldDescriptor* rhs) {
return lhs->is_repeated() == rhs->is_repeated();
});
auto chunks =
CollectFields(fields, /*options=*/{}, /*split_map=*/{},
[](const FieldDescriptor* lhs, const FieldDescriptor* rhs) {
return lhs->is_repeated() == rhs->is_repeated();
});

ASSERT_EQ(chunks.size(), 2);

Expand Down
31 changes: 18 additions & 13 deletions src/google/protobuf/compiler/cpp/field_generators/cord_field.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

#include <memory>
#include <string>
#include <tuple>

#include "absl/container/flat_hash_map.h"
#include "absl/log/absl_check.h"
Expand All @@ -21,7 +20,7 @@
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "google/protobuf/compiler/cpp/field.h"
#include "google/protobuf/compiler/cpp/field_generators/generators.h"
#include "google/protobuf/compiler/cpp/field_layout.h"
#include "google/protobuf/compiler/cpp/helpers.h"
#include "google/protobuf/compiler/cpp/options.h"
#include "google/protobuf/descriptor.h"
Expand Down Expand Up @@ -61,7 +60,8 @@ void SetCordVariables(

class CordFieldGenerator : public FieldGeneratorBase {
public:
CordFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
CordFieldGenerator(const FieldDescriptor* descriptor, const Options& options,
const FieldLayout& field_layout);
~CordFieldGenerator() override = default;

void GeneratePrivateMembers(io::Printer* p) const override;
Expand All @@ -84,7 +84,7 @@ class CordFieldGenerator : public FieldGeneratorBase {
if (field_->default_value_string().empty()) {
p->Emit(R"cc($name$_ {})cc");
} else {
p->Emit({{"Split", ShouldSplit(field_, options_) ? "Split::" : ""}},
p->Emit({{"Split", field_layout().IsSplit(field_) ? "Split::" : ""}},
R"cc(
$name$_ {
::absl::strings_internal::MakeStringConstant(
Expand Down Expand Up @@ -120,7 +120,8 @@ class CordFieldGenerator : public FieldGeneratorBase {
class CordOneofFieldGenerator : public CordFieldGenerator {
public:
CordOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
const Options& options,
const FieldLayout& field_layout);
~CordOneofFieldGenerator() override = default;

void GeneratePrivateMembers(io::Printer* p) const override;
Expand All @@ -140,8 +141,9 @@ class CordOneofFieldGenerator : public CordFieldGenerator {


CordFieldGenerator::CordFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: FieldGeneratorBase(descriptor, options) {
const Options& options,
const FieldLayout& field_layout)
: FieldGeneratorBase(descriptor, options, field_layout) {
SetCordVariables(descriptor, &variables_, options);
}

Expand Down Expand Up @@ -334,8 +336,9 @@ void CordFieldGenerator::GenerateAggregateInitializer(io::Printer* p) const {
// ===================================================================

CordOneofFieldGenerator::CordOneofFieldGenerator(
const FieldDescriptor* descriptor, const Options& options)
: CordFieldGenerator(descriptor, options) {}
const FieldDescriptor* descriptor, const Options& options,
const FieldLayout& field_layout)
: CordFieldGenerator(descriptor, options, field_layout) {}

void CordOneofFieldGenerator::GeneratePrivateMembers(io::Printer* p) const {
auto v = p->WithVars(variables_);
Expand Down Expand Up @@ -469,14 +472,16 @@ void CordOneofFieldGenerator::GenerateMergingCode(io::Printer* p) const {
} // namespace

std::unique_ptr<FieldGeneratorBase> MakeSingularCordGenerator(
const FieldDescriptor* desc, const Options& options) {
return std::make_unique<CordFieldGenerator>(desc, options);
const FieldDescriptor* desc, const Options& options,
const FieldLayout& field_layout) {
return std::make_unique<CordFieldGenerator>(desc, options, field_layout);
}


std::unique_ptr<FieldGeneratorBase> MakeOneofCordGenerator(
const FieldDescriptor* desc, const Options& options) {
return std::make_unique<CordOneofFieldGenerator>(desc, options);
const FieldDescriptor* desc, const Options& options,
const FieldLayout& field_layout) {
return std::make_unique<CordOneofFieldGenerator>(desc, options, field_layout);
}

} // namespace cpp
Expand Down
Loading
Loading