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

Side by Side Diff: lib/file_generator.dart

Issue 2013343002: Move server-side service stubs to .pbserver.dart (Closed) Base URL: git@github.com:dart-lang/dart-protoc-plugin.git@cleanup
Patch Set: bump version Created 4 years, 7 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
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. 7 /// Generates the Dart output files for one .proto input file.
8 /// 8 ///
9 /// Outputs include .pb.dart, pbenum.dart, and .pbjson.dart. 9 /// Outputs include .pb.dart, pbenum.dart, and .pbjson.dart.
10 class FileGenerator extends ProtobufContainer { 10 class FileGenerator extends ProtobufContainer {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 String fileName = filePath.pathSegments.last; 90 String fileName = filePath.pathSegments.last;
91 int index = fileName.lastIndexOf("."); 91 int index = fileName.lastIndexOf(".");
92 return index == -1 ? fileName : fileName.substring(0, index); 92 return index == -1 ? fileName : fileName.substring(0, index);
93 } 93 }
94 94
95 String _generateClassName(Uri protoFilePath) { 95 String _generateClassName(Uri protoFilePath) {
96 String s = _fileNameWithoutExtension(protoFilePath).replaceAll('-', '_'); 96 String s = _fileNameWithoutExtension(protoFilePath).replaceAll('-', '_');
97 return '${s[0].toUpperCase()}${s.substring(1)}'; 97 return '${s[0].toUpperCase()}${s.substring(1)}';
98 } 98 }
99 99
100 /// Returns the library name at the top of the .pb.dart file.
101 ///
102 /// (This should be unique to avoid warnings about duplicate Dart libraries.)
103 String _generateLibraryName(Uri protoFilePath) {
104 var libraryName =
105 _fileNameWithoutExtension(protoFilePath).replaceAll('-', '_');
106
107 if (_fileDescriptor.package != '') {
108 // Two .protos can be in the same proto package.
109 // It isn't unique enough to use as a Dart library name.
110 // But we can prepend it.
111 return _fileDescriptor.package + "_" + libraryName;
112 }
113
114 return libraryName;
115 }
116
117 /// Generates all the Dart files for this .proto file. 100 /// Generates all the Dart files for this .proto file.
118 List<CodeGeneratorResponse_File> generateFiles(OutputConfiguration config) { 101 List<CodeGeneratorResponse_File> generateFiles(OutputConfiguration config) {
119 if (!_linked) throw new StateError("not linked"); 102 if (!_linked) throw new StateError("not linked");
120 103
121 makeFile(String extension, String content) { 104 makeFile(String extension, String content) {
122 Uri protoUrl = new Uri.file(_fileDescriptor.name); 105 Uri protoUrl = new Uri.file(_fileDescriptor.name);
123 Uri dartUrl = config.outputPathFor(protoUrl, extension); 106 Uri dartUrl = config.outputPathFor(protoUrl, extension);
124 return new CodeGeneratorResponse_File() 107 return new CodeGeneratorResponse_File()
125 ..name = dartUrl.path 108 ..name = dartUrl.path
126 ..content = content; 109 ..content = content;
127 } 110 }
128 111
129 return [ 112 return [
130 makeFile(".pb.dart", generateMainFile(config)), 113 makeFile(".pb.dart", generateMainFile(config)),
131 makeFile(".pbenum.dart", generateEnumFile(config)), 114 makeFile(".pbenum.dart", generateEnumFile(config)),
115 makeFile(".pbserver.dart", generateServerFile(config)),
132 makeFile(".pbjson.dart", generateJsonFile(config)), 116 makeFile(".pbjson.dart", generateJsonFile(config)),
133 ]; 117 ];
134 } 118 }
135 119
136 /// Returns the contents of the .pb.dart file for this .proto file. 120 /// Returns the contents of the .pb.dart file for this .proto file.
137 String generateMainFile( 121 String generateMainFile(
138 [OutputConfiguration config = const DefaultOutputConfiguration()]) { 122 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
139 if (!_linked) throw new StateError("not linked"); 123 if (!_linked) throw new StateError("not linked");
140 IndentingWriter out = new IndentingWriter(); 124 IndentingWriter out = new IndentingWriter();
141 125
(...skipping 18 matching lines...) Expand all
160 for (ExtensionGenerator x in extensionGenerators) { 144 for (ExtensionGenerator x in extensionGenerators) {
161 out.println(' registry.add(${x.name});'); 145 out.println(' registry.add(${x.name});');
162 } 146 }
163 out.println('}'); 147 out.println('}');
164 }); 148 });
165 } 149 }
166 150
167 for (ClientApiGenerator c in clientApiGenerators) { 151 for (ClientApiGenerator c in clientApiGenerators) {
168 c.generate(out); 152 c.generate(out);
169 } 153 }
170 for (ServiceGenerator s in serviceGenerators) {
171 s.generate(out);
172 }
173
174 return out.toString(); 154 return out.toString();
175 } 155 }
176 156
177 /// Writes the header and imports for the .pb.dart file. 157 /// Writes the header and imports for the .pb.dart file.
178 void writeMainHeader(IndentingWriter out, 158 void writeMainHeader(IndentingWriter out,
179 [OutputConfiguration config = const DefaultOutputConfiguration()]) { 159 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
180 String libraryName = _generateLibraryName(protoFileUri); 160 _writeLibraryHeading(out);
181 out.println('///\n'
182 '// Generated code. Do not modify.\n'
183 '///\n'
184 'library $libraryName;\n');
185 161
186 // We only add the dart:async import if there are services in the 162 // We only add the dart:async import if there are services in the
187 // FileDescriptorProto. 163 // FileDescriptorProto.
188 if (_fileDescriptor.service.isNotEmpty) { 164 if (_fileDescriptor.service.isNotEmpty) {
189 out.println("import 'dart:async';\n"); 165 out.println("import 'dart:async';\n");
190 } 166 }
191 167
192 if (_needsFixnumImport) { 168 if (_needsFixnumImport) {
193 out.println("import 'package:fixnum/fixnum.dart';"); 169 out.println("import 'package:fixnum/fixnum.dart';");
194 } 170 }
(...skipping 10 matching lines...) Expand all
205 var symbols = mixinImports[imp]; 181 var symbols = mixinImports[imp];
206 out.println("import '${imp}' show ${symbols.join(', ')};"); 182 out.println("import '${imp}' show ${symbols.join(', ')};");
207 } 183 }
208 if (mixinImports.isNotEmpty) out.println(); 184 if (mixinImports.isNotEmpty) out.println();
209 185
210 // Import the .pb.dart files we depend on. 186 // Import the .pb.dart files we depend on.
211 var imports = new Set<FileGenerator>.identity(); 187 var imports = new Set<FileGenerator>.identity();
212 var enumImports = new Set<FileGenerator>.identity(); 188 var enumImports = new Set<FileGenerator>.identity();
213 _findProtosToImport(imports, enumImports); 189 _findProtosToImport(imports, enumImports);
214 190
215 void writeImport(FileGenerator target, String extension) {
216 Uri resolvedImport =
217 config.resolveImport(target.protoFileUri, protoFileUri, extension);
218 out.print("import '$resolvedImport'");
219 if (package != target.package && target.package.isNotEmpty) {
220 out.print(' as ${target.packageImportPrefix}');
221 }
222 out.println(';');
223 }
224
225 for (var target in imports) { 191 for (var target in imports) {
226 writeImport(target, ".pb.dart"); 192 _writeImport(out, config, target, ".pb.dart");
227 } 193 }
228 if (imports.isNotEmpty) out.println(); 194 if (imports.isNotEmpty) out.println();
229 195
230 for (var target in enumImports) { 196 for (var target in enumImports) {
231 writeImport(target, ".pbenum.dart"); 197 _writeImport(out, config, target, ".pbenum.dart");
232 } 198 }
233 if (enumImports.isNotEmpty) out.println(); 199 if (enumImports.isNotEmpty) out.println();
234 200
235 // Services also depend on the json imports.
236 if (serviceGenerators.isNotEmpty) {
237 Uri resolvedImport =
238 config.resolveImport(protoFileUri, protoFileUri, ".pbjson.dart");
239 out.println("import '$resolvedImport';");
240 out.println();
241 }
242
243 // Export enums in main file for backward compatibility. 201 // Export enums in main file for backward compatibility.
244 if (enumCount > 0) { 202 if (enumCount > 0) {
245 Uri resolvedImport = 203 Uri resolvedImport =
246 config.resolveImport(protoFileUri, protoFileUri, ".pbenum.dart"); 204 config.resolveImport(protoFileUri, protoFileUri, ".pbenum.dart");
247 out.println("export '$resolvedImport';"); 205 out.println("export '$resolvedImport';");
248 out.println(); 206 out.println();
249 } 207 }
250 } 208 }
251 209
252 bool get _needsFixnumImport { 210 bool get _needsFixnumImport {
253 for (var m in messageGenerators) { 211 for (var m in messageGenerators) {
254 if (m.needsFixnumImport) return true; 212 if (m.needsFixnumImport) return true;
255 } 213 }
256 for (var x in extensionGenerators) { 214 for (var x in extensionGenerators) {
257 if (x.needsFixnumImport) return true; 215 if (x.needsFixnumImport) return true;
258 } 216 }
259 return false; 217 return false;
260 } 218 }
261 219
262 bool get _needsProtobufImport => 220 bool get _needsProtobufImport =>
263 messageGenerators.isNotEmpty || 221 messageGenerators.isNotEmpty ||
264 extensionGenerators.isNotEmpty || 222 extensionGenerators.isNotEmpty ||
265 clientApiGenerators.isNotEmpty || 223 clientApiGenerators.isNotEmpty;
266 serviceGenerators.isNotEmpty;
267 224
268 /// Returns the generator for each .pb.dart file we need to import. 225 /// Returns the generator for each .pb.dart file we need to import.
269 void _findProtosToImport( 226 void _findProtosToImport(
270 Set<FileGenerator> imports, Set<FileGenerator> enumImports) { 227 Set<FileGenerator> imports, Set<FileGenerator> enumImports) {
271 for (var m in messageGenerators) { 228 for (var m in messageGenerators) {
272 m.addImportsTo(imports, enumImports); 229 m.addImportsTo(imports, enumImports);
273 } 230 }
274 for (var x in extensionGenerators) { 231 for (var x in extensionGenerators) {
275 x.addImportsTo(imports, enumImports); 232 x.addImportsTo(imports, enumImports);
276 } 233 }
234 // Add imports needed for client-side services.
277 for (var x in serviceGenerators) { 235 for (var x in serviceGenerators) {
278 x.addImportsTo(imports); 236 x.addImportsTo(imports);
279 } 237 }
280 // Don't need to import self. (But we may need to import the enums.) 238 // Don't need to import self. (But we may need to import the enums.)
281 imports.remove(this); 239 imports.remove(this);
282 } 240 }
283 241
284 /// Returns a map from import names to the Dart symbols to be imported. 242 /// Returns a map from import names to the Dart symbols to be imported.
285 Map<String, List<String>> findMixinsToImport() { 243 Map<String, List<String>> findMixinsToImport() {
286 var mixins = new Set<PbMixin>(); 244 var mixins = new Set<PbMixin>();
(...skipping 16 matching lines...) Expand all
303 imports[imp].sort(); 261 imports[imp].sort();
304 } 262 }
305 263
306 return imports; 264 return imports;
307 } 265 }
308 266
309 /// Returns the contents of the .pbenum.dart file for this .proto file. 267 /// Returns the contents of the .pbenum.dart file for this .proto file.
310 String generateEnumFile( 268 String generateEnumFile(
311 [OutputConfiguration config = const DefaultOutputConfiguration()]) { 269 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
312 if (!_linked) throw new StateError("not linked"); 270 if (!_linked) throw new StateError("not linked");
313 Uri filePath = new Uri.file(_fileDescriptor.name);
314 if (filePath.isAbsolute) {
315 // protoc should never generate a file descriptor with an absolute path.
316 throw "FAILURE: File with an absolute path is not supported";
317 }
318 271
319 var baseLibraryName = _generateLibraryName(filePath);
320 var libraryName = baseLibraryName + "_pbenum";
321 var out = new IndentingWriter(); 272 var out = new IndentingWriter();
322 out.print(''' 273 _writeLibraryHeading(out, "pbenum");
323 ///
324 // Generated code. Do not modify.
325 ///
326 library $libraryName;
327
328 ''');
329 274
330 if (enumCount > 0) { 275 if (enumCount > 0) {
331 out.println("import 'package:protobuf/protobuf.dart';"); 276 out.println("import 'package:protobuf/protobuf.dart';");
332 out.println(); 277 out.println();
333 } 278 }
334 279
335 for (EnumGenerator e in enumGenerators) { 280 for (EnumGenerator e in enumGenerators) {
336 e.generate(out); 281 e.generate(out);
337 } 282 }
338 283
339 for (MessageGenerator m in messageGenerators) { 284 for (MessageGenerator m in messageGenerators) {
340 m.generateEnums(out); 285 m.generateEnums(out);
341 } 286 }
342 287
343 return out.toString(); 288 return out.toString();
344 } 289 }
345 290
346 /// Returns the number of enum types generated in the .pbenum.dart file. 291 /// Returns the number of enum types generated in the .pbenum.dart file.
347 int get enumCount { 292 int get enumCount {
348 var count = enumGenerators.length; 293 var count = enumGenerators.length;
349 for (MessageGenerator m in messageGenerators) { 294 for (MessageGenerator m in messageGenerators) {
350 count += m.enumCount; 295 count += m.enumCount;
351 } 296 }
352 return count; 297 return count;
353 } 298 }
354 299
300 /// Returns the contents of the .pbserver.dart file for this .proto file.
301 String generateServerFile(
302 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
303 if (!_linked) throw new StateError("not linked");
304 var out = new IndentingWriter();
305 _writeLibraryHeading(out, "pbserver");
306
307 if (serviceGenerators.isNotEmpty) {
308 out.println('''
309 import 'dart:async';
310
311 import 'package:protobuf/protobuf.dart';
312 ''');
313 }
314
315 // Import .pb.dart files needed for requests and responses.
316 var imports = new Set<FileGenerator>();
317 for (var x in serviceGenerators) {
318 x.addImportsTo(imports);
319 }
320 for (var target in imports) {
321 _writeImport(out, config, target, ".pb.dart");
322 }
323 if (imports.isNotEmpty) out.println();
324
325 // Import .pbjson.dart file needed for $json and $messageJson.
326 if (serviceGenerators.isNotEmpty) {
327 _writeImport(out, config, this, ".pbjson.dart");
328 out.println();
329 }
330
331 for (ServiceGenerator s in serviceGenerators) {
332 s.generate(out);
333 }
334
335 return out.toString();
336 }
337
355 /// Returns the contents of the .pbjson.dart file for this .proto file. 338 /// Returns the contents of the .pbjson.dart file for this .proto file.
356 String generateJsonFile( 339 String generateJsonFile(
357 [OutputConfiguration config = const DefaultOutputConfiguration()]) { 340 [OutputConfiguration config = const DefaultOutputConfiguration()]) {
358 if (!_linked) throw new StateError("not linked"); 341 if (!_linked) throw new StateError("not linked");
359 Uri filePath = new Uri.file(_fileDescriptor.name);
360 if (filePath.isAbsolute) {
361 // protoc should never generate a file descriptor with an absolute path.
362 throw "FAILURE: File with an absolute path is not supported";
363 }
364
365 var baseLibraryName = _generateLibraryName(filePath);
366 var libraryName = baseLibraryName + "_pbjson";
367 var out = new IndentingWriter(); 342 var out = new IndentingWriter();
368 out.print(''' 343 _writeLibraryHeading(out, "pbjson");
369 ///
370 // Generated code. Do not modify.
371 ///
372 library $libraryName;
373
374 ''');
375 344
376 // Import the .pbjson.dart files we depend on. 345 // Import the .pbjson.dart files we depend on.
377 var importList = _findJsonProtosToImport(); 346 var imports = _findJsonProtosToImport();
378 for (var imported in importList) { 347 for (var target in imports) {
379 Uri resolvedImport = config.resolveImport( 348 _writeImport(out, config, target, ".pbjson.dart");
380 imported.protoFileUri, protoFileUri, ".pbjson.dart");
381 out.print("import '$resolvedImport'");
382 if (package != imported.package && imported.package.isNotEmpty) {
383 out.print(' as ${imported.packageImportPrefix}');
384 }
385 out.println(';');
386 } 349 }
387 if (importList.isNotEmpty) out.println(); 350 if (imports.isNotEmpty) out.println();
388 351
389 for (var e in enumGenerators) { 352 for (var e in enumGenerators) {
390 e.generateConstants(out); 353 e.generateConstants(out);
391 } 354 }
392 for (MessageGenerator m in messageGenerators) { 355 for (MessageGenerator m in messageGenerators) {
393 m.generateConstants(out); 356 m.generateConstants(out);
394 } 357 }
395 for (ServiceGenerator s in serviceGenerators) { 358 for (ServiceGenerator s in serviceGenerators) {
396 s.generateConstants(out); 359 s.generateConstants(out);
397 } 360 }
(...skipping 10 matching lines...) Expand all
408 } 371 }
409 for (var x in extensionGenerators) { 372 for (var x in extensionGenerators) {
410 x.addConstantImportsTo(imports); 373 x.addConstantImportsTo(imports);
411 } 374 }
412 for (var x in serviceGenerators) { 375 for (var x in serviceGenerators) {
413 x.addConstantImportsTo(imports); 376 x.addConstantImportsTo(imports);
414 } 377 }
415 imports.remove(this); // Don't need to import self. 378 imports.remove(this); // Don't need to import self.
416 return imports; 379 return imports;
417 } 380 }
381
382 /// Writes the library name at the top of the dart file.
383 ///
384 /// (This should be unique to avoid warnings about duplicate Dart libraries.)
385 void _writeLibraryHeading(IndentingWriter out, [String extension]) {
386 Uri filePath = new Uri.file(_fileDescriptor.name);
387 if (filePath.isAbsolute) {
388 // protoc should never generate a file descriptor with an absolute path.
389 throw "FAILURE: File with an absolute path is not supported";
390 }
391
392 var libraryName = _fileNameWithoutExtension(filePath).replaceAll('-', '_');
393 if (extension != null) libraryName += "_$extension";
394 if (_fileDescriptor.package != '') {
395 // Two .protos can be in the same proto package.
396 // It isn't unique enough to use as a Dart library name.
397 // But we can prepend it.
398 libraryName = _fileDescriptor.package + "_" + libraryName;
399 }
400 out.println('''
401 ///
402 // Generated code. Do not modify.
403 ///
404 library $libraryName;
405 ''');
406 }
407
408 /// Writes an import of a .dart file corresponding to a .proto file.
409 /// (Possibly the same .proto file.)
410 void _writeImport(IndentingWriter out, OutputConfiguration config,
411 FileGenerator target, String extension) {
412 Uri resolvedImport =
413 config.resolveImport(target.protoFileUri, protoFileUri, extension);
414 out.print("import '$resolvedImport'");
415 if (package != target.package && target.package.isNotEmpty) {
416 out.print(' as ${target.packageImportPrefix}');
417 }
418 out.println(';');
419 }
418 } 420 }
OLDNEW
« no previous file with comments | « Makefile ('k') | pubspec.yaml » ('j') | test/file_generator_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698