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 // This should match the extension in dart_options.proto. | |
9 static const int implementMapByDefaultOption = 95333044; | |
10 | 8 |
11 // Returns true if option implement_map_by_default is on for this file. | 9 /// Returns the the mixin to use by default in this file, |
12 static bool _shouldImplementMapByDefault(FileDescriptorProto desc) { | 10 /// or null for no mixin by default. |
13 if (!desc.hasOptions()) return false; | 11 static PbMixin _getDefaultMixin(FileDescriptorProto desc) { |
14 | 12 if (!desc.hasOptions()) return null; |
15 var val = desc.options.unknownFields.getField(implementMapByDefaultOption); | 13 if (!desc.options.hasExtension(Dart_options.defaultMixin)) { |
16 if (val == null || val.length != 1) return false; | 14 return null; |
17 | 15 } |
18 return val.values[0] == 1; | 16 var name = desc.options.getExtension(Dart_options.defaultMixin); |
17 PbMixin mixin = findMixin(name); | |
18 if (mixin == null) { | |
19 throw("unknown mixin class: ${name}"); | |
20 } | |
21 return mixin; | |
19 } | 22 } |
20 | 23 |
21 final FileDescriptorProto _fileDescriptor; | 24 final FileDescriptorProto _fileDescriptor; |
22 final ProtobufContainer _parent; | 25 final ProtobufContainer _parent; |
23 final GenerationContext _context; | 26 final GenerationContext _context; |
24 | 27 |
25 final List<EnumGenerator> enumGenerators = <EnumGenerator>[]; | 28 final List<EnumGenerator> enumGenerators = <EnumGenerator>[]; |
26 final List<MessageGenerator> messageGenerators = <MessageGenerator>[]; | 29 final List<MessageGenerator> messageGenerators = <MessageGenerator>[]; |
27 final List<ExtensionGenerator> extensionGenerators = <ExtensionGenerator>[]; | 30 final List<ExtensionGenerator> extensionGenerators = <ExtensionGenerator>[]; |
28 | 31 |
29 FileGenerator(this._fileDescriptor, this._parent, this._context) { | 32 FileGenerator(this._fileDescriptor, this._parent, this._context) { |
30 _context.register(this); | 33 _context.register(this); |
31 | 34 |
32 bool implementMap = _shouldImplementMapByDefault(_fileDescriptor); | 35 var defaultMixin = _getDefaultMixin(_fileDescriptor); |
33 | 36 |
34 // Load and register all enum and message types. | 37 // Load and register all enum and message types. |
35 for (EnumDescriptorProto enumType in _fileDescriptor.enumType) { | 38 for (EnumDescriptorProto enumType in _fileDescriptor.enumType) { |
36 enumGenerators.add(new EnumGenerator(enumType, this, _context)); | 39 enumGenerators.add(new EnumGenerator(enumType, this, _context)); |
37 } | 40 } |
38 for (DescriptorProto messageType in _fileDescriptor.messageType) { | 41 for (DescriptorProto messageType in _fileDescriptor.messageType) { |
39 messageGenerators.add( | 42 messageGenerators.add( |
40 new MessageGenerator(messageType, this, _context, implementMap)); | 43 new MessageGenerator(messageType, this, _context, defaultMixin)); |
41 } | 44 } |
42 for (FieldDescriptorProto extension in _fileDescriptor.extension) { | 45 for (FieldDescriptorProto extension in _fileDescriptor.extension) { |
43 extensionGenerators.add( | 46 extensionGenerators.add( |
44 new ExtensionGenerator(extension, this, _context)); | 47 new ExtensionGenerator(extension, this, _context)); |
45 } | 48 } |
46 } | 49 } |
47 | 50 |
48 String get package => _fileDescriptor.package; | 51 String get package => _fileDescriptor.package; |
49 String get classname => ''; | 52 String get classname => ''; |
50 String get fqname => '.${_fileDescriptor.package}'; | 53 String get fqname => '.${_fileDescriptor.package}'; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 out.println( | 93 out.println( |
91 '///\n' | 94 '///\n' |
92 '// Generated code. Do not modify.\n' | 95 '// Generated code. Do not modify.\n' |
93 '///\n' | 96 '///\n' |
94 'library $libraryName;\n' | 97 'library $libraryName;\n' |
95 '\n' | 98 '\n' |
96 "import 'package:fixnum/fixnum.dart';\n" | 99 "import 'package:fixnum/fixnum.dart';\n" |
97 "import 'package:protobuf/protobuf.dart';" | 100 "import 'package:protobuf/protobuf.dart';" |
98 ); | 101 ); |
99 | 102 |
100 if (needsMapMixinImport) { | 103 var mixinImports = findMixinsToImport(); |
101 out.println("import 'dart:collection' show MapMixin;"); | 104 var importNames = mixinImports.keys.toList(); |
105 importNames.sort(); | |
106 for (var imp in importNames) { | |
107 var symbols = mixinImports[imp]; | |
108 out.println("import '${imp}' show ${symbols.join(', ')};"); | |
Søren Gjesse
2015/06/23 06:43:33
This import could cause name-clashes. Should these
skybrian
2015/06/23 17:32:42
It's a good point but I'm going to defer this, sin
Søren Gjesse
2015/06/24 07:11:27
Please file an issue on this.
| |
102 } | 109 } |
103 | 110 |
104 for (String import in _fileDescriptor.dependency) { | 111 for (String import in _fileDescriptor.dependency) { |
105 Uri importPath = new Uri.file(import); | 112 Uri importPath = new Uri.file(import); |
106 if (importPath.isAbsolute) { | 113 if (importPath.isAbsolute) { |
107 // protoc should never generate an import with an absolute path. | 114 // protoc should never generate an import with an absolute path. |
108 throw("FAILURE: Import with absolute path is not supported"); | 115 throw("FAILURE: Import with absolute path is not supported"); |
109 } | 116 } |
110 // Create a path from the current file to the imported proto. | 117 // Create a path from the current file to the imported proto. |
111 Uri resolvedImport = _context.outputConfiguration.resolveImport( | 118 Uri resolvedImport = _context.outputConfiguration.resolveImport( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 out.println('static void registerAllExtensions(ExtensionRegistry ' | 153 out.println('static void registerAllExtensions(ExtensionRegistry ' |
147 'registry) {'); | 154 'registry) {'); |
148 for (ExtensionGenerator x in extensionGenerators) { | 155 for (ExtensionGenerator x in extensionGenerators) { |
149 out.println(' registry.add(${x.name});'); | 156 out.println(' registry.add(${x.name});'); |
150 } | 157 } |
151 out.println('}'); | 158 out.println('}'); |
152 }); | 159 }); |
153 } | 160 } |
154 } | 161 } |
155 | 162 |
156 bool get needsMapMixinImport { | 163 /// Returns a map from import names to the Dart symbols to be imported. |
157 for (var m in messageGenerators) { | 164 Map<String, List<String>> findMixinsToImport() { |
158 if (m.needsMapMixinImport) { | 165 var mixins = new Set<PbMixin>(); |
159 return true; | 166 for (MessageGenerator m in messageGenerators) { |
160 } | 167 m.addMixinsTo(mixins); |
161 } | 168 } |
162 return false; | 169 |
170 var imports = {}; | |
171 for (var m in mixins) { | |
172 var imp = m.importFrom; | |
173 List<String> symbols = imports[imp]; | |
174 if (symbols == null) { | |
175 symbols = []; | |
176 imports[imp] = symbols; | |
177 } | |
178 symbols.add(m.name); | |
179 } | |
180 | |
181 for (var imp in imports.keys) { | |
182 imports[imp].sort(); | |
183 } | |
184 | |
185 return imports; | |
163 } | 186 } |
164 } | 187 } |
165 | 188 |
166 class GenerationContext { | 189 class GenerationContext { |
167 final GenerationOptions options; | 190 final GenerationOptions options; |
168 final OutputConfiguration outputConfiguration; | 191 final OutputConfiguration outputConfiguration; |
169 final Map<String, ProtobufContainer> _registry = | 192 final Map<String, ProtobufContainer> _registry = |
170 <String, ProtobufContainer>{}; | 193 <String, ProtobufContainer>{}; |
171 final Map<String, FileGenerator> _files = | 194 final Map<String, FileGenerator> _files = |
172 <String, FileGenerator>{}; | 195 <String, FileGenerator>{}; |
173 | 196 |
174 GenerationContext(this.options, this.outputConfiguration); | 197 GenerationContext(this.options, this.outputConfiguration); |
175 | 198 |
176 void register(ProtobufContainer container) { | 199 void register(ProtobufContainer container) { |
177 _registry[container.fqname] = container; | 200 _registry[container.fqname] = container; |
178 if (container is FileGenerator) { | 201 if (container is FileGenerator) { |
179 _files[container._fileDescriptor.name] = container; | 202 _files[container._fileDescriptor.name] = container; |
180 } | 203 } |
181 } | 204 } |
182 | 205 |
183 ProtobufContainer operator [](String fqname) => _registry[fqname]; | 206 ProtobufContainer operator [](String fqname) => _registry[fqname]; |
184 | 207 |
185 FileGenerator lookupFile(String name) => _files[name]; | 208 FileGenerator lookupFile(String name) => _files[name]; |
186 } | 209 } |
OLD | NEW |