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 extends ProtobufContainer { | 7 class FileGenerator extends 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 21 matching lines...) Expand all Loading... |
32 String get classname => ''; | 32 String get classname => ''; |
33 String get fqname => '.${_fileDescriptor.package}'; | 33 String get fqname => '.${_fileDescriptor.package}'; |
34 | 34 |
35 // Extract the filename from a URI and remove the extension. | 35 // Extract the filename from a URI and remove the extension. |
36 String _fileNameWithoutExtension(Uri filePath) { | 36 String _fileNameWithoutExtension(Uri filePath) { |
37 String fileName = filePath.pathSegments.last; | 37 String fileName = filePath.pathSegments.last; |
38 int index = fileName.lastIndexOf("."); | 38 int index = fileName.lastIndexOf("."); |
39 return index == -1 ? fileName : fileName.substring(0, index); | 39 return index == -1 ? fileName : fileName.substring(0, index); |
40 } | 40 } |
41 | 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"; | |
46 return protoFilePath.resolve(dartFileName); | |
47 } | |
48 | |
49 String _generateClassName(Uri protoFilePath) { | 42 String _generateClassName(Uri protoFilePath) { |
50 String s = _fileNameWithoutExtension(protoFilePath).replaceAll('-', '_'); | 43 String s = _fileNameWithoutExtension(protoFilePath).replaceAll('-', '_'); |
51 return '${s[0].toUpperCase()}${s.substring(1)}'; | 44 return '${s[0].toUpperCase()}${s.substring(1)}'; |
52 } | 45 } |
53 | 46 |
54 String _generateLibraryName(Uri protoFilePath) { | 47 String _generateLibraryName(Uri protoFilePath) { |
55 if (_fileDescriptor.package != '') return _fileDescriptor.package; | 48 if (_fileDescriptor.package != '') return _fileDescriptor.package; |
56 return _fileNameWithoutExtension(protoFilePath).replaceAll('-', '_'); | 49 return _fileNameWithoutExtension(protoFilePath).replaceAll('-', '_'); |
57 } | 50 } |
58 | 51 |
59 Uri _relative(Uri target, Uri base) { | |
60 // Ignore the last segment of the base. | |
61 List<String> baseSegments = | |
62 base.pathSegments.sublist(0, base.pathSegments.length - 1); | |
63 List<String> targetSegments = target.pathSegments; | |
64 if (baseSegments.length == 1 && baseSegments[0] == '.') { | |
65 baseSegments = []; | |
66 } | |
67 if (targetSegments.length == 1 && targetSegments[0] == '.') { | |
68 targetSegments = []; | |
69 } | |
70 int common = 0; | |
71 int length = min(targetSegments.length, baseSegments.length); | |
72 while (common < length && targetSegments[common] == baseSegments[common]) { | |
73 common++; | |
74 } | |
75 | |
76 final segments = <String>[]; | |
77 if (common < baseSegments.length && baseSegments[common] == '..') { | |
78 throw new ArgumentError( | |
79 "Cannot create a relative path from $base to $target"); | |
80 } | |
81 for (int i = common; i < baseSegments.length; i++) { | |
82 segments.add('..'); | |
83 } | |
84 for (int i = common; i < targetSegments.length; i++) { | |
85 segments.add('${targetSegments[i]}'); | |
86 } | |
87 if (segments.isEmpty) { | |
88 segments.add('.'); | |
89 } | |
90 return new Uri(pathSegments: segments); | |
91 } | |
92 | |
93 CodeGeneratorResponse_File generateResponse() { | 52 CodeGeneratorResponse_File generateResponse() { |
94 MemoryWriter writer = new MemoryWriter(); | 53 MemoryWriter writer = new MemoryWriter(); |
95 IndentingWriter out = new IndentingWriter(' ', writer); | 54 IndentingWriter out = new IndentingWriter(' ', writer); |
96 | 55 |
97 generate(out); | 56 generate(out); |
98 | 57 |
99 Uri filePath = new Uri(scheme: 'file', path: _fileDescriptor.name); | 58 Uri filePath = new Uri.file(_fileDescriptor.name); |
100 return new CodeGeneratorResponse_File() | 59 return new CodeGeneratorResponse_File() |
101 ..name = _generatedFilePath(filePath).path | 60 ..name = _context.outputConfiguration.outputPathFor(filePath).path |
102 ..content = writer.toString(); | 61 ..content = writer.toString(); |
103 } | 62 } |
104 | 63 |
105 void generate(IndentingWriter out) { | 64 void generate(IndentingWriter out) { |
106 Uri filePath = new Uri.file(_fileDescriptor.name); | 65 Uri filePath = new Uri.file(_fileDescriptor.name); |
107 if (filePath.isAbsolute) { | 66 if (filePath.isAbsolute) { |
108 // protoc should never generate a file descriptor with an absolute path. | 67 // protoc should never generate a file descriptor with an absolute path. |
109 throw("FAILURE: File with an absolute path is not supported"); | 68 throw("FAILURE: File with an absolute path is not supported"); |
110 } | 69 } |
111 | 70 |
112 String libraryName = _generateLibraryName(filePath); | 71 String libraryName = _generateLibraryName(filePath); |
113 | 72 |
114 out.println( | 73 out.println( |
115 '///\n' | 74 '///\n' |
116 '// Generated code. Do not modify.\n' | 75 '// Generated code. Do not modify.\n' |
117 '///\n' | 76 '///\n' |
118 'library $libraryName;\n' | 77 'library $libraryName;\n' |
119 '\n' | 78 '\n' |
120 "import 'package:fixnum/fixnum.dart';\n" | 79 "import 'package:fixnum/fixnum.dart';\n" |
121 "import 'package:protobuf/protobuf.dart';" | 80 "import 'package:protobuf/protobuf.dart';" |
122 ); | 81 ); |
123 | 82 |
124 for (String import in _fileDescriptor.dependency) { | 83 for (String import in _fileDescriptor.dependency) { |
125 Uri importPath = new Uri.file(import); | 84 Uri importPath = new Uri.file(import); |
126 if (importPath.isAbsolute) { | 85 if (importPath.isAbsolute) { |
127 // protoc should never generate an import with an absolute path. | 86 // protoc should never generate an import with an absolute path. |
128 throw("FAILURE: Import with absolute path is not supported"); | 87 throw("FAILURE: Import with absolute path is not supported"); |
129 } | 88 } |
130 // Create a relative path from the current file to the import. | 89 // Create a path from the current file to the imported proto. |
131 Uri relativeProtoPath = _relative(importPath, filePath); | 90 Uri resolvedImport = _context.outputConfiguration.resolveImport( |
| 91 importPath, filePath); |
132 // Find the file generator for this import as it contains the | 92 // Find the file generator for this import as it contains the |
133 // package name. | 93 // package name. |
134 FileGenerator fileGenerator = _context.lookupFile(import); | 94 FileGenerator fileGenerator = _context.lookupFile(import); |
135 out.print("import '${_generatedFilePath(relativeProtoPath)}'"); | 95 out.print("import '$resolvedImport'"); |
136 if (package != fileGenerator.package && !fileGenerator.package.isEmpty) { | 96 if (package != fileGenerator.package && !fileGenerator.package.isEmpty) { |
137 out.print(' as ${fileGenerator.packageImportPrefix}'); | 97 out.print(' as ${fileGenerator.packageImportPrefix}'); |
138 } | 98 } |
139 out.println(';'); | 99 out.println(';'); |
140 } | 100 } |
141 out.println(''); | 101 out.println(''); |
142 | 102 |
143 // Initialize Field. | 103 // Initialize Field. |
144 for (MessageGenerator m in messageGenerators) { | 104 for (MessageGenerator m in messageGenerators) { |
145 m.initializeFields(); | 105 m.initializeFields(); |
(...skipping 22 matching lines...) Expand all Loading... |
168 out.println(' registry.add(${x.name});'); | 128 out.println(' registry.add(${x.name});'); |
169 } | 129 } |
170 out.println('}'); | 130 out.println('}'); |
171 }); | 131 }); |
172 } | 132 } |
173 } | 133 } |
174 } | 134 } |
175 | 135 |
176 class GenerationContext { | 136 class GenerationContext { |
177 final GenerationOptions options; | 137 final GenerationOptions options; |
| 138 final OutputConfiguration outputConfiguration; |
178 final Map<String, ProtobufContainer> _registry = | 139 final Map<String, ProtobufContainer> _registry = |
179 <String, ProtobufContainer>{}; | 140 <String, ProtobufContainer>{}; |
180 final Map<String, FileGenerator> _files = | 141 final Map<String, FileGenerator> _files = |
181 <String, FileGenerator>{}; | 142 <String, FileGenerator>{}; |
182 | 143 |
183 GenerationContext(this.options); | 144 GenerationContext(this.options, this.outputConfiguration); |
184 | 145 |
185 void register(ProtobufContainer container) { | 146 void register(ProtobufContainer container) { |
186 _registry[container.fqname] = container; | 147 _registry[container.fqname] = container; |
187 if (container is FileGenerator) { | 148 if (container is FileGenerator) { |
188 _files[container._fileDescriptor.name] = container; | 149 _files[container._fileDescriptor.name] = container; |
189 } | 150 } |
190 } | 151 } |
191 | 152 |
192 ProtobufContainer operator [](String fqname) => _registry[fqname]; | 153 ProtobufContainer operator [](String fqname) => _registry[fqname]; |
193 | 154 |
194 FileGenerator lookupFile(String name) => _files[name]; | 155 FileGenerator lookupFile(String name) => _files[name]; |
195 } | 156 } |
OLD | NEW |