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

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

Issue 2293073002: Tracing V2: Proto fields reflection. (Closed)
Patch Set: Created 4 years, 4 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
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..d79fc8f0305c7b1ae6e985e5dbdde86d3a805a32 100644
--- a/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
+++ b/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
@@ -101,6 +101,23 @@ class GeneratorJob {
return name;
}
+ inline std::string Capitalize(const std::string& str) {
Primiano Tucci (use gerrit) 2016/08/31 09:04:07 honestly I feel this is just overkill as you use o
+ std::string copy(str);
+ copy.at(0) = toupper(copy.at(0));
+ return copy;
+ }
+
+ inline std::string GetFieldNumberConstant(const FieldDescriptor* field) {
+ std::string name = field->camelcase_name();
+ if (!name.empty()) {
+ name = std::string("k") + Capitalize(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)
@@ -229,6 +246,7 @@ class GeneratorJob {
"#define $guard$\n\n"
"#include <stddef.h>\n"
"#include <stdint.h>\n\n"
Primiano Tucci (use gerrit) 2016/08/31 09:04:07 I think you need also cctype for std::toupper
+ "#include <string>\n\n"
"#include \"components/tracing/core/proto_zero_message.h\"\n",
"greeting", greeting,
"guard", guard);
@@ -435,6 +453,57 @@ class GeneratorJob {
"outer_class", outer_class);
}
+ void GenerateReflectionHelpers(const Descriptor* message) {
+ // Field numbers.
Primiano Tucci (use gerrit) 2016/08/31 09:04:07 I'd make this more clear: // Field Numbers (e.g.,
kraynov 2016/08/31 17:43:33 Acknowledged.
+ if (message->field_count() > 0) {
+ stub_h_->Print("enum : int32_t {\n");
Primiano Tucci (use gerrit) 2016/08/31 09:04:07 just realized this, so far we used uint32_t for fi
kraynov 2016/08/31 17:43:33 Acknowledged.
+ 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.
+ stub_h_->Print(
+ "static ::tracing::v2::proto::FieldReflection "
+ "GetFieldReflection(uint32_t field_id);");
+ stub_cc_->Print(
+ "::tracing::v2::proto::FieldReflection "
+ "$class$::GetFieldReflection(uint32_t field_id) {\n",
+ "class", GetCppClassName(message));
+ stub_cc_->Indent();
+ stub_cc_->Print("switch (field_id) {\n");
+ stub_cc_->Indent();
+
+ for (int i = 0; i < message->field_count(); ++i) {
+ const FieldDescriptor* field = message->field(i);
+ stub_cc_->Print(
+ "case $id$:\n"
+ " return ::tracing::v2::proto::FieldReflection(\"$name$\", "
Primiano Tucci (use gerrit) 2016/08/31 09:04:07 Hmm this is going to be slow. Can we make this jus
kraynov 2016/08/31 17:43:33 Done.
+ "::tracing::v2::proto::ProtoType::kProtoType$type$,"
+ "$id$, $repeated$);\n",
+ "name", field->name(),
+ "type", Capitalize(FieldDescriptor::TypeName(field->type())),
+ "id", GetFieldNumberConstant(field),
+ "repeated", std::to_string(field->is_repeated()));
+ }
+ stub_cc_->Print(
+ "default:\n"
+ " return ::tracing::v2::proto::FieldReflection::CreateInvalid();\n");
+
+ stub_cc_->Outdent();
+ stub_cc_->Print("}\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 +511,8 @@ class GeneratorJob {
"name", GetCppClassName(message));
stub_h_->Indent();
+ GenerateReflectionHelpers(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 +546,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);

Powered by Google App Engine
This is Rietveld 408576698