Chromium Code Reviews| 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 |