Chromium Code Reviews| 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); |