OLD | NEW |
---|---|
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 class FileGenerator implements ProtobufContainer { | 7 class FileGenerator implements ProtobufContainer { |
8 final FileDescriptorProto _fileDescriptor; | 8 final FileDescriptorProto _fileDescriptor; |
9 final ProtobufContainer _parent; | 9 final ProtobufContainer _parent; |
10 final GenerationContext _context; | 10 final GenerationContext _context; |
(...skipping 14 matching lines...) Expand all Loading... | |
25 for (FieldDescriptorProto extension in _fileDescriptor.extension) { | 25 for (FieldDescriptorProto extension in _fileDescriptor.extension) { |
26 extensionGenerators.add( | 26 extensionGenerators.add( |
27 new ExtensionGenerator(extension, this, _context)); | 27 new ExtensionGenerator(extension, this, _context)); |
28 } | 28 } |
29 } | 29 } |
30 | 30 |
31 String get classname => ''; | 31 String get classname => ''; |
32 String get fqname => _fileDescriptor.package == null | 32 String get fqname => _fileDescriptor.package == null |
33 ? '' : '.${_fileDescriptor.package}'; | 33 ? '' : '.${_fileDescriptor.package}'; |
34 | 34 |
35 _generatedFilePath(Path path) { | 35 // Extract the filename from a URI and remove the extension. |
36 Path withoutExtension = path.directoryPath | 36 String _fileNameWithoutExtension(Uri filePath) { |
37 .join(new Path(path.filenameWithoutExtension)); | 37 String fileName = filePath.pathSegments.last; |
38 return '${withoutExtension.toNativePath()}.pb.dart'; | 38 int index = fileName.lastIndexOf("."); |
39 return index == -1 ? fileName : fileName.substring(0, index); | |
40 } | |
41 | |
42 // Create the URI for the generated Dart file from the URI of the | |
43 // .proto file. | |
44 Uri _generatedFilePath(Uri protoFilePath) { | |
45 var dartFileName = _fileNameWithoutExtension(protoFilePath) + ".pb.dart"; | |
Anton Muhin
2013/09/02 09:26:10
nit: mix of ' and "
Anton Muhin
2013/09/02 09:26:10
nit: I'd rather use interpolation, but completely
| |
46 return protoFilePath.resolve(dartFileName); | |
47 } | |
48 | |
49 String _generateClassName(Uri protoFilePath) { | |
50 String s = _fileNameWithoutExtension(protoFilePath).replaceAll('-', '_'); | |
51 return '${s[0].toUpperCase()}${s.substring(1)}'; | |
52 } | |
53 | |
54 Uri _relative(Uri target, Uri base) { | |
Siggi Cherem (dart-lang)
2013/08/19 16:44:48
could we instead depend on the path package and us
Søren Gjesse
2013/08/20 07:35:33
I would rather not rely on other packages in the p
Siggi Cherem (dart-lang)
2013/08/20 17:42:48
Sounds good, especially since this should be going
| |
55 // Ignore the last segment of the base. | |
56 List<String> baseSegments = | |
Anton Muhin
2013/09/02 09:26:10
absolutely up to you, but I rather use new List<St
| |
57 base.pathSegments.sublist(0, base.pathSegments.length - 1); | |
58 List<String> targetSegments = target.pathSegments; | |
59 if (baseSegments.length == 1 && baseSegments[0] == '.') { | |
Anton Muhin
2013/09/02 09:26:10
what if baseSegments is [ '.', '.', '.' ] or alike
| |
60 baseSegments = []; | |
61 } | |
62 if (targetSegments.length == 1 && targetSegments[0] == '.') { | |
63 targetSegments = []; | |
64 } | |
65 int common = 0; | |
66 int length = min(targetSegments.length, baseSegments.length); | |
67 while (common < length && targetSegments[common] == baseSegments[common]) { | |
68 common++; | |
69 } | |
70 | |
71 final segments = <String>[]; | |
72 if (common < baseSegments.length && baseSegments[common] == '..') { | |
73 throw new ArgumentError( | |
74 "Cannot create a relative path from $base to $target"); | |
75 } | |
76 for (int i = common; i < baseSegments.length; i++) { | |
77 segments.add('..'); | |
78 } | |
79 for (int i = common; i < targetSegments.length; i++) { | |
80 segments.add('${targetSegments[i]}'); | |
81 } | |
82 if (segments.isEmpty) { | |
83 segments.add('.'); | |
84 } | |
85 return new Uri(pathSegments: segments); | |
39 } | 86 } |
40 | 87 |
41 CodeGeneratorResponse_File generateResponse() { | 88 CodeGeneratorResponse_File generateResponse() { |
42 MemoryWriter writer = new MemoryWriter(); | 89 MemoryWriter writer = new MemoryWriter(); |
43 IndentingWriter out = new IndentingWriter(' ', writer); | 90 IndentingWriter out = new IndentingWriter(' ', writer); |
44 | 91 |
45 generate(out); | 92 generate(out); |
46 | 93 |
47 Path filePath = new Path(_fileDescriptor.name); | 94 Uri filePath = new Uri(scheme: 'file', path: _fileDescriptor.name); |
48 return new CodeGeneratorResponse_File() | 95 return new CodeGeneratorResponse_File() |
49 ..name = _generatedFilePath(filePath) | 96 ..name = _generatedFilePath(filePath).path |
50 ..content = writer.toString(); | 97 ..content = writer.toString(); |
51 } | 98 } |
52 | 99 |
53 void generate(IndentingWriter out) { | 100 void generate(IndentingWriter out) { |
101 Uri filePath = new Uri.file(_fileDescriptor.name); | |
102 if (filePath.isAbsolute) { | |
103 // protoc should never generate an file descriptor an absolute path. | |
104 throw("FAILURE: file with absolute path is not supported"); | |
105 } | |
54 | 106 |
55 Path filePath = new Path(_fileDescriptor.name); | 107 String className = _generateClassName(filePath); |
56 Path directoryPath = filePath.directoryPath.canonicalize(); | |
57 | |
58 String className = filePath.filenameWithoutExtension.replaceAll('-', '_'); | |
59 className = '${className[0].toUpperCase()}${className.substring(1)}'; | |
60 | 108 |
61 String libraryName = className + '.pb'; | 109 String libraryName = className + '.pb'; |
62 | 110 |
63 out.println( | 111 out.println( |
64 '///\n' | 112 '///\n' |
65 '// Generated code. Do not modify.\n' | 113 '// Generated code. Do not modify.\n' |
66 '///\n' | 114 '///\n' |
67 'library $libraryName;\n' | 115 'library $libraryName;\n' |
68 '\n' | 116 '\n' |
69 "import 'dart:typed_data';\n\n" | 117 "import 'dart:typed_data';\n\n" |
70 "import 'package:protobuf/protobuf.dart';" | 118 "import 'package:protobuf/protobuf.dart';" |
71 ); | 119 ); |
72 | 120 |
73 for (String import in _fileDescriptor.dependency) { | 121 for (String import in _fileDescriptor.dependency) { |
74 Path relativeProtoPath = | 122 Uri importPath = new Uri.file(import); |
75 new Path(import).relativeTo(directoryPath).canonicalize(); | 123 if (importPath.isAbsolute) { |
124 // protoc should never generate an import with an absolute path. | |
125 throw("FAILURE: Import with absolute path is not supported"); | |
Anton Muhin
2013/09/02 09:26:10
nit: mix of ' and "
| |
126 } | |
127 // Create a relative path from the current file to the import. | |
128 Uri relativeProtoPath = _relative(importPath, filePath); | |
Siggi Cherem (dart-lang)
2013/08/19 16:44:48
What do imports look like in the descriptor? Are t
Søren Gjesse
2013/08/20 07:35:33
The imports in the descriptor are the literal stri
Siggi Cherem (dart-lang)
2013/08/20 17:42:48
I see, thanks.
In the future we might want to sta
| |
76 out.println("import '${_generatedFilePath(relativeProtoPath)}';"); | 129 out.println("import '${_generatedFilePath(relativeProtoPath)}';"); |
77 } | 130 } |
78 out.println(''); | 131 out.println(''); |
79 | 132 |
80 // Initialize Field. | 133 // Initialize Field. |
81 for (MessageGenerator m in messageGenerators) { | 134 for (MessageGenerator m in messageGenerators) { |
82 m.initializeFields(); | 135 m.initializeFields(); |
83 } | 136 } |
84 | 137 |
85 // Generate code. | 138 // Generate code. |
(...skipping 29 matching lines...) Expand all Loading... | |
115 <String, ProtobufContainer>{}; | 168 <String, ProtobufContainer>{}; |
116 | 169 |
117 GenerationContext(this.options); | 170 GenerationContext(this.options); |
118 | 171 |
119 void register(ProtobufContainer container) { | 172 void register(ProtobufContainer container) { |
120 _registry[container.fqname] = container; | 173 _registry[container.fqname] = container; |
121 } | 174 } |
122 | 175 |
123 ProtobufContainer operator [](String fqname) => _registry[fqname]; | 176 ProtobufContainer operator [](String fqname) => _registry[fqname]; |
124 } | 177 } |
OLD | NEW |