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

Side by Side Diff: components/tracing/proto_zero_plugin/proto_zero_generator.cc

Issue 2083373002: proto_zero_plugin [NOT FOR REVIEW]. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: refactoring Created 4 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "proto_zero_generator.h"
6
7 #include <string>
8 #include <algorithm>
9
10 #include <google/protobuf/descriptor.h>
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 make these absolute includes https://google.githu
11 #include <google/protobuf/io/printer.h>
12 #include <google/protobuf/io/zero_copy_stream.h>
13 #include <google/protobuf/stubs/strutil.h>
14
15 namespace google {
16 namespace protobuf {
17 namespace compiler {
18 namespace fastcpp {
19
20 namespace {
21
22 // TODO(kraynov) Ship "lite" runtime in order to use outside of tracing.
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 Not sure what this TODO means.
23 const string OUT_INCLUDES =
Primiano Tucci (use gerrit) 2016/07/05 11:30:16 This generates a static initializer (Bad thing). A
24 "#include \"base/trace_event/append_only_proto_message.h\"\n";
25 const string OUT_MESSAGE_CLASS =
26 "::base::trace_event::AppendOnlyProtoMessage";
27
28
29 class GeneratorJob {
30 public:
31 GeneratorJob(const FileDescriptor* file, io::Printer* printer)
32 : file_(file), printer_(printer) {}
33
34 void Run() {
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 Hmm Run makes it feel this is like part of some th
35 PrepareNamespace();
36 PrepareIncludeGuard();
37 PrepareMessages();
38
39 PrintBoilerplate();
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 I'd s/Print/Generate/ in these functions.
40 for (const Descriptor* message : messages_) {
41 PrintMessage(message);
42 }
43 PrintEpilog();
44 }
45
46 private:
47 // Split string by dots.
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 Looks like this is reinventing base/strings/string
48 vector<string> StringTokens(const string& str) {
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 std::string. I think we disallow "using namespace
49 vector<string> tokens;
50 size_t left = 0;
51 while (left < str.size()) {
52 size_t right = std::min(str.find('.', left), str.size());
53 tokens.push_back(str.substr(left, right));
54 left = right + 1;
55 }
56 return tokens;
57 }
58
59 // Seal generated classes into namespace corresponding to package name.
60 void PrepareNamespace() {
61 package_ = file_->package();
62 namespaces_ = StringTokens(package_);
63 absolute_namespace_ = "::";
64 for (const string ns : namespaces_) {
Primiano Tucci (use gerrit) 2016/07/05 11:30:18 missing & (const string&), this one is unnecessari
65 absolute_namespace_ += ns + "::";
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 this will make the abs_namespace end with "::". Do
66 }
67 }
68
69 // Unique define to guard a header.
70 void PrepareIncludeGuard() {
71 include_guard_ = package_ + "_" + file_->name() + "_H_";
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 Why this method pre-computing the include guard? L
72 UpperString(&include_guard_);
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 Use ToUpperASCII from base/strings
73 StripString(&include_guard_, ".-", '_');
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 ditto
74 }
75
76 // Collect all messages in DFS order.
77 // TODO(kraynov) Try topological sort to eliminate forward declarations.
78 void PrepareMessages() {
79 vector<const Descriptor*> stack;
80 for (int i = 0; i < file_->message_type_count(); ++i) {
81 stack.push_back(file_->message_type(i));
82 }
83 while (stack.size() > 0) {
Primiano Tucci (use gerrit) 2016/07/05 11:30:16 s/.size() > 0/! ... .empty())
84 const Descriptor* message = stack.back();
85 stack.pop_back();
86 messages_.push_back(message);
87 for (int i = 0; i < message->nested_type_count(); ++i) {
88 stack.push_back(message->nested_type(i));
89 }
90 }
91 }
92
93 // Get C++ class name corresponding to message descriptor.
94 // Nested names are splitted by underscores.
95 string GetCppClassName(const Descriptor* message) {
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 this seems to be a static function
96 string class_name = StripPrefixString(message->full_name(), package_ + ".");
97 StripString(&class_name, ".-", '_');
98 return class_name;
99 }
100
101 void PrintBoilerplate() {
Primiano Tucci (use gerrit) 2016/07/05 11:30:16 I think this should be called: GeneratePrologue()
102 printer_->Print(
103 "// Autogenerated. DO NOT EDIT.\n"
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 maybe say: autogenerated by //components/tracing/t
104 "#ifndef $guard$\n"
105 "#define $guard$\n\n"
106 "$includes$\n",
107
108 "includes", OUT_INCLUDES,
109 "guard", include_guard_);
110
111 // Print namespaces
112 for (string ns : namespaces_) {
113 printer_->Print("namespace $ns$ {\n", "ns", ns);
114 }
115 printer_->Print("\n");
116 // Print forward declarations
117 for (const Descriptor* message : messages_) {
118 printer_->Print(
119 "class $class$;\n",
120 "class", GetCppClassName(message));
121 }
122 printer_->Print("\n");
123 }
124
125 void PrintSimpleField(const FieldDescriptor* field) {
126 string type;
127 string appender;
128
129 switch (field->type()) {
130 case FieldDescriptor::TYPE_DOUBLE:
131 type = "double";
132 appender = "AppendDouble";
133 break;
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 also TYPE_FLOAT
134 case FieldDescriptor::TYPE_INT64:
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 I think this is SINT64. It seems proto supports in
135 type = "int64_t";
136 appender = "AppendVarIntSigned";
137 break;
138 case FieldDescriptor::TYPE_BOOL:
139 type = "bool";
140 appender = "AppendVarIntUnsigned";
141 break;
142 case FieldDescriptor::TYPE_STRING:
143 type = "const char*";
144 appender = "AppendString";
145 break;
146 default:
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 Add TYPE_UINT32
147 // TODO(kraynov) Fail if not supported.
148 break;
149 }
150 printer_->Print(
151 "void set_$name$($type$ value) {\n"
152 " $appender$($number$, value);\n"
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 s/number/field_number
153 "}\n",
154
155 "type", type,
156 "name", field->name(),
157 "appender", appender,
158 "number", std::to_string(field->number()));
159 }
160
161 void PrintNestedMessageField(const FieldDescriptor* field) {
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 For the moment let's leave this out and re-add onc
162 printer_->Print(
163 "$class$* add_$name$() {\n"
164 " $class$* inst = new $class$(buffer(), this);\n"
165 " BeginNestedMessage($number$, std::unique_ptr<$base$>(inst));\n"
166 " return inst;\n"
167 "}\n",
168
169 "class", absolute_namespace_ + GetCppClassName(field->message_type()),
170 "name", field->name(),
171 "number", std::to_string(field->number()),
172 "base", OUT_MESSAGE_CLASS);
173 }
174
175 void PrintFields(const Descriptor* message) {
Primiano Tucci (use gerrit) 2016/07/05 11:30:18 I'd s/message/descriptor/ here and elsewhere. In g
176 for (int i = 0; i < message->field_count(); ++i) {
177 if (message->field(i)->type() != FieldDescriptor::TYPE_MESSAGE) {
178 PrintSimpleField(message->field(i));
179 } else {
180 PrintNestedMessageField(message->field(i));
181 }
182 }
183 }
184
185 void PrintMessage(const Descriptor* message) {
186 printer_->Print(
187 "class $class$ : public $base$ {\n",
188
189 "class", GetCppClassName(message),
190 "base", OUT_MESSAGE_CLASS);
191
192 printer_->Indent();
193 PrintFields(message);
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 Legibility: hmm maybe PrintFields should just be i
194 printer_->Outdent();
195 printer_->Print("};\n\n");
196 }
197
198 void PrintEpilog() {
Primiano Tucci (use gerrit) 2016/07/05 11:30:18 s/Epilog/Epilogue/
199 for (auto it = namespaces_.rbegin(); it != namespaces_.rend(); ++it) {
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 for (const std::string& ns : namespaces_)
200 printer_->Print("} // namespace $ns$\n", "ns", *it);
201 }
202 printer_->Print(""
203 "#endif // $guard$\n",
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 yeah don't worry about this (the guard name in the
204 "guard", include_guard_);
205 }
206
207 const FileDescriptor* file_;
Primiano Tucci (use gerrit) 2016/07/05 11:30:17 I'd s/file_/descriptor_/. file_. suggests it's a u
208 io::Printer* printer_;
209
210 string package_;
211 string include_guard_;
212 vector<string> namespaces_;
213 string absolute_namespace_;
214 vector<const Descriptor*> messages_;
215 };
216
217 } // namespace
218
219 bool Generator::Generate(const FileDescriptor* file,
220 const string& parameter,
221 GeneratorContext* context,
222 string* error) const {
223
224 using google::protobuf::scoped_ptr;
225
226 string stub_name = StripSuffixString(file->name(), ".proto") + ".zeropb";
227
228 scoped_ptr<io::ZeroCopyOutputStream> pb_h(context->Open(stub_name + ".h"));
229 io::Printer pb_h_printer(pb_h.get(), '$'); // $ used as variable delimiter.
230 GeneratorJob job(file, &pb_h_printer);
231 job.Run();
232
233 scoped_ptr<io::ZeroCopyOutputStream> pb_cc(context->Open(stub_name + ".cc"));
234 io::Printer pb_cc_printer(pb_cc.get(), '$');
235 pb_cc_printer.Print("// This file intentionally left blank.\n");
236
237 return true;
238 }
239
240 } // namespace fastcpp
241 } // namespace compiler
242 } // namespace protobuf
243 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698