Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Unified Diff: components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc

Issue 2293073002: Tracing V2: Proto fields reflection. (Closed)
Patch Set: nit Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/tracing/test/proto_zero_generation_unittest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
diff --git a/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc b/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
index 713d3cca42fea6c28cb102b900dff6842c26bad2..cd2a0c9509c67fa34c13e0215c2a70735fc65577 100644
--- a/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
+++ b/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
@@ -43,9 +43,8 @@ class GeneratorJob {
GeneratorJob(const FileDescriptor *file,
Printer* stub_h_printer,
Printer* stub_cc_printer)
- : source_(file),
- stub_h_(stub_h_printer),
- stub_cc_(stub_cc_printer) {}
+ : source_(file), stub_h_(stub_h_printer), stub_cc_(stub_cc_printer) {
+ }
bool GenerateStubs() {
Preprocess();
@@ -101,6 +100,18 @@ class GeneratorJob {
return name;
}
+ inline std::string GetFieldNumberConstant(const FieldDescriptor* field) {
+ std::string name = field->camelcase_name();
+ if (!name.empty()) {
+ name.at(0) = toupper(name.at(0));
+ name = "k" + name + "FieldNumber";
+ } else {
+ // Protoc allows fields like 'bool _ = 1'.
+ Abort("Empty field name in camel case notation.");
+ }
+ return name;
+ }
+
// Small enums can be written faster without involving VarInt encoder.
inline bool IsTinyEnumField(const FieldDescriptor* field) {
if (field->type() != FieldDescriptor::TYPE_ENUM)
@@ -263,6 +274,16 @@ class GeneratorJob {
}
stub_cc_->Print("\n");
+ if (messages_.size() > 0) {
+ stub_cc_->Print(
+ "namespace {\n"
+ " static const ::tracing::v2::proto::ProtoFieldDescriptor "
+ "kInvalidField = {\"\", "
+ "::tracing::v2::proto::ProtoFieldDescriptor::Type::TYPE_INVALID, "
+ "0, false};\n"
+ "}\n\n");
+ }
+
// Print namespaces.
for (const std::string& ns : namespaces_) {
stub_h_->Print("namespace $ns$ {\n", "ns", ns);
@@ -435,6 +456,84 @@ class GeneratorJob {
"outer_class", outer_class);
}
+ void GenerateReflectionForMessageFields(const Descriptor* message) {
+ const bool has_fields = (message->field_count() > 0);
+
+ // Field number constants.
+ if (has_fields) {
+ stub_h_->Print("enum : int32_t {\n");
+ stub_h_->Indent();
+
+ for (int i = 0; i < message->field_count(); ++i) {
+ const FieldDescriptor* field = message->field(i);
+ stub_h_->Print(
+ "$name$ = $id$,\n",
+ "name", GetFieldNumberConstant(field),
+ "id", std::to_string(field->number()));
+ }
+ stub_h_->Outdent();
+ stub_h_->Print("};\n");
+ }
+
+ // Fields reflection table.
+ stub_h_->Print(
+ "static const ::tracing::v2::proto::ProtoFieldDescriptor* "
+ "GetFieldDescriptor(uint32_t field_id);\n");
+
+ std::string class_name = GetCppClassName(message);
+ if (has_fields) {
+ stub_cc_->Print(
+ "static const ::tracing::v2::proto::ProtoFieldDescriptor "
+ "kFields_$class$[] = {\n",
+ "class", class_name);
+ stub_cc_->Indent();
+ for (int i = 0; i < message->field_count(); ++i) {
+ const FieldDescriptor* field = message->field(i);
+ std::string type_const =
+ std::string("TYPE_") + FieldDescriptor::TypeName(field->type());
+ UpperString(&type_const);
+ stub_cc_->Print(
+ "{\"$name$\", "
+ "::tracing::v2::proto::ProtoFieldDescriptor::Type::$type$, "
+ "$number$, $is_repeated$},\n",
+ "name", field->name(),
+ "type", type_const,
+ "number", std::to_string(field->number()),
+ "is_repeated", std::to_string(field->is_repeated()));
+ }
+ stub_cc_->Outdent();
+ stub_cc_->Print("};\n\n");
+ }
+
+ // Fields reflection getter.
+ stub_cc_->Print(
+ "const ::tracing::v2::proto::ProtoFieldDescriptor* "
+ "$class$::GetFieldDescriptor(uint32_t field_id) {\n",
+ "class", class_name);
+ stub_cc_->Indent();
+ if (has_fields) {
+ stub_cc_->Print("switch (field_id) {\n");
+ stub_cc_->Indent();
+ for (int i = 0; i < message->field_count(); ++i) {
+ stub_cc_->Print(
+ "case $field$:\n"
+ " return &kFields_$class$[$id$];\n",
+ "class", class_name,
+ "field", GetFieldNumberConstant(message->field(i)),
+ "id", std::to_string(i));
+ }
+ stub_cc_->Print(
+ "default:\n"
+ " return &kInvalidField;\n");
+ stub_cc_->Outdent();
+ stub_cc_->Print("}\n");
+ } else {
+ stub_cc_->Print("return &kInvalidField;\n");
+ }
+ stub_cc_->Outdent();
+ stub_cc_->Print("}\n\n");
+ }
+
void GenerateMessageDescriptor(const Descriptor* message) {
stub_h_->Print(
"class $name$ : public ::tracing::v2::ProtoZeroMessage {\n"
@@ -442,6 +541,8 @@ class GeneratorJob {
"name", GetCppClassName(message));
stub_h_->Indent();
+ GenerateReflectionForMessageFields(message);
+
// Using statements for nested messages.
for (int i = 0; i < message->nested_type_count(); ++i) {
const Descriptor* nested_message = message->nested_type(i);
@@ -475,30 +576,6 @@ class GeneratorJob {
}
}
- // Field numbers.
- if (message->field_count() > 0) {
- stub_h_->Print("enum : int32_t {\n");
- stub_h_->Indent();
-
- for (int i = 0; i < message->field_count(); ++i) {
- const FieldDescriptor* field = message->field(i);
- std::string name = field->camelcase_name();
- if (!name.empty()) {
- name.at(0) = toupper(name.at(0));
- } else {
- // Protoc allows fields like 'bool _ = 1'.
- Abort("Empty field name in camel case notation.");
- }
-
- stub_h_->Print(
- "k$name$FieldNumber = $id$,\n",
- "name", name,
- "id", std::to_string(field->number()));
- }
- stub_h_->Outdent();
- stub_h_->Print("};\n");
- }
-
// Field descriptors.
for (int i = 0; i < message->field_count(); ++i) {
const FieldDescriptor* field = message->field(i);
« no previous file with comments | « components/tracing/test/proto_zero_generation_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698