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

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

Issue 2217703002: Tracing V2: Field number constants for protobuf plugin. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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 2165673b362eeefc3bbb110ca2e0be0fa6aac01c..055cbe759dda51227492034c18fdb1919a2dbb44 100644
--- a/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
+++ b/components/tracing/tools/proto_zero_plugin/proto_zero_generator.cc
@@ -26,6 +26,7 @@ using google::protobuf::compiler::GeneratorContext;
using google::protobuf::io::Printer;
using google::protobuf::io::ZeroCopyOutputStream;
+using google::protobuf::LowerString;
using google::protobuf::Split;
using google::protobuf::StripPrefixString;
using google::protobuf::StripString;
@@ -38,6 +39,93 @@ inline std::string ProtoStubName(const FileDescriptor* proto) {
return StripSuffixString(proto->name(), ".proto") + ".pbzero";
}
+enum CharCase {
+ UPPER,
+ LOWER,
+ DIGIT,
+ SYMBOL,
+ UNDEFINED,
+};
+
+inline CharCase GetCaseOfChar(char x) {
+ if ('A' <= x && x <= 'Z')
+ return CharCase::UPPER;
Primiano Tucci (use gerrit) 2016/08/05 08:52:05 I think here you are reinventing cctype's isupper(
kraynov 2016/08/05 11:05:53 Acknowledged.
+ else if ('a' <= x && x <= 'z')
+ return CharCase::LOWER;
+ else if ('0' <= x && x <= '9')
+ return CharCase::DIGIT;
+ else
+ return CharCase::SYMBOL;
+}
+
+std::string ExtractWord(const std::string& source, size_t* offset) {
+ std::string word;
+ CharCase start_case = CharCase::UNDEFINED;
+ CharCase end_case = CharCase::UNDEFINED;
+
+ while (*offset < source.size()) {
+ char current = source.at(*offset);
+ CharCase current_case = GetCaseOfChar(current);
+
+ // Skip underscores.
+ if (current_case == CharCase::SYMBOL) {
+ while (current_case == CharCase::SYMBOL) {
+ (*offset)++;
+ if (*offset == source.size())
+ return word;
+ current = source.at(*offset);
+ current_case = GetCaseOfChar(current);
+ }
+ if (!word.empty())
+ return word;
+ }
+ // Current case must be UPPER, LOWER or DIGIT below this line.
+
+ // Detect word's case.
+ if (word.empty()) {
+ start_case = current_case;
+ if (start_case == CharCase::LOWER || start_case == CharCase::DIGIT) {
+ end_case = start_case;
+ }
+ } else if (end_case == CharCase::UNDEFINED) {
+ // Must be a second character in this condition.
+ // Word starting with upper letter has two options (e.g. FOO or Bar).
+ end_case = current_case;
+ }
+
+ // Finish the word if case changes.
+ if (current_case != end_case && end_case != CharCase::UNDEFINED) {
+ if (end_case == CharCase::UPPER && current_case == CharCase::LOWER) {
+ // Rollback one character.
+ // E.g. [URL]Encoder, not [URLE]ncoder.
+ (*offset)--;
+ word.erase(word.size() - 1, 1);
+ }
+ return word;
+ }
+
+ word.push_back(current);
+ (*offset)++;
+ }
+ return word;
+}
+
+std::string NameToCamelCase(const std::string& name) {
+ std::string camel;
+ size_t offset = 0;
+ while (offset < name.size()) {
+ // Offset is mutable by ExtractWord function.
+ std::string word = ExtractWord(name, &offset);
+ if (word.empty())
+ continue;
+ LowerString(&word);
+ if (GetCaseOfChar(word.at(0)) == LOWER)
+ word.at(0) -= ('a' - 'A');
+ camel += word;
+ }
+ return camel;
+}
+
class GeneratorJob {
public:
GeneratorJob(const FileDescriptor *file,
@@ -463,7 +551,27 @@ class GeneratorJob {
}
}
- // Fields descriptors.
+ // 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 = NameToCamelCase(field->name());
Primiano Tucci (use gerrit) 2016/08/05 08:52:05 can you not just use field->camelcase_name()
kraynov 2016/08/05 11:05:53 Acknowledged.
+ if (name.empty())
+ 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);
if (field->is_packed()) {

Powered by Google App Engine
This is Rietveld 408576698