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

Side by Side Diff: lib/file_generator.dart

Issue 2020483002: clean up API for file_generator.dart (Closed) Base URL: git@github.com:dart-lang/dart-protoc-plugin.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « lib/code_generator.dart ('k') | test/file_generator_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of protoc; 5 part of protoc;
6 6
7 /// Generates the Dart output files for one .proto input file.
8 ///
9 /// Outputs include .pb.dart, pbenum.dart, and .pbjson.dart.
7 class FileGenerator extends ProtobufContainer { 10 class FileGenerator extends ProtobufContainer {
8 /// Returns the the mixin to use by default in this file, 11 /// Returns the the mixin to use by default in this file,
9 /// or null for no mixin by default. 12 /// or null for no mixin by default.
10 static PbMixin _getDefaultMixin(FileDescriptorProto desc) { 13 static PbMixin _getDefaultMixin(FileDescriptorProto desc) {
11 if (!desc.hasOptions()) return null; 14 if (!desc.hasOptions()) return null;
12 if (!desc.options.hasExtension(Dart_options.defaultMixin)) { 15 if (!desc.options.hasExtension(Dart_options.defaultMixin)) {
13 return null; 16 return null;
14 } 17 }
15 var name = desc.options.getExtension(Dart_options.defaultMixin); 18 var name = desc.options.getExtension(Dart_options.defaultMixin);
16 PbMixin mixin = findMixin(name); 19 PbMixin mixin = findMixin(name);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 if (_fileDescriptor.package != '') { 107 if (_fileDescriptor.package != '') {
105 // Two .protos can be in the same proto package. 108 // Two .protos can be in the same proto package.
106 // It isn't unique enough to use as a Dart library name. 109 // It isn't unique enough to use as a Dart library name.
107 // But we can prepend it. 110 // But we can prepend it.
108 return _fileDescriptor.package + "_" + libraryName; 111 return _fileDescriptor.package + "_" + libraryName;
109 } 112 }
110 113
111 return libraryName; 114 return libraryName;
112 } 115 }
113 116
114 CodeGeneratorResponse_File generateResponse(OutputConfiguration config) { 117 /// Generates all the Dart files for this .proto file.
118 List<CodeGeneratorResponse_File> generateFiles(OutputConfiguration config) {
119 if (!_linked) throw new StateError("not linked");
120
121 makeFile(String extension, String content) {
122 Uri protoUrl = new Uri.file(_fileDescriptor.name);
123 Uri dartUrl = config.outputPathFor(protoUrl, extension);
124 return new CodeGeneratorResponse_File()
125 ..name = dartUrl.path
126 ..content = content;
127 }
128
129 return [
130 makeFile(".pb.dart", generateMainFile(config)),
131 makeFile(".pbenum.dart", generateEnumFile(config)),
132 makeFile(".pbjson.dart", generateJsonFile(config)),
133 ];
134 }
135
136 /// Returns the contents of the .pb.dart file for this .proto file.
137 String generateMainFile(
138 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
139 if (!_linked) throw new StateError("not linked");
115 IndentingWriter out = new IndentingWriter(); 140 IndentingWriter out = new IndentingWriter();
116 141
117 generate(out, config); 142 writeMainHeader(out, config);
118
119 Uri filePath = new Uri.file(_fileDescriptor.name);
120 return new CodeGeneratorResponse_File()
121 ..name = config.outputPathFor(filePath, ".pb.dart").path
122 ..content = out.toString();
123 }
124
125 /// Generates the Dart code for this .proto file.
126 void generate(IndentingWriter out,
127 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
128 if (!_linked) throw new StateError("not linked");
129
130 generateHeader(out, config);
131 143
132 // Generate code. 144 // Generate code.
133 for (MessageGenerator m in messageGenerators) { 145 for (MessageGenerator m in messageGenerators) {
134 m.generate(out); 146 m.generate(out);
135 } 147 }
136 148
137 // Generate code for extensions defined at top-level using a class 149 // Generate code for extensions defined at top-level using a class
138 // name derived from the file name. 150 // name derived from the file name.
139 if (!extensionGenerators.isEmpty) { 151 if (!extensionGenerators.isEmpty) {
140 // TODO(antonm): do not generate a class. 152 // TODO(antonm): do not generate a class.
(...skipping 10 matching lines...) Expand all
151 out.println('}'); 163 out.println('}');
152 }); 164 });
153 } 165 }
154 166
155 for (ClientApiGenerator c in clientApiGenerators) { 167 for (ClientApiGenerator c in clientApiGenerators) {
156 c.generate(out); 168 c.generate(out);
157 } 169 }
158 for (ServiceGenerator s in serviceGenerators) { 170 for (ServiceGenerator s in serviceGenerators) {
159 s.generate(out); 171 s.generate(out);
160 } 172 }
173
174 return out.toString();
161 } 175 }
162 176
163 /// Prints header and imports. 177 /// Writes the header and imports for the .pb.dart file.
164 void generateHeader(IndentingWriter out, 178 void writeMainHeader(IndentingWriter out,
165 [OutputConfiguration config = const DefaultOutputConfiguration()]) { 179 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
166 String libraryName = _generateLibraryName(protoFileUri); 180 String libraryName = _generateLibraryName(protoFileUri);
167 out.println('///\n' 181 out.println('///\n'
168 '// Generated code. Do not modify.\n' 182 '// Generated code. Do not modify.\n'
169 '///\n' 183 '///\n'
170 'library $libraryName;\n'); 184 'library $libraryName;\n');
171 185
172 // We only add the dart:async import if there are services in the 186 // We only add the dart:async import if there are services in the
173 // FileDescriptorProto. 187 // FileDescriptorProto.
174 if (_fileDescriptor.service.isNotEmpty) { 188 if (_fileDescriptor.service.isNotEmpty) {
175 out.println("import 'dart:async';\n"); 189 out.println("import 'dart:async';\n");
176 } 190 }
177 191
178 if (_needsFixnumImport) { 192 if (_needsFixnumImport) {
179 out.println("import 'package:fixnum/fixnum.dart';"); 193 out.println("import 'package:fixnum/fixnum.dart';");
180 } 194 }
181 195
182 if (_needsProtobufImport) { 196 if (_needsProtobufImport) {
183 out.println("import 'package:protobuf/protobuf.dart';"); 197 out.println("import 'package:protobuf/protobuf.dart';");
184 out.println(); 198 out.println();
185 } 199 }
186 200
187 var mixinImports = findMixinsToImport(); 201 var mixinImports = findMixinsToImport();
188 var importNames = mixinImports.keys.toList(); 202 var importNames = mixinImports.keys.toList();
189 importNames.sort(); 203 importNames.sort();
190 for (var imp in importNames) { 204 for (var imp in importNames) {
191 var symbols = mixinImports[imp]; 205 var symbols = mixinImports[imp];
192 out.println("import '${imp}' show ${symbols.join(', ')};"); 206 out.println("import '${imp}' show ${symbols.join(', ')};");
193 } 207 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 symbols.add(m.name); 299 symbols.add(m.name);
286 } 300 }
287 301
288 for (var imp in imports.keys) { 302 for (var imp in imports.keys) {
289 imports[imp].sort(); 303 imports[imp].sort();
290 } 304 }
291 305
292 return imports; 306 return imports;
293 } 307 }
294 308
295 CodeGeneratorResponse_File generateEnumResponse(OutputConfiguration config) { 309 /// Returns the contents of the .pbenum.dart file for this .proto file.
310 String generateEnumFile(
311 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
296 if (!_linked) throw new StateError("not linked"); 312 if (!_linked) throw new StateError("not linked");
297
298 IndentingWriter out = new IndentingWriter();
299
300 generateEnumFile(out, config);
301
302 Uri filePath = new Uri.file(_fileDescriptor.name);
303 return new CodeGeneratorResponse_File()
304 ..name = config.outputPathFor(filePath, ".pbenum.dart").path
305 ..content = out.toString();
306 }
307
308 void generateEnumFile(IndentingWriter out,
309 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
310 Uri filePath = new Uri.file(_fileDescriptor.name); 313 Uri filePath = new Uri.file(_fileDescriptor.name);
311 if (filePath.isAbsolute) { 314 if (filePath.isAbsolute) {
312 // protoc should never generate a file descriptor with an absolute path. 315 // protoc should never generate a file descriptor with an absolute path.
313 throw "FAILURE: File with an absolute path is not supported"; 316 throw "FAILURE: File with an absolute path is not supported";
314 } 317 }
315 318
316 var baseLibraryName = _generateLibraryName(filePath); 319 var baseLibraryName = _generateLibraryName(filePath);
317 var libraryName = baseLibraryName + "_pbenum"; 320 var libraryName = baseLibraryName + "_pbenum";
321 var out = new IndentingWriter();
318 out.print(''' 322 out.print('''
319 /// 323 ///
320 // Generated code. Do not modify. 324 // Generated code. Do not modify.
321 /// 325 ///
322 library $libraryName; 326 library $libraryName;
323 327
324 '''); 328 ''');
325 329
326 if (enumCount > 0) { 330 if (enumCount > 0) {
327 out.println("import 'package:protobuf/protobuf.dart';"); 331 out.println("import 'package:protobuf/protobuf.dart';");
328 out.println(); 332 out.println();
329 } 333 }
330 334
331 for (EnumGenerator e in enumGenerators) { 335 for (EnumGenerator e in enumGenerators) {
332 e.generate(out); 336 e.generate(out);
333 } 337 }
334 338
335 for (MessageGenerator m in messageGenerators) { 339 for (MessageGenerator m in messageGenerators) {
336 m.generateEnums(out); 340 m.generateEnums(out);
337 } 341 }
342
343 return out.toString();
338 } 344 }
339 345
340 /// Returns the number of enum types generated in the .pbenum.dart file. 346 /// Returns the number of enum types generated in the .pbenum.dart file.
341 int get enumCount { 347 int get enumCount {
342 var count = enumGenerators.length; 348 var count = enumGenerators.length;
343 for (MessageGenerator m in messageGenerators) { 349 for (MessageGenerator m in messageGenerators) {
344 count += m.enumCount; 350 count += m.enumCount;
345 } 351 }
346 return count; 352 return count;
347 } 353 }
348 354
349 CodeGeneratorResponse_File generateJsonDartResponse( 355 /// Returns the contents of the .pbjson.dart file for this .proto file.
350 OutputConfiguration config) { 356 String generateJsonFile(
357 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
351 if (!_linked) throw new StateError("not linked"); 358 if (!_linked) throw new StateError("not linked");
352
353 IndentingWriter out = new IndentingWriter();
354
355 generateJsonDart(out, config);
356
357 Uri filePath = new Uri.file(_fileDescriptor.name);
358 return new CodeGeneratorResponse_File()
359 ..name = config.outputPathFor(filePath, ".pbjson.dart").path
360 ..content = out.toString();
361 }
362
363 void generateJsonDart(IndentingWriter out,
364 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
365 Uri filePath = new Uri.file(_fileDescriptor.name); 359 Uri filePath = new Uri.file(_fileDescriptor.name);
366 if (filePath.isAbsolute) { 360 if (filePath.isAbsolute) {
367 // protoc should never generate a file descriptor with an absolute path. 361 // protoc should never generate a file descriptor with an absolute path.
368 throw "FAILURE: File with an absolute path is not supported"; 362 throw "FAILURE: File with an absolute path is not supported";
369 } 363 }
370 364
371 var baseLibraryName = _generateLibraryName(filePath); 365 var baseLibraryName = _generateLibraryName(filePath);
372 var libraryName = baseLibraryName + "_pbjson"; 366 var libraryName = baseLibraryName + "_pbjson";
367 var out = new IndentingWriter();
373 out.print(''' 368 out.print('''
374 /// 369 ///
375 // Generated code. Do not modify. 370 // Generated code. Do not modify.
376 /// 371 ///
377 library $libraryName; 372 library $libraryName;
378 373
379 '''); 374 ''');
380 375
381 // Import the .pbjson.dart files we depend on. 376 // Import the .pbjson.dart files we depend on.
382 var importList = _findJsonProtosToImport(); 377 var importList = _findJsonProtosToImport();
(...skipping 10 matching lines...) Expand all
393 388
394 for (var e in enumGenerators) { 389 for (var e in enumGenerators) {
395 e.generateConstants(out); 390 e.generateConstants(out);
396 } 391 }
397 for (MessageGenerator m in messageGenerators) { 392 for (MessageGenerator m in messageGenerators) {
398 m.generateConstants(out); 393 m.generateConstants(out);
399 } 394 }
400 for (ServiceGenerator s in serviceGenerators) { 395 for (ServiceGenerator s in serviceGenerators) {
401 s.generateConstants(out); 396 s.generateConstants(out);
402 } 397 }
398
399 return out.toString();
403 } 400 }
404 401
405 /// Returns the generator for each .pbjson.dart file the generated 402 /// Returns the generator for each .pbjson.dart file the generated
406 /// .pbjson.dart needs to import. 403 /// .pbjson.dart needs to import.
407 Set<FileGenerator> _findJsonProtosToImport() { 404 Set<FileGenerator> _findJsonProtosToImport() {
408 var imports = new Set<FileGenerator>.identity(); 405 var imports = new Set<FileGenerator>.identity();
409 for (var m in messageGenerators) { 406 for (var m in messageGenerators) {
410 m.addConstantImportsTo(imports); 407 m.addConstantImportsTo(imports);
411 } 408 }
412 for (var x in extensionGenerators) { 409 for (var x in extensionGenerators) {
413 x.addConstantImportsTo(imports); 410 x.addConstantImportsTo(imports);
414 } 411 }
415 for (var x in serviceGenerators) { 412 for (var x in serviceGenerators) {
416 x.addConstantImportsTo(imports); 413 x.addConstantImportsTo(imports);
417 } 414 }
418 imports.remove(this); // Don't need to import self. 415 imports.remove(this); // Don't need to import self.
419 return imports; 416 return imports;
420 } 417 }
421 } 418 }
OLDNEW
« no previous file with comments | « lib/code_generator.dart ('k') | test/file_generator_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698