Support for Any (#112)

* Support for Any
diff --git a/.gitignore b/.gitignore
index 3c62455..d9b7de5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 .idea/
 .packages
 .pub
+.idea
 out
 packages
 pubspec.lock
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 23744cd..7edb27f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.10.0
+
+* Breaking change: Support for [any](https://developers.google.com/protocol-buffers/docs/proto3#any) messages.
+  Generated files require package:protobuf version 0.10.1 or newer.
+  `BuilderInfo.messageName` will now be the fully qualified name for generated messages.
+
 ## 0.9.0
 
 * Breaking change: Add `copyWith()` to message classes and update `getDefault()` to use `freeze()`.
diff --git a/Makefile b/Makefile
index 8b92a17..c6c338d 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,7 @@
 BENCHMARK_PROTOS = $(wildcard benchmark/protos/*.proto)
 
 TEST_PROTO_LIST = \
+	google/protobuf/any \
 	google/protobuf/unittest_import \
 	google/protobuf/unittest_optimize_for \
 	google/protobuf/unittest \
@@ -36,7 +37,8 @@
 	service2 \
 	service3 \
 	toplevel_import \
-	toplevel
+	toplevel \
+	using_any
 TEST_PROTO_DIR=$(OUTPUT_DIR)/protos
 TEST_PROTO_LIBS=$(foreach f, $(TEST_PROTO_LIST), \
   $(TEST_PROTO_DIR)/$(f).pb.dart \
diff --git a/lib/code_generator.dart b/lib/code_generator.dart
index 862ac82..46bf0fa 100644
--- a/lib/code_generator.dart
+++ b/lib/code_generator.dart
@@ -7,7 +7,13 @@
 abstract class ProtobufContainer {
   String get package;
   String get classname;
-  String get fqname;
+  String get fullName;
+
+  /// The fully qualified name with a leading '.'.
+  ///
+  /// This exists because names from protoc come like this.
+  String get dottedName => '.$fullName';
+
   String get packageImportPrefix =>
       _cachedImportPrefix ??= _calculateImportPrefix();
 
@@ -83,6 +89,6 @@
 
   String get package => '';
   String get classname => null;
-  String get fqname => '';
+  String get fullName => '';
   get fileGen => null;
 }
diff --git a/lib/enum_generator.dart b/lib/enum_generator.dart
index 3dbbd21..cae2e1f 100644
--- a/lib/enum_generator.dart
+++ b/lib/enum_generator.dart
@@ -13,22 +13,21 @@
 class EnumGenerator extends ProtobufContainer {
   final ProtobufContainer _parent;
   final String classname;
-  final String fqname;
+  final String fullName;
   final EnumDescriptorProto _descriptor;
   final List<EnumValueDescriptorProto> _canonicalValues =
       <EnumValueDescriptorProto>[];
   final List<EnumAlias> _aliases = <EnumAlias>[];
 
   EnumGenerator(EnumDescriptorProto descriptor, ProtobufContainer parent)
-      : _parent = parent,
-        classname = (parent == null || parent is FileGenerator)
+      : assert(parent != null),
+        _parent = parent,
+        classname = (parent is FileGenerator)
             ? descriptor.name
             : '${parent.classname}_${descriptor.name}',
-        fqname = (parent == null || parent.fqname == null)
+        fullName = parent.fullName == ''
             ? descriptor.name
-            : (parent.fqname == '.'
-                ? '.${descriptor.name}'
-                : '${parent.fqname}.${descriptor.name}'),
+            : '${parent.fullName}.${descriptor.name}',
         _descriptor = descriptor {
     for (EnumValueDescriptorProto value in descriptor.value) {
       EnumValueDescriptorProto canonicalValue =
@@ -46,7 +45,7 @@
 
   /// Make this enum available as a field type.
   void register(GenerationContext ctx) {
-    ctx.registerFieldType(fqname, this);
+    ctx.registerFieldType(this);
   }
 
   /// Returns a const expression that evaluates to the JSON for this message.
diff --git a/lib/extension_generator.dart b/lib/extension_generator.dart
index db1692d..784e255 100644
--- a/lib/extension_generator.dart
+++ b/lib/extension_generator.dart
@@ -11,7 +11,7 @@
   // populated by resolve()
   ProtobufField _field;
   String _extensionName;
-  String _extendedClassName = "";
+  String _extendedFullName = "";
 
   ExtensionGenerator(this._descriptor, this._parent);
 
@@ -22,7 +22,7 @@
     ProtobufContainer extendedType = ctx.getFieldType(_descriptor.extendee);
     // TODO(skybrian) When would this be null?
     if (extendedType != null) {
-      _extendedClassName = extendedType.classname;
+      _extendedFullName = extendedType.fullName;
     }
   }
 
@@ -80,7 +80,7 @@
 
     if (_field.isRepeated) {
       out.print('static final $_protobufImportPrefix.Extension $name = '
-          'new $_protobufImportPrefix.Extension<$dartType>.repeated(\'$_extendedClassName\','
+          'new $_protobufImportPrefix.Extension<$dartType>.repeated(\'$_extendedFullName\','
           ' \'$name\', ${_field.number}, ${_field.typeConstant}');
       if (type.isMessage || type.isGroup) {
         out.println(', $dartType.$checkItem, $dartType.create);');
@@ -95,7 +95,7 @@
     }
 
     out.print('static final $_protobufImportPrefix.Extension $name = '
-        'new $_protobufImportPrefix.Extension<$dartType>(\'$_extendedClassName\', \'$name\', '
+        'new $_protobufImportPrefix.Extension<$dartType>(\'$_extendedFullName\', \'$name\', '
         '${_field.number}, ${_field.typeConstant}');
 
     String initializer = _field.generateDefaultFunction(package);
diff --git a/lib/file_generator.dart b/lib/file_generator.dart
index 717a9de..1e1e5b4 100644
--- a/lib/file_generator.dart
+++ b/lib/file_generator.dart
@@ -163,7 +163,7 @@
 
   String get package => descriptor.package;
   String get classname => '';
-  String get fqname => '.${descriptor.package}';
+  String get fullName => descriptor.package;
   FileGenerator get fileGen => this;
 
   /// Generates all the Dart files for this .proto file.
diff --git a/lib/grpc_generator.dart b/lib/grpc_generator.dart
index e1eaa6c..80b1c62 100644
--- a/lib/grpc_generator.dart
+++ b/lib/grpc_generator.dart
@@ -73,7 +73,7 @@
       return;
     }
     mg.checkResolved();
-    _deps[mg.fqname] = mg;
+    _deps[mg.dottedName] = mg;
   }
 
   /// Adds dependencies of [generate] to [imports].
diff --git a/lib/linker.dart b/lib/linker.dart
index cf275d7..717c6bb 100644
--- a/lib/linker.dart
+++ b/lib/linker.dart
@@ -55,8 +55,10 @@
   }
 
   /// Makes a message, group, or enum available for reference.
-  void registerFieldType(String name, ProtobufContainer type) {
-    _typeRegistry[name] = type;
+  void registerFieldType(ProtobufContainer type) {
+    // Register the name with a leading '.' to be compatible with input from
+    // protoc.
+    _typeRegistry[type.dottedName] = type;
   }
 
   /// Returns info about a .pb.dart being imported,
diff --git a/lib/message_generator.dart b/lib/message_generator.dart
index 19962a9..0f08f25 100644
--- a/lib/message_generator.dart
+++ b/lib/message_generator.dart
@@ -27,10 +27,27 @@
   /// The name of the Dart class to generate.
   final String classname;
 
-  /// The fully-qualified name of the message type.
+  /// The fully-qualified name of the message (without any leading '.').
+  final String fullName;
+
+  /// The part of the fully qualified name that comes after the package prefix.
   ///
-  /// (Used as a unique key and in error messages, not in Dart code.)
-  final String fqname;
+  /// For nested messages this will include the names of the parents.
+  ///
+  /// For example:
+  /// ```
+  /// package foo;
+  ///
+  /// message Container {
+  ///   message Nested {
+  ///     int32 int32_value = 1;
+  ///   }
+  /// }
+  /// ```
+  /// The nested message will have a `fullName` of 'foo.Container.Nested', and a
+  /// `messageName` of 'Container.Nested'.
+  String get messageName =>
+      fullName.substring(package.length == 0 ? 0 : package.length + 1);
 
   final PbMixin mixin;
 
@@ -48,11 +65,10 @@
       : _descriptor = descriptor,
         _parent = parent,
         classname = messageClassName(descriptor, parent: parent.classname),
-        fqname = (parent == null || parent.fqname == null)
+        assert(parent != null),
+        fullName = parent.fullName == ''
             ? descriptor.name
-            : (parent.fqname == '.'
-                ? '.${descriptor.name}'
-                : '${parent.fqname}.${descriptor.name}'),
+            : '${parent.fullName}.${descriptor.name}',
         mixin = _getMixin(descriptor, parent.fileGen.descriptor, declaredMixins,
             defaultMixin) {
     for (EnumDescriptorProto e in _descriptor.enumType) {
@@ -77,7 +93,7 @@
   /// Throws an exception if [resolve] hasn't been called yet.
   void checkResolved() {
     if (_fieldList == null) {
-      throw new StateError("message not resolved: ${fqname}");
+      throw new StateError("message not resolved: ${fullName}");
     }
   }
 
@@ -103,7 +119,7 @@
 
   // Registers message and enum types that can be used elsewhere.
   void register(GenerationContext ctx) {
-    ctx.registerFieldType(fqname, this);
+    ctx.registerFieldType(this);
     for (var m in _messageGenerators) {
       m.register(ctx);
     }
@@ -205,11 +221,15 @@
       mixinClause = ' with ${mixinNames.join(", ")}';
     }
 
+    String packageClause = package == ''
+        ? ''
+        : ', package: const $_protobufImportPrefix.PackageName(\'$package\')';
     out.addBlock(
         'class ${classname} extends $_protobufImportPrefix.GeneratedMessage${mixinClause} {',
         '}', () {
       out.addBlock(
-          'static final $_protobufImportPrefix.BuilderInfo _i = new $_protobufImportPrefix.BuilderInfo(\'${classname}\')',
+          'static final $_protobufImportPrefix.BuilderInfo _i = '
+          'new $_protobufImportPrefix.BuilderInfo(\'${messageName}\'$packageClause)',
           ';', () {
         for (ProtobufField field in _fieldList) {
           var dartFieldName = field.memberNames.fieldName;
@@ -255,9 +275,12 @@
       out.println('static ${classname} _defaultInstance;');
       out.addBlock('static void $checkItem($classname v) {', '}', () {
         out.println('if (v is! $classname)'
-            " $_protobufImportPrefix.checkItemFailed(v, '$classname');");
+            " $_protobufImportPrefix.checkItemFailed(v, _i.messageName);");
       });
       generateFieldsAccessorsMutators(out);
+      if (fullName == 'google.protobuf.Any') {
+        generateAnyMethods(out);
+      }
     });
     out.println();
   }
@@ -271,7 +294,7 @@
   bool _hasRequiredFields(MessageGenerator type, Set alreadySeen) {
     if (type._fieldList == null) throw new StateError("message not resolved");
 
-    if (alreadySeen.contains(type.fqname)) {
+    if (alreadySeen.contains(type.fullName)) {
       // The type is already in cache.  This means that either:
       // a. The type has no required fields.
       // b. We are in the midst of checking if the type has required fields,
@@ -282,7 +305,7 @@
       //    here.
       return false;
     }
-    alreadySeen.add(type.fqname);
+    alreadySeen.add(type.fullName);
     // If the type has extensions, an extension with message type could contain
     // required fields, so we have to be conservative and assume such an
     // extension exists.
@@ -304,6 +327,45 @@
     return false;
   }
 
+  /// Generates methods for the Any message class for packing and unpacking
+  /// values.
+  void generateAnyMethods(IndentingWriter out) {
+    out.println('''
+  /// Unpacks the message in [value] into [instance].
+  ///
+  /// Throws a [InvalidProtocolBufferException] if [typeUrl] does not correspond
+  /// to the type of [instance].
+  ///
+  /// A typical usage would be `any.unpackInto(new Message())`.
+  ///
+  /// Returns [instance].
+  T unpackInto<T extends $_protobufImportPrefix.GeneratedMessage>(T instance,
+      {$_protobufImportPrefix.ExtensionRegistry extensionRegistry = $_protobufImportPrefix.ExtensionRegistry.EMPTY}) {
+    $_protobufImportPrefix.unpackIntoHelper(value, instance, typeUrl,
+        extensionRegistry: extensionRegistry);
+    return instance;
+  }
+
+  /// Returns `true` if the encoded message matches the type of [instance].
+  ///
+  /// Can be used with a default instance:
+  /// `any.canUnpackInto(Message.getDefault())`
+  bool canUnpackInto($_protobufImportPrefix.GeneratedMessage instance) {
+    return $_protobufImportPrefix.canUnpackIntoHelper(instance, typeUrl);
+  }
+
+  /// Creates a new [Any] encoding [message].
+  ///
+  /// The [typeUrl] will be [typeUrlPrefix]/`fullName` where `fullName` is
+  /// the fully qualified name of the type of [message].
+  static Any pack($_protobufImportPrefix.GeneratedMessage message,
+      {String typeUrlPrefix = 'type.googleapis.com'}) {
+    return new Any()
+      ..value = message.writeToBuffer()
+      ..typeUrl = '\${typeUrlPrefix}/\${message.info_.messageName}';
+  }''');
+  }
+
   void generateFieldsAccessorsMutators(IndentingWriter out) {
     for (ProtobufField field in _fieldList) {
       out.println();
@@ -324,15 +386,15 @@
 
     if (field.isRepeated) {
       if (field.overridesSetter) {
-        throw 'Field ${field.fqname} cannot override a setter for '
+        throw 'Field ${field.fullName} cannot override a setter for '
             '${names.fieldName} because it is repeated.';
       }
       if (field.overridesHasMethod) {
-        throw 'Field ${field.fqname} cannot override '
+        throw 'Field ${field.fullName} cannot override '
             '${names.hasMethodName}() because it is repeated.';
       }
       if (field.overridesClearMethod) {
-        throw 'Field ${field.fqname} cannot override '
+        throw 'Field ${field.fullName} cannot override '
             '${names.clearMethodName}() because it is repeated.';
       }
     } else {
diff --git a/lib/protobuf_field.dart b/lib/protobuf_field.dart
index e69b078..615c547 100644
--- a/lib/protobuf_field.dart
+++ b/lib/protobuf_field.dart
@@ -22,7 +22,7 @@
   /// Dart names within a GeneratedMessage or `null` for an extension.
   final MemberNames memberNames;
 
-  final String fqname;
+  final String fullName;
   final BaseType baseType;
 
   ProtobufField.message(
@@ -37,7 +37,7 @@
       ProtobufContainer parent, GenerationContext ctx)
       : this.descriptor = descriptor,
         this.memberNames = dartNames,
-        fqname = '${parent.fqname}.${descriptor.name}',
+        fullName = '${parent.fullName}.${descriptor.name}',
         baseType = new BaseType(descriptor, ctx);
 
   /// The index of this field in MessageGenerator.fieldList.
@@ -290,9 +290,9 @@
 
   get _invalidDefaultValue => "dart-protoc-plugin:"
       " invalid default value (${descriptor.defaultValue})"
-      " found in field $fqname";
+      " found in field $fullName";
 
   _typeNotImplemented(String methodName) => "dart-protoc-plugin:"
       " $methodName not implemented for type (${descriptor.type})"
-      " found in field $fqname";
+      " found in field $fullName";
 }
diff --git a/lib/service_generator.dart b/lib/service_generator.dart
index 75d8e0c..22c7f6d 100644
--- a/lib/service_generator.dart
+++ b/lib/service_generator.dart
@@ -12,13 +12,13 @@
 
   /// The message types needed directly by this service.
   ///
-  /// The key is the fully qualified name.
+  /// The key is the fully qualified name with a leading '.'.
   /// Populated by [resolve].
   final _deps = <String, MessageGenerator>{};
 
   /// The message types needed transitively by this service.
   ///
-  /// The key is the fully qualified name.
+  /// The key is the fully qualified name with a leading '.'.
   /// Populated by [resolve].
   final _transitiveDeps = <String, MessageGenerator>{};
 
@@ -69,14 +69,14 @@
   }
 
   void _addDepsRecursively(MessageGenerator mg, int depth) {
-    if (_transitiveDeps.containsKey(mg.fqname)) {
+    if (_transitiveDeps.containsKey(mg.dottedName)) {
       // Already added, but perhaps at a different depth.
-      if (depth == 0) _deps[mg.fqname] = mg;
+      if (depth == 0) _deps[mg.dottedName] = mg;
       return;
     }
     mg.checkResolved();
-    if (depth == 0) _deps[mg.fqname] = mg;
-    _transitiveDeps[mg.fqname] = mg;
+    if (depth == 0) _deps[mg.dottedName] = mg;
+    _transitiveDeps[mg.dottedName] = mg;
     for (var field in mg._fieldList) {
       if (field.baseType.isGroup || field.baseType.isMessage) {
         _addDepsRecursively(field.baseType.generator, depth + 1);
diff --git a/lib/src/dart_options.pb.dart b/lib/src/dart_options.pb.dart
index b4d45c5..286a731 100644
--- a/lib/src/dart_options.pb.dart
+++ b/lib/src/dart_options.pb.dart
@@ -9,7 +9,8 @@
 import 'package:protobuf/protobuf.dart' as $pb;
 
 class DartMixin extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('DartMixin')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('DartMixin',
+      package: const $pb.PackageName('dart_options'))
     ..aOS(1, 'name')
     ..aOS(2, 'importFrom')
     ..aOS(3, 'parent')
@@ -31,7 +32,7 @@
   static DartMixin getDefault() => _defaultInstance ??= create()..freeze();
   static DartMixin _defaultInstance;
   static void $checkItem(DartMixin v) {
-    if (v is! DartMixin) $pb.checkItemFailed(v, 'DartMixin');
+    if (v is! DartMixin) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -60,7 +61,8 @@
 }
 
 class Imports extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Imports')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Imports',
+      package: const $pb.PackageName('dart_options'))
     ..pp<DartMixin>(
         1, 'mixins', $pb.PbFieldType.PM, DartMixin.$checkItem, DartMixin.create)
     ..hasRequiredFields = false;
@@ -81,7 +83,7 @@
   static Imports getDefault() => _defaultInstance ??= create()..freeze();
   static Imports _defaultInstance;
   static void $checkItem(Imports v) {
-    if (v is! Imports) $pb.checkItemFailed(v, 'Imports');
+    if (v is! Imports) $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<DartMixin> get mixins => $_getList(0);
@@ -89,26 +91,41 @@
 
 class Dart_options {
   static final $pb.Extension imports = new $pb.Extension<Imports>(
-      'FileOptions',
+      'google.protobuf.FileOptions',
       'imports',
       28125061,
       $pb.PbFieldType.OM,
       Imports.getDefault,
       Imports.create);
   static final $pb.Extension defaultMixin = new $pb.Extension<String>(
-      'FileOptions', 'defaultMixin', 96128839, $pb.PbFieldType.OS);
+      'google.protobuf.FileOptions',
+      'defaultMixin',
+      96128839,
+      $pb.PbFieldType.OS);
   static final $pb.Extension mixin = new $pb.Extension<String>(
-      'MessageOptions', 'mixin', 96128839, $pb.PbFieldType.OS);
+      'google.protobuf.MessageOptions', 'mixin', 96128839, $pb.PbFieldType.OS);
   static final $pb.Extension overrideGetter = new $pb.Extension<bool>(
-      'FieldOptions', 'overrideGetter', 28205290, $pb.PbFieldType.OB);
+      'google.protobuf.FieldOptions',
+      'overrideGetter',
+      28205290,
+      $pb.PbFieldType.OB);
   static final $pb.Extension overrideSetter = new $pb.Extension<bool>(
-      'FieldOptions', 'overrideSetter', 28937366, $pb.PbFieldType.OB);
+      'google.protobuf.FieldOptions',
+      'overrideSetter',
+      28937366,
+      $pb.PbFieldType.OB);
   static final $pb.Extension overrideHasMethod = new $pb.Extension<bool>(
-      'FieldOptions', 'overrideHasMethod', 28937461, $pb.PbFieldType.OB);
+      'google.protobuf.FieldOptions',
+      'overrideHasMethod',
+      28937461,
+      $pb.PbFieldType.OB);
   static final $pb.Extension overrideClearMethod = new $pb.Extension<bool>(
-      'FieldOptions', 'overrideClearMethod', 28907907, $pb.PbFieldType.OB);
+      'google.protobuf.FieldOptions',
+      'overrideClearMethod',
+      28907907,
+      $pb.PbFieldType.OB);
   static final $pb.Extension dartName = new $pb.Extension<String>(
-      'FieldOptions', 'dartName', 28700919, $pb.PbFieldType.OS);
+      'google.protobuf.FieldOptions', 'dartName', 28700919, $pb.PbFieldType.OS);
   static void registerAllExtensions($pb.ExtensionRegistry registry) {
     registry.add(imports);
     registry.add(defaultMixin);
diff --git a/lib/src/descriptor.pb.dart b/lib/src/descriptor.pb.dart
index b6c3c8e..e0c91c6 100644
--- a/lib/src/descriptor.pb.dart
+++ b/lib/src/descriptor.pb.dart
@@ -14,7 +14,8 @@
 export 'descriptor.pbenum.dart';
 
 class FileDescriptorSet extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FileDescriptorSet')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FileDescriptorSet',
+      package: const $pb.PackageName('google.protobuf'))
     ..pp<FileDescriptorProto>(1, 'file', $pb.PbFieldType.PM,
         FileDescriptorProto.$checkItem, FileDescriptorProto.create);
 
@@ -36,14 +37,15 @@
       _defaultInstance ??= create()..freeze();
   static FileDescriptorSet _defaultInstance;
   static void $checkItem(FileDescriptorSet v) {
-    if (v is! FileDescriptorSet) $pb.checkItemFailed(v, 'FileDescriptorSet');
+    if (v is! FileDescriptorSet) $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<FileDescriptorProto> get file => $_getList(0);
 }
 
 class FileDescriptorProto extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FileDescriptorProto')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FileDescriptorProto',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOS(1, 'name')
     ..aOS(2, 'package')
     ..pPS(3, 'dependency')
@@ -82,8 +84,7 @@
       _defaultInstance ??= create()..freeze();
   static FileDescriptorProto _defaultInstance;
   static void $checkItem(FileDescriptorProto v) {
-    if (v is! FileDescriptorProto)
-      $pb.checkItemFailed(v, 'FileDescriptorProto');
+    if (v is! FileDescriptorProto) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -142,11 +143,12 @@
 }
 
 class DescriptorProto_ExtensionRange extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      new $pb.BuilderInfo('DescriptorProto_ExtensionRange')
-        ..a<int>(1, 'start', $pb.PbFieldType.O3)
-        ..a<int>(2, 'end', $pb.PbFieldType.O3)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo(
+      'DescriptorProto.ExtensionRange',
+      package: const $pb.PackageName('google.protobuf'))
+    ..a<int>(1, 'start', $pb.PbFieldType.O3)
+    ..a<int>(2, 'end', $pb.PbFieldType.O3)
+    ..hasRequiredFields = false;
 
   DescriptorProto_ExtensionRange() : super();
   DescriptorProto_ExtensionRange.fromBuffer(List<int> i,
@@ -171,7 +173,7 @@
   static DescriptorProto_ExtensionRange _defaultInstance;
   static void $checkItem(DescriptorProto_ExtensionRange v) {
     if (v is! DescriptorProto_ExtensionRange)
-      $pb.checkItemFailed(v, 'DescriptorProto_ExtensionRange');
+      $pb.checkItemFailed(v, _i.messageName);
   }
 
   int get start => $_get(0, 0);
@@ -192,11 +194,12 @@
 }
 
 class DescriptorProto_ReservedRange extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      new $pb.BuilderInfo('DescriptorProto_ReservedRange')
-        ..a<int>(1, 'start', $pb.PbFieldType.O3)
-        ..a<int>(2, 'end', $pb.PbFieldType.O3)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo(
+      'DescriptorProto.ReservedRange',
+      package: const $pb.PackageName('google.protobuf'))
+    ..a<int>(1, 'start', $pb.PbFieldType.O3)
+    ..a<int>(2, 'end', $pb.PbFieldType.O3)
+    ..hasRequiredFields = false;
 
   DescriptorProto_ReservedRange() : super();
   DescriptorProto_ReservedRange.fromBuffer(List<int> i,
@@ -221,7 +224,7 @@
   static DescriptorProto_ReservedRange _defaultInstance;
   static void $checkItem(DescriptorProto_ReservedRange v) {
     if (v is! DescriptorProto_ReservedRange)
-      $pb.checkItemFailed(v, 'DescriptorProto_ReservedRange');
+      $pb.checkItemFailed(v, _i.messageName);
   }
 
   int get start => $_get(0, 0);
@@ -242,7 +245,8 @@
 }
 
 class DescriptorProto extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('DescriptorProto')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('DescriptorProto',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOS(1, 'name')
     ..pp<FieldDescriptorProto>(2, 'field', $pb.PbFieldType.PM,
         FieldDescriptorProto.$checkItem, FieldDescriptorProto.create)
@@ -288,7 +292,7 @@
       _defaultInstance ??= create()..freeze();
   static DescriptorProto _defaultInstance;
   static void $checkItem(DescriptorProto v) {
-    if (v is! DescriptorProto) $pb.checkItemFailed(v, 'DescriptorProto');
+    if (v is! DescriptorProto) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -325,7 +329,8 @@
 }
 
 class FieldDescriptorProto extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FieldDescriptorProto')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FieldDescriptorProto',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOS(1, 'name')
     ..aOS(2, 'extendee')
     ..a<int>(3, 'number', $pb.PbFieldType.O3)
@@ -369,8 +374,7 @@
       _defaultInstance ??= create()..freeze();
   static FieldDescriptorProto _defaultInstance;
   static void $checkItem(FieldDescriptorProto v) {
-    if (v is! FieldDescriptorProto)
-      $pb.checkItemFailed(v, 'FieldDescriptorProto');
+    if (v is! FieldDescriptorProto) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -455,7 +459,8 @@
 }
 
 class OneofDescriptorProto extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('OneofDescriptorProto')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('OneofDescriptorProto',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOS(1, 'name')
     ..a<OneofOptions>(2, 'options', $pb.PbFieldType.OM, OneofOptions.getDefault,
         OneofOptions.create);
@@ -479,8 +484,7 @@
       _defaultInstance ??= create()..freeze();
   static OneofDescriptorProto _defaultInstance;
   static void $checkItem(OneofDescriptorProto v) {
-    if (v is! OneofDescriptorProto)
-      $pb.checkItemFailed(v, 'OneofDescriptorProto');
+    if (v is! OneofDescriptorProto) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -501,7 +505,8 @@
 }
 
 class EnumDescriptorProto extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumDescriptorProto')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumDescriptorProto',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOS(1, 'name')
     ..pp<EnumValueDescriptorProto>(2, 'value', $pb.PbFieldType.PM,
         EnumValueDescriptorProto.$checkItem, EnumValueDescriptorProto.create)
@@ -527,8 +532,7 @@
       _defaultInstance ??= create()..freeze();
   static EnumDescriptorProto _defaultInstance;
   static void $checkItem(EnumDescriptorProto v) {
-    if (v is! EnumDescriptorProto)
-      $pb.checkItemFailed(v, 'EnumDescriptorProto');
+    if (v is! EnumDescriptorProto) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -551,12 +555,13 @@
 }
 
 class EnumValueDescriptorProto extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      new $pb.BuilderInfo('EnumValueDescriptorProto')
-        ..aOS(1, 'name')
-        ..a<int>(2, 'number', $pb.PbFieldType.O3)
-        ..a<EnumValueOptions>(3, 'options', $pb.PbFieldType.OM,
-            EnumValueOptions.getDefault, EnumValueOptions.create);
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo(
+      'EnumValueDescriptorProto',
+      package: const $pb.PackageName('google.protobuf'))
+    ..aOS(1, 'name')
+    ..a<int>(2, 'number', $pb.PbFieldType.O3)
+    ..a<EnumValueOptions>(3, 'options', $pb.PbFieldType.OM,
+        EnumValueOptions.getDefault, EnumValueOptions.create);
 
   EnumValueDescriptorProto() : super();
   EnumValueDescriptorProto.fromBuffer(List<int> i,
@@ -578,8 +583,7 @@
       _defaultInstance ??= create()..freeze();
   static EnumValueDescriptorProto _defaultInstance;
   static void $checkItem(EnumValueDescriptorProto v) {
-    if (v is! EnumValueDescriptorProto)
-      $pb.checkItemFailed(v, 'EnumValueDescriptorProto');
+    if (v is! EnumValueDescriptorProto) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -608,13 +612,14 @@
 }
 
 class ServiceDescriptorProto extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      new $pb.BuilderInfo('ServiceDescriptorProto')
-        ..aOS(1, 'name')
-        ..pp<MethodDescriptorProto>(2, 'method', $pb.PbFieldType.PM,
-            MethodDescriptorProto.$checkItem, MethodDescriptorProto.create)
-        ..a<ServiceOptions>(3, 'options', $pb.PbFieldType.OM,
-            ServiceOptions.getDefault, ServiceOptions.create);
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo(
+      'ServiceDescriptorProto',
+      package: const $pb.PackageName('google.protobuf'))
+    ..aOS(1, 'name')
+    ..pp<MethodDescriptorProto>(2, 'method', $pb.PbFieldType.PM,
+        MethodDescriptorProto.$checkItem, MethodDescriptorProto.create)
+    ..a<ServiceOptions>(3, 'options', $pb.PbFieldType.OM,
+        ServiceOptions.getDefault, ServiceOptions.create);
 
   ServiceDescriptorProto() : super();
   ServiceDescriptorProto.fromBuffer(List<int> i,
@@ -636,8 +641,7 @@
       _defaultInstance ??= create()..freeze();
   static ServiceDescriptorProto _defaultInstance;
   static void $checkItem(ServiceDescriptorProto v) {
-    if (v is! ServiceDescriptorProto)
-      $pb.checkItemFailed(v, 'ServiceDescriptorProto');
+    if (v is! ServiceDescriptorProto) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -660,7 +664,8 @@
 }
 
 class MethodDescriptorProto extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MethodDescriptorProto')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MethodDescriptorProto',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOS(1, 'name')
     ..aOS(2, 'inputType')
     ..aOS(3, 'outputType')
@@ -689,8 +694,7 @@
       _defaultInstance ??= create()..freeze();
   static MethodDescriptorProto _defaultInstance;
   static void $checkItem(MethodDescriptorProto v) {
-    if (v is! MethodDescriptorProto)
-      $pb.checkItemFailed(v, 'MethodDescriptorProto');
+    if (v is! MethodDescriptorProto) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -743,7 +747,8 @@
 }
 
 class FileOptions extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FileOptions')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FileOptions',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOS(1, 'javaPackage')
     ..aOS(8, 'javaOuterClassname')
     ..e<FileOptions_OptimizeMode>(
@@ -788,7 +793,7 @@
   static FileOptions getDefault() => _defaultInstance ??= create()..freeze();
   static FileOptions _defaultInstance;
   static void $checkItem(FileOptions v) {
-    if (v is! FileOptions) $pb.checkItemFailed(v, 'FileOptions');
+    if (v is! FileOptions) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get javaPackage => $_getS(0, '');
@@ -931,7 +936,8 @@
 }
 
 class MessageOptions extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MessageOptions')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MessageOptions',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOB(1, 'messageSetWireFormat')
     ..aOB(2, 'noStandardDescriptorAccessor')
     ..aOB(3, 'deprecated')
@@ -957,7 +963,7 @@
   static MessageOptions getDefault() => _defaultInstance ??= create()..freeze();
   static MessageOptions _defaultInstance;
   static void $checkItem(MessageOptions v) {
-    if (v is! MessageOptions) $pb.checkItemFailed(v, 'MessageOptions');
+    if (v is! MessageOptions) $pb.checkItemFailed(v, _i.messageName);
   }
 
   bool get messageSetWireFormat => $_get(0, false);
@@ -996,7 +1002,8 @@
 }
 
 class FieldOptions extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FieldOptions')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FieldOptions',
+      package: const $pb.PackageName('google.protobuf'))
     ..e<FieldOptions_CType>(
         1,
         'ctype',
@@ -1036,7 +1043,7 @@
   static FieldOptions getDefault() => _defaultInstance ??= create()..freeze();
   static FieldOptions _defaultInstance;
   static void $checkItem(FieldOptions v) {
-    if (v is! FieldOptions) $pb.checkItemFailed(v, 'FieldOptions');
+    if (v is! FieldOptions) $pb.checkItemFailed(v, _i.messageName);
   }
 
   FieldOptions_CType get ctype => $_getN(0);
@@ -1091,7 +1098,8 @@
 }
 
 class OneofOptions extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('OneofOptions')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('OneofOptions',
+      package: const $pb.PackageName('google.protobuf'))
     ..pp<UninterpretedOption>(999, 'uninterpretedOption', $pb.PbFieldType.PM,
         UninterpretedOption.$checkItem, UninterpretedOption.create)
     ..hasExtensions = true;
@@ -1113,14 +1121,15 @@
   static OneofOptions getDefault() => _defaultInstance ??= create()..freeze();
   static OneofOptions _defaultInstance;
   static void $checkItem(OneofOptions v) {
-    if (v is! OneofOptions) $pb.checkItemFailed(v, 'OneofOptions');
+    if (v is! OneofOptions) $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<UninterpretedOption> get uninterpretedOption => $_getList(0);
 }
 
 class EnumOptions extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumOptions')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumOptions',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOB(2, 'allowAlias')
     ..aOB(3, 'deprecated')
     ..pp<UninterpretedOption>(999, 'uninterpretedOption', $pb.PbFieldType.PM,
@@ -1144,7 +1153,7 @@
   static EnumOptions getDefault() => _defaultInstance ??= create()..freeze();
   static EnumOptions _defaultInstance;
   static void $checkItem(EnumOptions v) {
-    if (v is! EnumOptions) $pb.checkItemFailed(v, 'EnumOptions');
+    if (v is! EnumOptions) $pb.checkItemFailed(v, _i.messageName);
   }
 
   bool get allowAlias => $_get(0, false);
@@ -1167,7 +1176,8 @@
 }
 
 class EnumValueOptions extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumValueOptions')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumValueOptions',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOB(1, 'deprecated')
     ..pp<UninterpretedOption>(999, 'uninterpretedOption', $pb.PbFieldType.PM,
         UninterpretedOption.$checkItem, UninterpretedOption.create)
@@ -1191,7 +1201,7 @@
       _defaultInstance ??= create()..freeze();
   static EnumValueOptions _defaultInstance;
   static void $checkItem(EnumValueOptions v) {
-    if (v is! EnumValueOptions) $pb.checkItemFailed(v, 'EnumValueOptions');
+    if (v is! EnumValueOptions) $pb.checkItemFailed(v, _i.messageName);
   }
 
   bool get deprecated => $_get(0, false);
@@ -1206,7 +1216,8 @@
 }
 
 class ServiceOptions extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ServiceOptions')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ServiceOptions',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOB(33, 'deprecated')
     ..pp<UninterpretedOption>(999, 'uninterpretedOption', $pb.PbFieldType.PM,
         UninterpretedOption.$checkItem, UninterpretedOption.create)
@@ -1229,7 +1240,7 @@
   static ServiceOptions getDefault() => _defaultInstance ??= create()..freeze();
   static ServiceOptions _defaultInstance;
   static void $checkItem(ServiceOptions v) {
-    if (v is! ServiceOptions) $pb.checkItemFailed(v, 'ServiceOptions');
+    if (v is! ServiceOptions) $pb.checkItemFailed(v, _i.messageName);
   }
 
   bool get deprecated => $_get(0, false);
@@ -1244,7 +1255,8 @@
 }
 
 class MethodOptions extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MethodOptions')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MethodOptions',
+      package: const $pb.PackageName('google.protobuf'))
     ..aOB(33, 'deprecated')
     ..e<MethodOptions_IdempotencyLevel>(
         34,
@@ -1274,7 +1286,7 @@
   static MethodOptions getDefault() => _defaultInstance ??= create()..freeze();
   static MethodOptions _defaultInstance;
   static void $checkItem(MethodOptions v) {
-    if (v is! MethodOptions) $pb.checkItemFailed(v, 'MethodOptions');
+    if (v is! MethodOptions) $pb.checkItemFailed(v, _i.messageName);
   }
 
   bool get deprecated => $_get(0, false);
@@ -1297,10 +1309,11 @@
 }
 
 class UninterpretedOption_NamePart extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      new $pb.BuilderInfo('UninterpretedOption_NamePart')
-        ..aQS(1, 'namePart')
-        ..a<bool>(2, 'isExtension', $pb.PbFieldType.QB);
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo(
+      'UninterpretedOption.NamePart',
+      package: const $pb.PackageName('google.protobuf'))
+    ..aQS(1, 'namePart')
+    ..a<bool>(2, 'isExtension', $pb.PbFieldType.QB);
 
   UninterpretedOption_NamePart() : super();
   UninterpretedOption_NamePart.fromBuffer(List<int> i,
@@ -1325,7 +1338,7 @@
   static UninterpretedOption_NamePart _defaultInstance;
   static void $checkItem(UninterpretedOption_NamePart v) {
     if (v is! UninterpretedOption_NamePart)
-      $pb.checkItemFailed(v, 'UninterpretedOption_NamePart');
+      $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get namePart => $_getS(0, '');
@@ -1346,7 +1359,8 @@
 }
 
 class UninterpretedOption extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('UninterpretedOption')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('UninterpretedOption',
+      package: const $pb.PackageName('google.protobuf'))
     ..pp<UninterpretedOption_NamePart>(
         2,
         'name',
@@ -1379,8 +1393,7 @@
       _defaultInstance ??= create()..freeze();
   static UninterpretedOption _defaultInstance;
   static void $checkItem(UninterpretedOption v) {
-    if (v is! UninterpretedOption)
-      $pb.checkItemFailed(v, 'UninterpretedOption');
+    if (v is! UninterpretedOption) $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<UninterpretedOption_NamePart> get name => $_getList(0);
@@ -1435,14 +1448,15 @@
 }
 
 class SourceCodeInfo_Location extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      new $pb.BuilderInfo('SourceCodeInfo_Location')
-        ..p<int>(1, 'path', $pb.PbFieldType.K3)
-        ..p<int>(2, 'span', $pb.PbFieldType.K3)
-        ..aOS(3, 'leadingComments')
-        ..aOS(4, 'trailingComments')
-        ..pPS(6, 'leadingDetachedComments')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo(
+      'SourceCodeInfo.Location',
+      package: const $pb.PackageName('google.protobuf'))
+    ..p<int>(1, 'path', $pb.PbFieldType.K3)
+    ..p<int>(2, 'span', $pb.PbFieldType.K3)
+    ..aOS(3, 'leadingComments')
+    ..aOS(4, 'trailingComments')
+    ..pPS(6, 'leadingDetachedComments')
+    ..hasRequiredFields = false;
 
   SourceCodeInfo_Location() : super();
   SourceCodeInfo_Location.fromBuffer(List<int> i,
@@ -1464,8 +1478,7 @@
       _defaultInstance ??= create()..freeze();
   static SourceCodeInfo_Location _defaultInstance;
   static void $checkItem(SourceCodeInfo_Location v) {
-    if (v is! SourceCodeInfo_Location)
-      $pb.checkItemFailed(v, 'SourceCodeInfo_Location');
+    if (v is! SourceCodeInfo_Location) $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<int> get path => $_getList(0);
@@ -1492,7 +1505,8 @@
 }
 
 class SourceCodeInfo extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('SourceCodeInfo')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('SourceCodeInfo',
+      package: const $pb.PackageName('google.protobuf'))
     ..pp<SourceCodeInfo_Location>(1, 'location', $pb.PbFieldType.PM,
         SourceCodeInfo_Location.$checkItem, SourceCodeInfo_Location.create)
     ..hasRequiredFields = false;
@@ -1514,20 +1528,21 @@
   static SourceCodeInfo getDefault() => _defaultInstance ??= create()..freeze();
   static SourceCodeInfo _defaultInstance;
   static void $checkItem(SourceCodeInfo v) {
-    if (v is! SourceCodeInfo) $pb.checkItemFailed(v, 'SourceCodeInfo');
+    if (v is! SourceCodeInfo) $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<SourceCodeInfo_Location> get location => $_getList(0);
 }
 
 class GeneratedCodeInfo_Annotation extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      new $pb.BuilderInfo('GeneratedCodeInfo_Annotation')
-        ..p<int>(1, 'path', $pb.PbFieldType.K3)
-        ..aOS(2, 'sourceFile')
-        ..a<int>(3, 'begin', $pb.PbFieldType.O3)
-        ..a<int>(4, 'end', $pb.PbFieldType.O3)
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo(
+      'GeneratedCodeInfo.Annotation',
+      package: const $pb.PackageName('google.protobuf'))
+    ..p<int>(1, 'path', $pb.PbFieldType.K3)
+    ..aOS(2, 'sourceFile')
+    ..a<int>(3, 'begin', $pb.PbFieldType.O3)
+    ..a<int>(4, 'end', $pb.PbFieldType.O3)
+    ..hasRequiredFields = false;
 
   GeneratedCodeInfo_Annotation() : super();
   GeneratedCodeInfo_Annotation.fromBuffer(List<int> i,
@@ -1552,7 +1567,7 @@
   static GeneratedCodeInfo_Annotation _defaultInstance;
   static void $checkItem(GeneratedCodeInfo_Annotation v) {
     if (v is! GeneratedCodeInfo_Annotation)
-      $pb.checkItemFailed(v, 'GeneratedCodeInfo_Annotation');
+      $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<int> get path => $_getList(0);
@@ -1583,7 +1598,8 @@
 }
 
 class GeneratedCodeInfo extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('GeneratedCodeInfo')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('GeneratedCodeInfo',
+      package: const $pb.PackageName('google.protobuf'))
     ..pp<GeneratedCodeInfo_Annotation>(
         1,
         'annotation',
@@ -1610,7 +1626,7 @@
       _defaultInstance ??= create()..freeze();
   static GeneratedCodeInfo _defaultInstance;
   static void $checkItem(GeneratedCodeInfo v) {
-    if (v is! GeneratedCodeInfo) $pb.checkItemFailed(v, 'GeneratedCodeInfo');
+    if (v is! GeneratedCodeInfo) $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<GeneratedCodeInfo_Annotation> get annotation => $_getList(0);
diff --git a/lib/src/plugin.pb.dart b/lib/src/plugin.pb.dart
index 6da3376..826fd25 100644
--- a/lib/src/plugin.pb.dart
+++ b/lib/src/plugin.pb.dart
@@ -11,7 +11,8 @@
 import 'descriptor.pb.dart' as $google$protobuf;
 
 class Version extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Version')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Version',
+      package: const $pb.PackageName('google.protobuf.compiler'))
     ..a<int>(1, 'major', $pb.PbFieldType.O3)
     ..a<int>(2, 'minor', $pb.PbFieldType.O3)
     ..a<int>(3, 'patch', $pb.PbFieldType.O3)
@@ -34,7 +35,7 @@
   static Version getDefault() => _defaultInstance ??= create()..freeze();
   static Version _defaultInstance;
   static void $checkItem(Version v) {
-    if (v is! Version) $pb.checkItemFailed(v, 'Version');
+    if (v is! Version) $pb.checkItemFailed(v, _i.messageName);
   }
 
   int get major => $_get(0, 0);
@@ -71,7 +72,8 @@
 }
 
 class CodeGeneratorRequest extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('CodeGeneratorRequest')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('CodeGeneratorRequest',
+      package: const $pb.PackageName('google.protobuf.compiler'))
     ..pPS(1, 'fileToGenerate')
     ..aOS(2, 'parameter')
     ..a<Version>(3, 'compilerVersion', $pb.PbFieldType.OM, Version.getDefault,
@@ -102,8 +104,7 @@
       _defaultInstance ??= create()..freeze();
   static CodeGeneratorRequest _defaultInstance;
   static void $checkItem(CodeGeneratorRequest v) {
-    if (v is! CodeGeneratorRequest)
-      $pb.checkItemFailed(v, 'CodeGeneratorRequest');
+    if (v is! CodeGeneratorRequest) $pb.checkItemFailed(v, _i.messageName);
   }
 
   List<String> get fileToGenerate => $_getList(0);
@@ -128,12 +129,13 @@
 }
 
 class CodeGeneratorResponse_File extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i =
-      new $pb.BuilderInfo('CodeGeneratorResponse_File')
-        ..aOS(1, 'name')
-        ..aOS(2, 'insertionPoint')
-        ..aOS(15, 'content')
-        ..hasRequiredFields = false;
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo(
+      'CodeGeneratorResponse.File',
+      package: const $pb.PackageName('google.protobuf.compiler'))
+    ..aOS(1, 'name')
+    ..aOS(2, 'insertionPoint')
+    ..aOS(15, 'content')
+    ..hasRequiredFields = false;
 
   CodeGeneratorResponse_File() : super();
   CodeGeneratorResponse_File.fromBuffer(List<int> i,
@@ -158,7 +160,7 @@
   static CodeGeneratorResponse_File _defaultInstance;
   static void $checkItem(CodeGeneratorResponse_File v) {
     if (v is! CodeGeneratorResponse_File)
-      $pb.checkItemFailed(v, 'CodeGeneratorResponse_File');
+      $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get name => $_getS(0, '');
@@ -187,7 +189,8 @@
 }
 
 class CodeGeneratorResponse extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('CodeGeneratorResponse')
+  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('CodeGeneratorResponse',
+      package: const $pb.PackageName('google.protobuf.compiler'))
     ..aOS(1, 'error')
     ..pp<CodeGeneratorResponse_File>(
         15,
@@ -217,8 +220,7 @@
       _defaultInstance ??= create()..freeze();
   static CodeGeneratorResponse _defaultInstance;
   static void $checkItem(CodeGeneratorResponse v) {
-    if (v is! CodeGeneratorResponse)
-      $pb.checkItemFailed(v, 'CodeGeneratorResponse');
+    if (v is! CodeGeneratorResponse) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get error => $_getS(0, '');
diff --git a/pubspec.yaml b/pubspec.yaml
index b7430bd..b3e942a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: protoc_plugin
-version: 0.9.0
+version: 0.10.0
 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.0
+  protobuf: ^0.10.1
   dart_style: ^1.0.6
 dev_dependencies:
   test: ^1.3.0
diff --git a/test/all_tests.dart b/test/all_tests.dart
index fb05b2c..e9e159b 100755
--- a/test/all_tests.dart
+++ b/test/all_tests.dart
@@ -6,6 +6,7 @@
 library protoc_plugin_all_tests;
 
 import 'bazel_test.dart' as bazel;
+import 'any_test.dart' as any;
 import 'client_generator_test.dart' as client_generator;
 import 'const_generator_test.dart' as const_generator;
 import 'enum_generator_test.dart' as enum_generator;
@@ -30,6 +31,7 @@
 import 'wire_format_test.dart' as wire_format;
 
 void main() {
+  any.main();
   bazel.main();
   client_generator.main();
   const_generator.main();
diff --git a/test/any_test.dart b/test/any_test.dart
new file mode 100644
index 0000000..e755a27
--- /dev/null
+++ b/test/any_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:protobuf/protobuf.dart';
+import 'package:test/test.dart';
+
+import '../out/protos/google/protobuf/any.pb.dart';
+import '../out/protos/service.pb.dart';
+import '../out/protos/toplevel.pb.dart' as toplevel;
+import '../out/protos/using_any.pb.dart';
+
+void main() {
+  test('pack -> unpack', () {
+    Any any = Any.pack(new SearchRequest()..query = 'hest');
+    expect(any.typeUrl, 'type.googleapis.com/SearchRequest');
+    Any any1 = Any.pack(new SearchRequest()..query = 'hest1',
+        typeUrlPrefix: 'example.com');
+    expect(any1.typeUrl, 'example.com/SearchRequest');
+    expect(any1.canUnpackInto(SearchRequest.getDefault()), true);
+    expect(any1.canUnpackInto(SearchResponse.getDefault()), false);
+    SearchRequest searchRequest = any.unpackInto(new SearchRequest());
+    expect(searchRequest.query, 'hest');
+    SearchRequest searchRequest1 = any1.unpackInto(new SearchRequest());
+    expect(searchRequest1.query, 'hest1');
+    expect(() {
+      any.unpackInto(new SearchResponse());
+    }, throwsA(const TypeMatcher<InvalidProtocolBufferException>()));
+  });
+
+  test('any inside any', () {
+    Any any = Any.pack(Any.pack(new SearchRequest()..query = 'hest'));
+    expect(any.typeUrl, 'type.googleapis.com/google.protobuf.Any');
+    expect(any.canUnpackInto(Any.getDefault()), true);
+    expect(any.canUnpackInto(SearchRequest.getDefault()), false);
+    expect(any.unpackInto(new Any()).canUnpackInto(SearchRequest.getDefault()),
+        true);
+    expect(any.unpackInto(new Any()).unpackInto(new SearchRequest()).query,
+        'hest');
+  });
+
+  test('toplevel', () {
+    Any any = Any.pack(new toplevel.T()
+      ..a = 127
+      ..b = 'hest');
+    expect(any.typeUrl, 'type.googleapis.com/T');
+    var t2 = any.unpackInto(new toplevel.T());
+    expect(t2.a, 127);
+    expect(t2.b, 'hest');
+  });
+
+  test('nested message', () {
+    Any any = Any.pack(new Container_Nested()..int32Value = 127);
+    expect(
+        any.typeUrl, 'type.googleapis.com/protobuf_unittest.Container.Nested');
+    var t2 = any.unpackInto(new Container_Nested());
+    expect(t2.int32Value, 127);
+  });
+
+  test('using any', () {
+    Any any = Any.pack(new SearchRequest()..query = 'hest');
+    Any any1 = Any.pack(new SearchRequest()..query = 'hest1');
+    Any any2 = Any.pack(new SearchRequest()..query = 'hest2');
+    TestAny testAny = TestAny()
+      ..anyValue = any
+      ..repeatedAnyValue.addAll(<Any>[any1, any2]);
+    TestAny testAnyFromBuffer = TestAny.fromBuffer(testAny.writeToBuffer());
+    expect(testAnyFromBuffer.anyValue.unpackInto(new SearchRequest()).query,
+        'hest');
+    expect(
+        testAnyFromBuffer.repeatedAnyValue[0]
+            .unpackInto(new SearchRequest())
+            .query,
+        'hest1');
+    expect(
+        testAnyFromBuffer.repeatedAnyValue[1]
+            .unpackInto(new SearchRequest())
+            .query,
+        'hest2');
+  });
+}
diff --git a/test/enum_generator_test.dart b/test/enum_generator_test.dart
index 6c644c5..a5f8fc5 100755
--- a/test/enum_generator_test.dart
+++ b/test/enum_generator_test.dart
@@ -31,7 +31,9 @@
           ..number = 2
       ]);
     IndentingWriter writer = new IndentingWriter();
-    EnumGenerator eg = new EnumGenerator(ed, null);
+    FileGenerator fg =
+        new FileGenerator(new FileDescriptorProto(), new GenerationOptions());
+    EnumGenerator eg = new EnumGenerator(ed, fg);
     eg.generate(writer);
     expectMatchesGoldenFile(writer.toString(), 'test/goldens/enum');
   });
diff --git a/test/extension_test.dart b/test/extension_test.dart
index 3cb212f..9a015b6 100644
--- a/test/extension_test.dart
+++ b/test/extension_test.dart
@@ -80,13 +80,13 @@
       message.setExtension(Unittest.optionalInt32Extension, 0);
     },
         throwsArgError(
-            "Extension optionalInt32Extension not legal for message TestAllTypes"));
+            "Extension optionalInt32Extension not legal for message protobuf_unittest.TestAllTypes"));
 
     expect(() {
       message.getExtension(Unittest.optionalInt32Extension);
     },
         throwsArgError(
-            "Extension optionalInt32Extension not legal for message TestAllTypes"));
+            "Extension optionalInt32Extension not legal for message protobuf_unittest.TestAllTypes"));
   });
 
   test("throws if an int32 extension is set to a bad value", () {
@@ -95,7 +95,7 @@
       message.setExtension(Unittest.optionalInt32Extension, "hello");
     },
         throwsArgError(
-            "Illegal to set field optionalInt32Extension (1) of TestAllExtensions"
+            "Illegal to set field optionalInt32Extension (1) of protobuf_unittest.TestAllExtensions"
             " to value (hello): not type int"));
   });
 
@@ -105,7 +105,7 @@
       message.setExtension(Unittest.optionalInt64Extension, 123);
     },
         throwsArgError(
-            "Illegal to set field optionalInt64Extension (2) of TestAllExtensions"
+            "Illegal to set field optionalInt64Extension (2) of protobuf_unittest.TestAllExtensions"
             " to value (123): not Int64"));
   });
 
@@ -118,7 +118,7 @@
     },
         throwsArgError(
             "Illegal to set field optionalNestedMessageExtension (18)"
-            " of TestAllExtensions to value (123): not a GeneratedMessage"));
+            " of protobuf_unittest.TestAllExtensions to value (123): not a GeneratedMessage"));
 
     // For a repeated message, the type check is exact.
     expect(() {
@@ -135,7 +135,7 @@
       message.setExtension(Unittest.optionalNestedEnumExtension, 123);
     },
         throwsArgError("Illegal to set field optionalNestedEnumExtension (21)"
-            " of TestAllExtensions to value (123): not type ProtobufEnum"));
+            " of protobuf_unittest.TestAllExtensions to value (123): not type ProtobufEnum"));
 
     // For a repeated enum, the type check is exact.
     expect(() {
diff --git a/test/goldens/grpc_service.pb b/test/goldens/grpc_service.pb
index d2be7d6..6bca039 100644
--- a/test/goldens/grpc_service.pb
+++ b/test/goldens/grpc_service.pb
@@ -24,7 +24,7 @@
   static Empty getDefault() => _defaultInstance ??= create()..freeze();
   static Empty _defaultInstance;
   static void $checkItem(Empty v) {
-    if (v is! Empty) $pb.checkItemFailed(v, 'Empty');
+    if (v is! Empty) $pb.checkItemFailed(v, _i.messageName);
   }
 }
 
diff --git a/test/goldens/imports.pb b/test/goldens/imports.pb
index f313beb..31f37c1 100644
--- a/test/goldens/imports.pb
+++ b/test/goldens/imports.pb
@@ -30,7 +30,7 @@
   static M getDefault() => _defaultInstance ??= create()..freeze();
   static M _defaultInstance;
   static void $checkItem(M v) {
-    if (v is! M) $pb.checkItemFailed(v, 'M');
+    if (v is! M) $pb.checkItemFailed(v, _i.messageName);
   }
 
   M get m => $_getN(0);
diff --git a/test/goldens/messageGenerator b/test/goldens/messageGenerator
index a54f47f..db6ea74 100644
--- a/test/goldens/messageGenerator
+++ b/test/goldens/messageGenerator
@@ -16,7 +16,7 @@
   static PhoneNumber getDefault() => _defaultInstance ??= create()..freeze();
   static PhoneNumber _defaultInstance;
   static void $checkItem(PhoneNumber v) {
-    if (v is! PhoneNumber) $pb.checkItemFailed(v, 'PhoneNumber');
+    if (v is! PhoneNumber) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get number => $_getS(0, '');
diff --git a/test/goldens/oneMessage.pb b/test/goldens/oneMessage.pb
index 7b6ba5d..f952864 100644
--- a/test/goldens/oneMessage.pb
+++ b/test/goldens/oneMessage.pb
@@ -26,7 +26,7 @@
   static PhoneNumber getDefault() => _defaultInstance ??= create()..freeze();
   static PhoneNumber _defaultInstance;
   static void $checkItem(PhoneNumber v) {
-    if (v is! PhoneNumber) $pb.checkItemFailed(v, 'PhoneNumber');
+    if (v is! PhoneNumber) $pb.checkItemFailed(v, _i.messageName);
   }
 
   String get number => $_getS(0, '');
diff --git a/test/goldens/service.pb b/test/goldens/service.pb
index 50fd16b..72a7084 100644
--- a/test/goldens/service.pb
+++ b/test/goldens/service.pb
@@ -25,7 +25,7 @@
   static Empty getDefault() => _defaultInstance ??= create()..freeze();
   static Empty _defaultInstance;
   static void $checkItem(Empty v) {
-    if (v is! Empty) $pb.checkItemFailed(v, 'Empty');
+    if (v is! Empty) $pb.checkItemFailed(v, _i.messageName);
   }
 }
 
diff --git a/test/map_test.dart b/test/map_test.dart
index 4dd0741..b5837c7 100644
--- a/test/map_test.dart
+++ b/test/map_test.dart
@@ -56,7 +56,9 @@
     var rec = new pb.Rec();
     expect(() {
       rec["unknown"] = 123;
-    }, throwsError(ArgumentError, "field 'unknown' not found in Rec"));
+    },
+        throwsError(ArgumentError,
+            "field 'unknown' not found in protobuf_unittest.Rec"));
   });
 
   test('operator []= throws exception for repeated field', () {
@@ -111,7 +113,9 @@
     rec.str = "hello";
     expect(() {
       rec.remove("str");
-    }, throwsError(UnsupportedError, "remove() not supported by Rec"));
+    },
+        throwsError(UnsupportedError,
+            "remove() not supported by protobuf_unittest.Rec"));
     expect(rec.str, "hello");
   });
 
diff --git a/test/protos/google/protobuf/any.proto b/test/protos/google/protobuf/any.proto
new file mode 100644
index 0000000..4932942
--- /dev/null
+++ b/test/protos/google/protobuf/any.proto
@@ -0,0 +1,154 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package google.protobuf;
+
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "github.com/golang/protobuf/ptypes/any";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "AnyProto";
+option java_multiple_files = true;
+option objc_class_prefix = "GPB";
+
+// `Any` contains an arbitrary serialized protocol buffer message along with a
+// URL that describes the type of the serialized message.
+//
+// Protobuf library provides support to pack/unpack Any values in the form
+// of utility functions or additional generated methods of the Any type.
+//
+// Example 1: Pack and unpack a message in C++.
+//
+//     Foo foo = ...;
+//     Any any;
+//     any.PackFrom(foo);
+//     ...
+//     if (any.UnpackTo(&foo)) {
+//       ...
+//     }
+//
+// Example 2: Pack and unpack a message in Java.
+//
+//     Foo foo = ...;
+//     Any any = Any.pack(foo);
+//     ...
+//     if (any.is(Foo.class)) {
+//       foo = any.unpack(Foo.class);
+//     }
+//
+//  Example 3: Pack and unpack a message in Python.
+//
+//     foo = Foo(...)
+//     any = Any()
+//     any.Pack(foo)
+//     ...
+//     if any.Is(Foo.DESCRIPTOR):
+//       any.Unpack(foo)
+//       ...
+//
+//  Example 4: Pack and unpack a message in Go
+//
+//      foo := &pb.Foo{...}
+//      any, err := ptypes.MarshalAny(foo)
+//      ...
+//      foo := &pb.Foo{}
+//      if err := ptypes.UnmarshalAny(any, foo); err != nil {
+//        ...
+//      }
+//
+// The pack methods provided by protobuf library will by default use
+// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+// methods only use the fully qualified type name after the last '/'
+// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+// name "y.z".
+//
+//
+// JSON
+// ====
+// The JSON representation of an `Any` value uses the regular
+// representation of the deserialized, embedded message, with an
+// additional field `@type` which contains the type URL. Example:
+//
+//     package google.profile;
+//     message Person {
+//       string first_name = 1;
+//       string last_name = 2;
+//     }
+//
+//     {
+//       "@type": "type.googleapis.com/google.profile.Person",
+//       "firstName": <string>,
+//       "lastName": <string>
+//     }
+//
+// If the embedded message type is well-known and has a custom JSON
+// representation, that representation will be embedded adding a field
+// `value` which holds the custom JSON in addition to the `@type`
+// field. Example (for message [google.protobuf.Duration][]):
+//
+//     {
+//       "@type": "type.googleapis.com/google.protobuf.Duration",
+//       "value": "1.212s"
+//     }
+//
+message Any {
+  // A URL/resource name that uniquely identifies the type of the serialized
+  // protocol buffer message. The last segment of the URL's path must represent
+  // the fully qualified name of the type (as in
+  // `path/google.protobuf.Duration`). The name should be in a canonical form
+  // (e.g., leading "." is not accepted).
+  //
+  // In practice, teams usually precompile into the binary all types that they
+  // expect it to use in the context of Any. However, for URLs which use the
+  // scheme `http`, `https`, or no scheme, one can optionally set up a type
+  // server that maps type URLs to message definitions as follows:
+  //
+  // * If no scheme is provided, `https` is assumed.
+  // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+  //   value in binary format, or produce an error.
+  // * Applications are allowed to cache lookup results based on the
+  //   URL, or have them precompiled into a binary to avoid any
+  //   lookup. Therefore, binary compatibility needs to be preserved
+  //   on changes to types. (Use versioned type names to manage
+  //   breaking changes.)
+  //
+  // Note: this functionality is not currently available in the official
+  // protobuf release, and it is not used for type URLs beginning with
+  // type.googleapis.com.
+  //
+  // Schemes other than `http`, `https` (or the empty scheme) might be
+  // used with implementation specific semantics.
+  //
+  string type_url = 1;
+
+  // Must be a valid serialized protocol buffer of the above specified type.
+  bytes value = 2;
+}
diff --git a/test/protos/using_any.proto b/test/protos/using_any.proto
new file mode 100644
index 0000000..8cfd0cb
--- /dev/null
+++ b/test/protos/using_any.proto
@@ -0,0 +1,21 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+syntax = "proto3";
+
+package protobuf_unittest;
+
+import "google/protobuf/any.proto";
+
+message TestAny {
+  int32 int32_value = 1;
+  google.protobuf.Any any_value = 2;
+  repeated google.protobuf.Any repeated_any_value = 3;
+}
+
+message Container {
+  message Nested {
+    int32 int32_value = 1;
+  }
+}