Sync internal changes (#123)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7edb27f..b3faaa9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.10.1
+
+* Breaking change: Prefix generated Dart proto imports by proto file path instead of by package.
+  Tighten up member name checks for generated enum classes.
+  Requires package:protobuf version 0.10.2 or newer.
+
 ## 0.10.0
 
 * Breaking change: Support for [any](https://developers.google.com/protocol-buffers/docs/proto3#any) messages.
diff --git a/lib/base_type.dart b/lib/base_type.dart
index 743bd86..028543c 100644
--- a/lib/base_type.dart
+++ b/lib/base_type.dart
@@ -37,23 +37,23 @@
   /// (Always the empty string for primitive types.)
   String get package => generator == null ? "" : generator.package;
 
-  /// The Dart expression to use for this type when in a different package.
-  String get prefixed {
-    if (generator == null || generator.packageImportPrefix.isEmpty) {
-      return unprefixed;
-    }
-    return generator.packageImportPrefix + "." + unprefixed;
-  }
+  /// The Dart expression to use for this type when in a different file.
+  String get prefixed => generator == null
+      ? unprefixed
+      : generator.fileImportPrefix + "." + unprefixed;
 
   /// Returns the name to use in generated code for this Dart type.
   ///
   /// Doesn't include the List type for repeated fields.
-  /// [package] is the current package where we are generating code.
-  /// The Dart class might be imported from a different package.
-  String getDartType(String package) =>
-      (package == this.package) ? unprefixed : prefixed;
+  /// [protoFileUri] represents the current proto file where we are generating
+  /// code. The Dart class might be imported from a different proto file.
+  String getDartType(FileGenerator fileGen) =>
+      (fileGen.protoFileUri == generator?.fileGen?.protoFileUri)
+          ? unprefixed
+          : prefixed;
 
-  String getRepeatedDartType(String package) => "List<${getDartType(package)}>";
+  String getRepeatedDartType(FileGenerator fileGen) =>
+      "List<${getDartType(fileGen)}>";
 
   factory BaseType(FieldDescriptorProto field, GenerationContext ctx) {
     String constSuffix;
diff --git a/lib/code_generator.dart b/lib/code_generator.dart
index 46bf0fa..d5080c9 100644
--- a/lib/code_generator.dart
+++ b/lib/code_generator.dart
@@ -5,6 +5,10 @@
 part of protoc;
 
 abstract class ProtobufContainer {
+  // Internal map of proto file URIs to prefix aliases to resolve name conflicts
+  static final importPrefixes = <String, String>{};
+  static var idx = 0;
+
   String get package;
   String get classname;
   String get fullName;
@@ -14,14 +18,17 @@
   /// This exists because names from protoc come like this.
   String get dottedName => '.$fullName';
 
-  String get packageImportPrefix =>
-      _cachedImportPrefix ??= _calculateImportPrefix();
+  String get fileImportPrefix => _getFileImportPrefix();
 
-  String _cachedImportPrefix;
-
-  String _calculateImportPrefix() {
-    final importName = package.replaceAll('.', r'$');
-    return importName.isNotEmpty ? '\$$importName' : '';
+  String _getFileImportPrefix() {
+    String path = fileGen.protoFileUri.toString();
+    if (importPrefixes.containsKey(path)) {
+      return importPrefixes[path];
+    }
+    final alias = '\$$idx';
+    importPrefixes[path] = alias;
+    idx++;
+    return alias;
   }
 
   /// The generator of the .pb.dart file defining this entity.
diff --git a/lib/enum_generator.dart b/lib/enum_generator.dart
index cae2e1f..8bd3022 100644
--- a/lib/enum_generator.dart
+++ b/lib/enum_generator.dart
@@ -22,9 +22,8 @@
   EnumGenerator(EnumDescriptorProto descriptor, ProtobufContainer parent)
       : assert(parent != null),
         _parent = parent,
-        classname = (parent is FileGenerator)
-            ? descriptor.name
-            : '${parent.classname}_${descriptor.name}',
+        classname = messageOrEnumClassName(descriptor.name,
+            parent: parent?.classname ?? ''),
         fullName = parent.fullName == ''
             ? descriptor.name
             : '${parent.fullName}.${descriptor.name}',
@@ -52,10 +51,10 @@
   /// [usage] represents the .pb.dart file where the expression will be used.
   String getJsonConstant(FileGenerator usage) {
     var name = "$classname\$json";
-    if (usage.package == fileGen.package || packageImportPrefix.isEmpty) {
+    if (usage.protoFileUri == fileGen.protoFileUri) {
       return name;
     }
-    return "$packageImportPrefix.$name";
+    return "$fileImportPrefix.$name";
   }
 
   void generate(IndentingWriter out) {
@@ -64,14 +63,17 @@
         '}\n', () {
       // -----------------------------------------------------------------
       // Define enum types.
+      var reservedNames = reservedEnumNames;
       for (EnumValueDescriptorProto val in _canonicalValues) {
-        out.println('static const ${classname} ${val.name} = '
-            "const ${classname}._(${val.number}, '${val.name}');");
+        final name = unusedEnumNames(val.name, reservedNames);
+        out.println('static const ${classname} $name = '
+            "const ${classname}._(${val.number}, '$name');");
       }
       if (!_aliases.isEmpty) {
         out.println();
         for (EnumAlias alias in _aliases) {
-          out.println('static const ${classname} ${alias.value.name} ='
+          final name = unusedEnumNames(alias.value.name, reservedNames);
+          out.println('static const ${classname} $name ='
               ' ${alias.canonicalValue.name};');
         }
       }
@@ -79,8 +81,10 @@
 
       out.println('static const List<${classname}> values ='
           ' const <${classname}> [');
+      reservedNames = reservedEnumNames;
       for (EnumValueDescriptorProto val in _canonicalValues) {
-        out.println('  ${val.name},');
+        final name = unusedEnumNames(val.name, reservedNames);
+        out.println('  $name,');
       }
       out.println('];');
       out.println();
diff --git a/lib/extension_generator.dart b/lib/extension_generator.dart
index 784e255..352e0f4 100644
--- a/lib/extension_generator.dart
+++ b/lib/extension_generator.dart
@@ -76,7 +76,7 @@
 
     String name = _extensionName;
     var type = _field.baseType;
-    var dartType = type.getDartType(package);
+    var dartType = type.getDartType(fileGen);
 
     if (_field.isRepeated) {
       out.print('static final $_protobufImportPrefix.Extension $name = '
@@ -98,12 +98,12 @@
         'new $_protobufImportPrefix.Extension<$dartType>(\'$_extendedFullName\', \'$name\', '
         '${_field.number}, ${_field.typeConstant}');
 
-    String initializer = _field.generateDefaultFunction(package);
+    String initializer = _field.generateDefaultFunction(fileGen);
 
     if (type.isMessage || type.isGroup) {
       out.println(', $initializer, $dartType.create);');
     } else if (type.isEnum) {
-      var dartEnum = type.getDartType(package);
+      var dartEnum = type.getDartType(fileGen);
       String enumParams = '(var v) => $dartEnum.valueOf(v), $dartEnum.values';
       out.println(", $initializer, null, $enumParams);");
     } else if (initializer != null) {
diff --git a/lib/file_generator.dart b/lib/file_generator.dart
index 1e1e5b4..eeecdfb 100644
--- a/lib/file_generator.dart
+++ b/lib/file_generator.dart
@@ -511,7 +511,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 ''');
   }
 
@@ -522,8 +522,8 @@
     Uri resolvedImport =
         config.resolveImport(target.protoFileUri, protoFileUri, extension);
     out.print("import '$resolvedImport'");
-    if (package != target.package && target.package.isNotEmpty) {
-      out.print(' as ${target.packageImportPrefix}');
+    if (protoFileUri != target.protoFileUri) {
+      out.print(' as ${target.fileImportPrefix}');
     }
     out.println(';');
   }
diff --git a/lib/grpc_generator.dart b/lib/grpc_generator.dart
index 80b1c62..00aaad9 100644
--- a/lib/grpc_generator.dart
+++ b/lib/grpc_generator.dart
@@ -96,12 +96,11 @@
       // TODO(jakobr): Throw more actionable error.
       throw 'FAILURE: Unknown type reference (${fqname}) for ${location}';
     }
-    if (fileGen.package == mg.fileGen.package || mg.fileGen.package == '') {
-      // It's either the same file, or another file with the same package.
-      // (In the second case, we import it without using "as".)
+    if (fileGen.protoFileUri == mg.fileGen.protoFileUri) {
+      // If it's the same file, we import it without using "as".
       return mg.classname;
     }
-    return mg.packageImportPrefix + '.' + mg.classname;
+    return mg.fileImportPrefix + '.' + mg.classname;
   }
 
   void generate(IndentingWriter out) {
diff --git a/lib/message_generator.dart b/lib/message_generator.dart
index 0f08f25..6341982 100644
--- a/lib/message_generator.dart
+++ b/lib/message_generator.dart
@@ -64,7 +64,8 @@
       Map<String, PbMixin> declaredMixins, PbMixin defaultMixin)
       : _descriptor = descriptor,
         _parent = parent,
-        classname = messageClassName(descriptor, parent: parent.classname),
+        classname = messageOrEnumClassName(descriptor.name,
+            parent: parent?.classname ?? ''),
         assert(parent != null),
         fullName = parent.fullName == ''
             ? descriptor.name
@@ -101,10 +102,10 @@
   /// [usage] represents the .pb.dart file where the expression will be used.
   String getJsonConstant(FileGenerator usage) {
     var name = "$classname\$json";
-    if (usage.package == fileGen.package || packageImportPrefix.isEmpty) {
+    if (usage.protoFileUri == fileGen.protoFileUri) {
       return name;
     }
-    return "$packageImportPrefix.$name";
+    return "$fileImportPrefix.$name";
   }
 
   /// Adds all mixins used in this message and any submessages.
@@ -233,7 +234,7 @@
           ';', () {
         for (ProtobufField field in _fieldList) {
           var dartFieldName = field.memberNames.fieldName;
-          out.println(field.generateBuilderInfoCall(package, dartFieldName));
+          out.println(field.generateBuilderInfoCall(fileGen, dartFieldName));
         }
 
         if (_descriptor.extensionRange.length > 0) {
@@ -375,7 +376,7 @@
 
   void generateFieldAccessorsMutators(
       ProtobufField field, IndentingWriter out) {
-    var fieldTypeString = field.getDartType(package);
+    var fieldTypeString = field.getDartType(fileGen);
     var defaultExpr = field.getDefaultExpr();
     var names = field.memberNames;
 
diff --git a/lib/names.dart b/lib/names.dart
index d472beb..905036a 100644
--- a/lib/names.dart
+++ b/lib/names.dart
@@ -45,7 +45,7 @@
   var existingNames = new Set<String>()
     ..addAll(_dartReservedWords)
     ..addAll(GeneratedMessage_reservedNames)
-    ..addAll(_generatedNames);
+    ..addAll(_generatedMessageNames);
   return _unusedMemberNames(descriptor, null, existingNames).fieldName;
 }
 
@@ -53,7 +53,7 @@
 String extensionClassName(FileDescriptorProto descriptor) {
   var taken = new Set<String>();
   for (var messageType in descriptor.messageType) {
-    taken.add(messageClassName(messageType));
+    taken.add(messageOrEnumClassName(messageType.name));
   }
   for (var enumType in descriptor.enumType) {
     taken.add(enumType.name);
@@ -94,17 +94,19 @@
   String toString() => "$message";
 }
 
-/// Chooses the name of the Dart class to generate for a protobuf message.
+/// Chooses the name of the Dart class to generate for a proto message or enum.
 ///
-/// For a nested message, [parent] should be provided
+/// For a nested message or enum, [parent] should be provided
 /// with the name of the Dart class for the immediate parent.
-String messageClassName(DescriptorProto descriptor, {String parent: ''}) {
-  var name = descriptor.name;
+String messageOrEnumClassName(String descriptorName, {String parent: ''}) {
+  var name = descriptorName;
   if (parent != '') {
-    name = '${parent}_${descriptor.name}';
+    name = '${parent}_${descriptorName}';
   }
   if (name == 'Function') {
     name = 'Function_'; // Avoid reserved word.
+  } else if (name == 'List') {
+    name = 'List_';
   } else if (name.startsWith('Function_')) {
     // Avoid any further name conflicts due to 'Function' rename (unlikely).
     name = name + '_';
@@ -112,6 +114,26 @@
   return name;
 }
 
+/// Returns the set of names reserved by the ProtobufEnum class and its
+/// generated subclasses.
+Set<String> get reservedEnumNames => new Set<String>()
+  ..addAll(ProtobufEnum_reservedNames)
+  ..addAll(_protobufEnumNames);
+
+/// Chooses the ProtobufEnum names for each value.
+///
+/// Since the values all have the same type as the containing enum class, it
+/// does not require all the same checks as for message member names. Still,
+/// it needs to be checked against a list of reserved names to avoid collisions.
+String unusedEnumNames(String name, Set<String> existingNames) {
+  final suffix = '_';
+  while (existingNames.contains(name)) {
+    name += suffix;
+  }
+  existingNames.add(name);
+  return name;
+}
+
 /// Chooses the GeneratedMessage member names for each field.
 ///
 /// Additional names to avoid can be supplied using [reserved].
@@ -141,7 +163,7 @@
   var existingNames = new Set<String>()
     ..addAll(_dartReservedWords)
     ..addAll(GeneratedMessage_reservedNames)
-    ..addAll(_generatedNames)
+    ..addAll(_generatedMessageNames)
     ..addAll(reserved);
 
   var memberNames = <String, MemberNames>{};
@@ -335,10 +357,25 @@
   'with'
 ];
 
-// List of names used in the generated class itself.
-const List<String> _generatedNames = const [
+// List of names used in the generated message classes.
+//
+// This is in addition to GeneratedMessage_reservedNames, which are names from
+// the base GeneratedMessage class determined by reflection.
+const _generatedMessageNames = const <String>[
   'create',
   'createRepeated',
   'getDefault',
+  'List',
+  checkItem
+];
+
+// List of names used in the generated enum classes.
+//
+// This is in addition to ProtobufEnum_reservedNames, which are names from the
+// base ProtobufEnum class determined by reflection.
+const _protobufEnumNames = const <String>[
+  'List',
+  'valueOf',
+  'values',
   checkItem
 ];
diff --git a/lib/protobuf_field.dart b/lib/protobuf_field.dart
index 615c547..cfbdbd1 100644
--- a/lib/protobuf_field.dart
+++ b/lib/protobuf_field.dart
@@ -75,10 +75,10 @@
   /// Returns the expression to use for the Dart type.
   ///
   /// This will be a List for repeated types.
-  /// [package] is the package where we are generating code.
-  String getDartType(String package) {
-    if (isRepeated) return baseType.getRepeatedDartType(package);
-    return baseType.getDartType(package);
+  /// [fileGen] represents the .proto file where we are generating code.
+  String getDartType(FileGenerator fileGen) {
+    if (isRepeated) return baseType.getRepeatedDartType(fileGen);
+    return baseType.getDartType(fileGen);
   }
 
   /// Returns the tag number of the underlying proto field.
@@ -101,10 +101,10 @@
 
   /// Returns Dart code adding this field to a BuilderInfo object.
   /// The call will start with ".." and a method name.
-  /// [package] is the package where the code will be evaluated.
-  String generateBuilderInfoCall(String package, String dartFieldName) {
+  /// [fileGen] represents the .proto file where the code will be evaluated.
+  String generateBuilderInfoCall(FileGenerator fileGen, String dartFieldName) {
     String quotedName = "'$dartFieldName'";
-    String type = baseType.getDartType(package);
+    String type = baseType.getDartType(fileGen);
 
     if (isRepeated) {
       if (baseType.isMessage || baseType.isGroup) {
@@ -120,7 +120,7 @@
       }
     }
 
-    String makeDefault = generateDefaultFunction(package);
+    String makeDefault = generateDefaultFunction(fileGen);
     if (baseType.isEnum) {
       String enumParams = '$type.valueOf, $type.values';
       return '..e<$type>('
@@ -185,14 +185,14 @@
 
   /// Returns a function expression that returns the field's default value.
   ///
-  /// [package] is the package where the expression will be evaluated.
-  /// Returns null if this field doesn't have an initializer.
-  String generateDefaultFunction(String package) {
+  /// [fileGen] represents the .proto file where the expression will be
+  /// evaluated.
+  String generateDefaultFunction(FileGenerator fileGen) {
     if (isRepeated) {
       return '() => new $_protobufImportPrefix.PbList()';
     }
-
-    bool samePackage = package == baseType.package;
+    bool sameProtoFile =
+        fileGen.protoFileUri == baseType.generator?.fileGen?.protoFileUri;
 
     switch (descriptor.type) {
       case FieldDescriptorProto_Type.TYPE_BOOL:
@@ -246,10 +246,10 @@
         return '() => <int>[$byteList]';
       case FieldDescriptorProto_Type.TYPE_GROUP:
       case FieldDescriptorProto_Type.TYPE_MESSAGE:
-        if (samePackage) return '${baseType.unprefixed}.getDefault';
+        if (sameProtoFile) return '${baseType.unprefixed}.getDefault';
         return "${baseType.prefixed}.getDefault";
       case FieldDescriptorProto_Type.TYPE_ENUM:
-        var className = samePackage ? baseType.unprefixed : baseType.prefixed;
+        var className = sameProtoFile ? baseType.unprefixed : baseType.prefixed;
         EnumGenerator gen = baseType.generator;
         if (descriptor.hasDefaultValue() && !descriptor.defaultValue.isEmpty) {
           return '$className.${descriptor.defaultValue}';
diff --git a/lib/service_generator.dart b/lib/service_generator.dart
index 22c7f6d..a001403 100644
--- a/lib/service_generator.dart
+++ b/lib/service_generator.dart
@@ -113,12 +113,11 @@
       var location = _undefinedDeps[fqname];
       throw 'FAILURE: Unknown type reference (${fqname}) for ${location}';
     }
-    if (fileGen.package == mg.fileGen.package || mg.fileGen.package == "") {
-      // It's either the same file, or another file with the same package.
-      // (In the second case, we import it without using "as".)
+    if (fileGen.protoFileUri == mg.fileGen.protoFileUri) {
+      // If it's the same file, we import it without using "as".
       return mg.classname;
     }
-    return mg.packageImportPrefix + "." + mg.classname;
+    return mg.fileImportPrefix + "." + mg.classname;
   }
 
   List<MethodDescriptorProto> get _methodDescriptors => _descriptor.method;
diff --git a/lib/src/dart_options.pb.dart b/lib/src/dart_options.pb.dart
index 286a731..0f20e07 100644
--- a/lib/src/dart_options.pb.dart
+++ b/lib/src/dart_options.pb.dart
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
diff --git a/lib/src/descriptor.pb.dart b/lib/src/descriptor.pb.dart
index e0c91c6..0be6201 100644
--- a/lib/src/descriptor.pb.dart
+++ b/lib/src/descriptor.pb.dart
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
diff --git a/lib/src/descriptor.pbenum.dart b/lib/src/descriptor.pbenum.dart
index 2d51b2b..00b0491 100644
--- a/lib/src/descriptor.pbenum.dart
+++ b/lib/src/descriptor.pbenum.dart
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore_for_file: UNDEFINED_SHOWN_NAME,UNUSED_SHOWN_NAME
 import 'dart:core' show int, dynamic, String, List, Map;
diff --git a/lib/src/plugin.pb.dart b/lib/src/plugin.pb.dart
index 826fd25..7a8ea75 100644
--- a/lib/src/plugin.pb.dart
+++ b/lib/src/plugin.pb.dart
@@ -1,14 +1,14 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
-import 'descriptor.pb.dart' as $google$protobuf;
+import 'descriptor.pb.dart' as $0;
 
 class Version extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Version',
@@ -78,12 +78,8 @@
     ..aOS(2, 'parameter')
     ..a<Version>(3, 'compilerVersion', $pb.PbFieldType.OM, Version.getDefault,
         Version.create)
-    ..pp<$google$protobuf.FileDescriptorProto>(
-        15,
-        'protoFile',
-        $pb.PbFieldType.PM,
-        $google$protobuf.FileDescriptorProto.$checkItem,
-        $google$protobuf.FileDescriptorProto.create);
+    ..pp<$0.FileDescriptorProto>(15, 'protoFile', $pb.PbFieldType.PM,
+        $0.FileDescriptorProto.$checkItem, $0.FileDescriptorProto.create);
 
   CodeGeneratorRequest() : super();
   CodeGeneratorRequest.fromBuffer(List<int> i,
@@ -125,7 +121,7 @@
   bool hasCompilerVersion() => $_has(2);
   void clearCompilerVersion() => clearField(3);
 
-  List<$google$protobuf.FileDescriptorProto> get protoFile => $_getList(3);
+  List<$0.FileDescriptorProto> get protoFile => $_getList(3);
 }
 
 class CodeGeneratorResponse_File extends $pb.GeneratedMessage {
diff --git a/pubspec.yaml b/pubspec.yaml
index b3e942a..85cc31a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: protoc_plugin
-version: 0.10.0
+version: 0.10.1
 author: Dart Team <misc@dartlang.org>
 description: Protoc compiler plugin to generate Dart code
 homepage: https://github.com/dart-lang/dart-protoc-plugin
@@ -8,7 +8,7 @@
 dependencies:
   fixnum: ^0.10.5
   path: ^1.0.0
-  protobuf: ^0.10.1
+  protobuf: ^0.10.2
   dart_style: ^1.0.6
 dev_dependencies:
   test: ^1.3.0
diff --git a/test/client_generator_test.dart b/test/client_generator_test.dart
index 17682be..e0adfa4 100644
--- a/test/client_generator_test.dart
+++ b/test/client_generator_test.dart
@@ -15,11 +15,13 @@
 void main() {
   test('testClientGenerator', () {
     var options = new GenerationOptions();
-    var fd = buildFileDescriptor("testpkg", ["SomeRequest", "SomeReply"]);
+    var fd = buildFileDescriptor(
+        "testpkg", "testpkg.proto", ["SomeRequest", "SomeReply"]);
     fd.service.add(buildServiceDescriptor());
     var fg = new FileGenerator(fd, options);
 
-    var fd2 = buildFileDescriptor("foo.bar", ["EmptyMessage", "AnotherReply"]);
+    var fd2 = buildFileDescriptor(
+        "foo.bar", "foobar.proto", ["EmptyMessage", "AnotherReply"]);
     var fg2 = new FileGenerator(fd2, options);
 
     link(new GenerationOptions(), [fg, fg2]);
diff --git a/test/goldens/client b/test/goldens/client
index 52fa215..31dee56 100644
--- a/test/goldens/client
+++ b/test/goldens/client
@@ -6,9 +6,9 @@
     var emptyResponse = new SomeReply();
     return _client.invoke<SomeReply>(ctx, 'Test', 'AMethod', request, emptyResponse);
   }
-  Future<$foo$bar.AnotherReply> anotherMethod($pb.ClientContext ctx, $foo$bar.EmptyMessage request) {
-    var emptyResponse = new $foo$bar.AnotherReply();
-    return _client.invoke<$foo$bar.AnotherReply>(ctx, 'Test', 'AnotherMethod', request, emptyResponse);
+  Future<$0.AnotherReply> anotherMethod($pb.ClientContext ctx, $0.EmptyMessage request) {
+    var emptyResponse = new $0.AnotherReply();
+    return _client.invoke<$0.AnotherReply>(ctx, 'Test', 'AnotherMethod', request, emptyResponse);
   }
 }
 
diff --git a/test/goldens/grpc_service.pb b/test/goldens/grpc_service.pb
index 6bca039..84d08bb 100644
--- a/test/goldens/grpc_service.pb
+++ b/test/goldens/grpc_service.pb
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
diff --git a/test/goldens/grpc_service.pbgrpc b/test/goldens/grpc_service.pbgrpc
index d996771..3877a3c 100644
--- a/test/goldens/grpc_service.pbgrpc
+++ b/test/goldens/grpc_service.pbgrpc
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 import 'dart:async';
 
diff --git a/test/goldens/header_in_package.pb b/test/goldens/header_in_package.pb
index a04916a..e77372f 100644
--- a/test/goldens/header_in_package.pb
+++ b/test/goldens/header_in_package.pb
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
diff --git a/test/goldens/header_with_fixnum.pb b/test/goldens/header_with_fixnum.pb
index 788d114..dbb4437 100644
--- a/test/goldens/header_with_fixnum.pb
+++ b/test/goldens/header_with_fixnum.pb
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
diff --git a/test/goldens/imports.pb b/test/goldens/imports.pb
index 31f37c1..cc0b0f1 100644
--- a/test/goldens/imports.pb
+++ b/test/goldens/imports.pb
@@ -1,21 +1,21 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
-import 'package1.pb.dart' as $p1;
-import 'package2.pb.dart' as $p2;
+import 'package1.pb.dart' as $0;
+import 'package2.pb.dart' as $1;
 
 class M extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('M')
     ..a<M>(1, 'm', $pb.PbFieldType.OM, M.getDefault, M.create)
-    ..a<$p1.M>(2, 'm1', $pb.PbFieldType.OM, $p1.M.getDefault, $p1.M.create)
-    ..a<$p2.M>(3, 'm2', $pb.PbFieldType.OM, $p2.M.getDefault, $p2.M.create)
+    ..a<$0.M>(2, 'm1', $pb.PbFieldType.OM, $0.M.getDefault, $0.M.create)
+    ..a<$1.M>(3, 'm2', $pb.PbFieldType.OM, $1.M.getDefault, $1.M.create)
     ..hasRequiredFields = false
   ;
 
@@ -38,13 +38,13 @@
   bool hasM() => $_has(0);
   void clearM() => clearField(1);
 
-  $p1.M get m1 => $_getN(1);
-  set m1($p1.M v) { setField(2, v); }
+  $0.M get m1 => $_getN(1);
+  set m1($0.M v) { setField(2, v); }
   bool hasM1() => $_has(1);
   void clearM1() => clearField(2);
 
-  $p2.M get m2 => $_getN(2);
-  set m2($p2.M v) { setField(3, v); }
+  $1.M get m2 => $_getN(2);
+  set m2($1.M v) { setField(3, v); }
   bool hasM2() => $_has(2);
   void clearM2() => clearField(3);
 }
diff --git a/test/goldens/imports.pbjson b/test/goldens/imports.pbjson
index 325f725..5792ad6 100644
--- a/test/goldens/imports.pbjson
+++ b/test/goldens/imports.pbjson
@@ -1,5 +1,5 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
diff --git a/test/goldens/oneMessage.pb b/test/goldens/oneMessage.pb
index f952864..32aac30 100644
--- a/test/goldens/oneMessage.pb
+++ b/test/goldens/oneMessage.pb
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
diff --git a/test/goldens/oneMessage.pbjson b/test/goldens/oneMessage.pbjson
index dcc2fea..6491be2 100644
--- a/test/goldens/oneMessage.pbjson
+++ b/test/goldens/oneMessage.pbjson
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 const PhoneNumber$json = const {
   '1': 'PhoneNumber',
diff --git a/test/goldens/service.pb b/test/goldens/service.pb
index 72a7084..c2a72c5 100644
--- a/test/goldens/service.pb
+++ b/test/goldens/service.pb
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 import 'dart:async';
 // ignore: UNUSED_SHOWN_NAME
diff --git a/test/goldens/service.pbserver b/test/goldens/service.pbserver
index 92953f8..9e67e8a 100644
--- a/test/goldens/service.pbserver
+++ b/test/goldens/service.pbserver
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 import 'dart:async';
 
diff --git a/test/goldens/serviceGenerator b/test/goldens/serviceGenerator
index affe065..c6a5ac7 100644
--- a/test/goldens/serviceGenerator
+++ b/test/goldens/serviceGenerator
@@ -1,11 +1,11 @@
 abstract class TestServiceBase extends GeneratedService {
   Future<SomeReply> aMethod(ServerContext ctx, SomeRequest request);
-  Future<$foo$bar.AnotherReply> anotherMethod(ServerContext ctx, $foo$bar.EmptyMessage request);
+  Future<$0.AnotherReply> anotherMethod(ServerContext ctx, $0.EmptyMessage request);
 
   GeneratedMessage createRequest(String method) {
     switch (method) {
       case 'AMethod': return new SomeRequest();
-      case 'AnotherMethod': return new $foo$bar.EmptyMessage();
+      case 'AnotherMethod': return new $0.EmptyMessage();
       default: throw new ArgumentError('Unknown method: $method');
     }
   }
diff --git a/test/goldens/topLevelEnum.pb b/test/goldens/topLevelEnum.pb
index da45d78..c69577f 100644
--- a/test/goldens/topLevelEnum.pb
+++ b/test/goldens/topLevelEnum.pb
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore: UNUSED_SHOWN_NAME
 import 'dart:core' show int, bool, double, String, List, override;
diff --git a/test/goldens/topLevelEnum.pbenum b/test/goldens/topLevelEnum.pbenum
index b60f0e4..2559b05 100644
--- a/test/goldens/topLevelEnum.pbenum
+++ b/test/goldens/topLevelEnum.pbenum
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 // ignore_for_file: UNDEFINED_SHOWN_NAME,UNUSED_SHOWN_NAME
 import 'dart:core' show int, dynamic, String, List, Map;
diff --git a/test/goldens/topLevelEnum.pbjson b/test/goldens/topLevelEnum.pbjson
index 5a3b7f1..dfda97d 100644
--- a/test/goldens/topLevelEnum.pbjson
+++ b/test/goldens/topLevelEnum.pbjson
@@ -1,7 +1,7 @@
 ///
 //  Generated code. Do not modify.
 ///
-// ignore_for_file: non_constant_identifier_names,library_prefixes
+// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
 
 const PhoneType$json = const {
   '1': 'PhoneType',
diff --git a/test/service_generator_test.dart b/test/service_generator_test.dart
index d2ba2ce..3c4ef2a 100644
--- a/test/service_generator_test.dart
+++ b/test/service_generator_test.dart
@@ -15,11 +15,13 @@
 void main() {
   test('testServiceGenerator', () {
     var options = new GenerationOptions();
-    var fd = buildFileDescriptor("testpkg", ["SomeRequest", "SomeReply"]);
+    var fd = buildFileDescriptor(
+        "testpkg", "testpkg.proto", ["SomeRequest", "SomeReply"]);
     fd.service.add(buildServiceDescriptor());
     var fg = new FileGenerator(fd, options);
 
-    var fd2 = buildFileDescriptor("foo.bar", ["EmptyMessage", "AnotherReply"]);
+    var fd2 = buildFileDescriptor(
+        "foo.bar", "foobar.proto", ["EmptyMessage", "AnotherReply"]);
     var fg2 = new FileGenerator(fd2, options);
 
     link(new GenerationOptions(), [fg, fg2]);
diff --git a/test/service_util.dart b/test/service_util.dart
index ca16c28..0f8ffec 100644
--- a/test/service_util.dart
+++ b/test/service_util.dart
@@ -22,10 +22,11 @@
   return sd;
 }
 
-FileDescriptorProto buildFileDescriptor(String package, List<String> messages) {
+FileDescriptorProto buildFileDescriptor(
+    String package, String fileUri, List<String> messages) {
   var fd = new FileDescriptorProto()
     ..package = package
-    ..name = 'test';
+    ..name = fileUri;
   for (var name in messages) {
     var md = new DescriptorProto()..name = name;