Sync internal change adding support for freezable messages. (#120)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7f2540b..23744cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.9.0
+
+* Breaking change: Add `copyWith()` to message classes and update `getDefault()` to use `freeze()`.
+  Requires package:protobuf version 0.10.0 or newer.
+
 ## 0.8.2
 
 * Generated code now imports 'package:protobuf/protobuf.dart' prefixed.
diff --git a/lib/message_generator.dart b/lib/message_generator.dart
index 0619b80..19962a9 100644
--- a/lib/message_generator.dart
+++ b/lib/message_generator.dart
@@ -239,6 +239,8 @@
           ' : super.fromJson(i, r);');
       out.println('${classname} clone() =>'
           ' new ${classname}()..mergeFromMessage(this);');
+      out.println('$classname copyWith(void Function($classname) updates) =>'
+          ' super.copyWith((message) => updates(message as $classname));');
 
       out.println('$_protobufImportPrefix.BuilderInfo get info_ => _i;');
 
@@ -248,11 +250,8 @@
       out.println(
           'static $_protobufImportPrefix.PbList<${classname}> createRepeated() =>'
           ' new $_protobufImportPrefix.PbList<${classname}>();');
-      out.addBlock('static ${classname} getDefault() {', '}', () {
-        out.println(
-            'if (_defaultInstance == null) _defaultInstance = new _Readonly${classname}();');
-        out.println('return _defaultInstance;');
-      });
+      out.println(
+          'static ${classname} getDefault() => _defaultInstance ??= create()..freeze();');
       out.println('static ${classname} _defaultInstance;');
       out.addBlock('static void $checkItem($classname v) {', '}', () {
         out.println('if (v is! $classname)'
@@ -261,10 +260,6 @@
       generateFieldsAccessorsMutators(out);
     });
     out.println();
-
-    out.println(
-        'class _Readonly${classname} extends ${classname} with $_protobufImportPrefix.ReadonlyMessageMixin {}');
-    out.println();
   }
 
   // Returns true if the message type has any required fields.  If it doesn't,
diff --git a/lib/src/dart_options.pb.dart b/lib/src/dart_options.pb.dart
index 149a166..b4d45c5 100644
--- a/lib/src/dart_options.pb.dart
+++ b/lib/src/dart_options.pb.dart
@@ -23,14 +23,12 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   DartMixin clone() => new DartMixin()..mergeFromMessage(this);
+  DartMixin copyWith(void Function(DartMixin) updates) =>
+      super.copyWith((message) => updates(message as DartMixin));
   $pb.BuilderInfo get info_ => _i;
   static DartMixin create() => new DartMixin();
   static $pb.PbList<DartMixin> createRepeated() => new $pb.PbList<DartMixin>();
-  static DartMixin getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyDartMixin();
-    return _defaultInstance;
-  }
-
+  static DartMixin getDefault() => _defaultInstance ??= create()..freeze();
   static DartMixin _defaultInstance;
   static void $checkItem(DartMixin v) {
     if (v is! DartMixin) $pb.checkItemFailed(v, 'DartMixin');
@@ -61,8 +59,6 @@
   void clearParent() => clearField(3);
 }
 
-class _ReadonlyDartMixin extends DartMixin with $pb.ReadonlyMessageMixin {}
-
 class Imports extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Imports')
     ..pp<DartMixin>(
@@ -77,14 +73,12 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   Imports clone() => new Imports()..mergeFromMessage(this);
+  Imports copyWith(void Function(Imports) updates) =>
+      super.copyWith((message) => updates(message as Imports));
   $pb.BuilderInfo get info_ => _i;
   static Imports create() => new Imports();
   static $pb.PbList<Imports> createRepeated() => new $pb.PbList<Imports>();
-  static Imports getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyImports();
-    return _defaultInstance;
-  }
-
+  static Imports getDefault() => _defaultInstance ??= create()..freeze();
   static Imports _defaultInstance;
   static void $checkItem(Imports v) {
     if (v is! Imports) $pb.checkItemFailed(v, 'Imports');
@@ -93,8 +87,6 @@
   List<DartMixin> get mixins => $_getList(0);
 }
 
-class _ReadonlyImports extends Imports with $pb.ReadonlyMessageMixin {}
-
 class Dart_options {
   static final $pb.Extension imports = new $pb.Extension<Imports>(
       'FileOptions',
diff --git a/lib/src/descriptor.pb.dart b/lib/src/descriptor.pb.dart
index fa76b84..b6c3c8e 100644
--- a/lib/src/descriptor.pb.dart
+++ b/lib/src/descriptor.pb.dart
@@ -26,16 +26,14 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   FileDescriptorSet clone() => new FileDescriptorSet()..mergeFromMessage(this);
+  FileDescriptorSet copyWith(void Function(FileDescriptorSet) updates) =>
+      super.copyWith((message) => updates(message as FileDescriptorSet));
   $pb.BuilderInfo get info_ => _i;
   static FileDescriptorSet create() => new FileDescriptorSet();
   static $pb.PbList<FileDescriptorSet> createRepeated() =>
       new $pb.PbList<FileDescriptorSet>();
-  static FileDescriptorSet getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyFileDescriptorSet();
-    return _defaultInstance;
-  }
-
+  static FileDescriptorSet getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static FileDescriptorSet _defaultInstance;
   static void $checkItem(FileDescriptorSet v) {
     if (v is! FileDescriptorSet) $pb.checkItemFailed(v, 'FileDescriptorSet');
@@ -44,9 +42,6 @@
   List<FileDescriptorProto> get file => $_getList(0);
 }
 
-class _ReadonlyFileDescriptorSet extends FileDescriptorSet
-    with $pb.ReadonlyMessageMixin {}
-
 class FileDescriptorProto extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FileDescriptorProto')
     ..aOS(1, 'name')
@@ -77,16 +72,14 @@
       : super.fromJson(i, r);
   FileDescriptorProto clone() =>
       new FileDescriptorProto()..mergeFromMessage(this);
+  FileDescriptorProto copyWith(void Function(FileDescriptorProto) updates) =>
+      super.copyWith((message) => updates(message as FileDescriptorProto));
   $pb.BuilderInfo get info_ => _i;
   static FileDescriptorProto create() => new FileDescriptorProto();
   static $pb.PbList<FileDescriptorProto> createRepeated() =>
       new $pb.PbList<FileDescriptorProto>();
-  static FileDescriptorProto getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyFileDescriptorProto();
-    return _defaultInstance;
-  }
-
+  static FileDescriptorProto getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static FileDescriptorProto _defaultInstance;
   static void $checkItem(FileDescriptorProto v) {
     if (v is! FileDescriptorProto)
@@ -148,9 +141,6 @@
   void clearSyntax() => clearField(12);
 }
 
-class _ReadonlyFileDescriptorProto extends FileDescriptorProto
-    with $pb.ReadonlyMessageMixin {}
-
 class DescriptorProto_ExtensionRange extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i =
       new $pb.BuilderInfo('DescriptorProto_ExtensionRange')
@@ -167,17 +157,17 @@
       : super.fromJson(i, r);
   DescriptorProto_ExtensionRange clone() =>
       new DescriptorProto_ExtensionRange()..mergeFromMessage(this);
+  DescriptorProto_ExtensionRange copyWith(
+          void Function(DescriptorProto_ExtensionRange) updates) =>
+      super.copyWith(
+          (message) => updates(message as DescriptorProto_ExtensionRange));
   $pb.BuilderInfo get info_ => _i;
   static DescriptorProto_ExtensionRange create() =>
       new DescriptorProto_ExtensionRange();
   static $pb.PbList<DescriptorProto_ExtensionRange> createRepeated() =>
       new $pb.PbList<DescriptorProto_ExtensionRange>();
-  static DescriptorProto_ExtensionRange getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyDescriptorProto_ExtensionRange();
-    return _defaultInstance;
-  }
-
+  static DescriptorProto_ExtensionRange getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static DescriptorProto_ExtensionRange _defaultInstance;
   static void $checkItem(DescriptorProto_ExtensionRange v) {
     if (v is! DescriptorProto_ExtensionRange)
@@ -201,9 +191,6 @@
   void clearEnd() => clearField(2);
 }
 
-class _ReadonlyDescriptorProto_ExtensionRange
-    extends DescriptorProto_ExtensionRange with $pb.ReadonlyMessageMixin {}
-
 class DescriptorProto_ReservedRange extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i =
       new $pb.BuilderInfo('DescriptorProto_ReservedRange')
@@ -220,17 +207,17 @@
       : super.fromJson(i, r);
   DescriptorProto_ReservedRange clone() =>
       new DescriptorProto_ReservedRange()..mergeFromMessage(this);
+  DescriptorProto_ReservedRange copyWith(
+          void Function(DescriptorProto_ReservedRange) updates) =>
+      super.copyWith(
+          (message) => updates(message as DescriptorProto_ReservedRange));
   $pb.BuilderInfo get info_ => _i;
   static DescriptorProto_ReservedRange create() =>
       new DescriptorProto_ReservedRange();
   static $pb.PbList<DescriptorProto_ReservedRange> createRepeated() =>
       new $pb.PbList<DescriptorProto_ReservedRange>();
-  static DescriptorProto_ReservedRange getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyDescriptorProto_ReservedRange();
-    return _defaultInstance;
-  }
-
+  static DescriptorProto_ReservedRange getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static DescriptorProto_ReservedRange _defaultInstance;
   static void $checkItem(DescriptorProto_ReservedRange v) {
     if (v is! DescriptorProto_ReservedRange)
@@ -254,9 +241,6 @@
   void clearEnd() => clearField(2);
 }
 
-class _ReadonlyDescriptorProto_ReservedRange
-    extends DescriptorProto_ReservedRange with $pb.ReadonlyMessageMixin {}
-
 class DescriptorProto extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('DescriptorProto')
     ..aOS(1, 'name')
@@ -294,16 +278,14 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   DescriptorProto clone() => new DescriptorProto()..mergeFromMessage(this);
+  DescriptorProto copyWith(void Function(DescriptorProto) updates) =>
+      super.copyWith((message) => updates(message as DescriptorProto));
   $pb.BuilderInfo get info_ => _i;
   static DescriptorProto create() => new DescriptorProto();
   static $pb.PbList<DescriptorProto> createRepeated() =>
       new $pb.PbList<DescriptorProto>();
-  static DescriptorProto getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyDescriptorProto();
-    return _defaultInstance;
-  }
-
+  static DescriptorProto getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static DescriptorProto _defaultInstance;
   static void $checkItem(DescriptorProto v) {
     if (v is! DescriptorProto) $pb.checkItemFailed(v, 'DescriptorProto');
@@ -342,9 +324,6 @@
   List<String> get reservedName => $_getList(9);
 }
 
-class _ReadonlyDescriptorProto extends DescriptorProto
-    with $pb.ReadonlyMessageMixin {}
-
 class FieldDescriptorProto extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FieldDescriptorProto')
     ..aOS(1, 'name')
@@ -380,16 +359,14 @@
       : super.fromJson(i, r);
   FieldDescriptorProto clone() =>
       new FieldDescriptorProto()..mergeFromMessage(this);
+  FieldDescriptorProto copyWith(void Function(FieldDescriptorProto) updates) =>
+      super.copyWith((message) => updates(message as FieldDescriptorProto));
   $pb.BuilderInfo get info_ => _i;
   static FieldDescriptorProto create() => new FieldDescriptorProto();
   static $pb.PbList<FieldDescriptorProto> createRepeated() =>
       new $pb.PbList<FieldDescriptorProto>();
-  static FieldDescriptorProto getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyFieldDescriptorProto();
-    return _defaultInstance;
-  }
-
+  static FieldDescriptorProto getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static FieldDescriptorProto _defaultInstance;
   static void $checkItem(FieldDescriptorProto v) {
     if (v is! FieldDescriptorProto)
@@ -477,9 +454,6 @@
   void clearJsonName() => clearField(10);
 }
 
-class _ReadonlyFieldDescriptorProto extends FieldDescriptorProto
-    with $pb.ReadonlyMessageMixin {}
-
 class OneofDescriptorProto extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('OneofDescriptorProto')
     ..aOS(1, 'name')
@@ -495,16 +469,14 @@
       : super.fromJson(i, r);
   OneofDescriptorProto clone() =>
       new OneofDescriptorProto()..mergeFromMessage(this);
+  OneofDescriptorProto copyWith(void Function(OneofDescriptorProto) updates) =>
+      super.copyWith((message) => updates(message as OneofDescriptorProto));
   $pb.BuilderInfo get info_ => _i;
   static OneofDescriptorProto create() => new OneofDescriptorProto();
   static $pb.PbList<OneofDescriptorProto> createRepeated() =>
       new $pb.PbList<OneofDescriptorProto>();
-  static OneofDescriptorProto getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyOneofDescriptorProto();
-    return _defaultInstance;
-  }
-
+  static OneofDescriptorProto getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static OneofDescriptorProto _defaultInstance;
   static void $checkItem(OneofDescriptorProto v) {
     if (v is! OneofDescriptorProto)
@@ -528,9 +500,6 @@
   void clearOptions() => clearField(2);
 }
 
-class _ReadonlyOneofDescriptorProto extends OneofDescriptorProto
-    with $pb.ReadonlyMessageMixin {}
-
 class EnumDescriptorProto extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumDescriptorProto')
     ..aOS(1, 'name')
@@ -548,16 +517,14 @@
       : super.fromJson(i, r);
   EnumDescriptorProto clone() =>
       new EnumDescriptorProto()..mergeFromMessage(this);
+  EnumDescriptorProto copyWith(void Function(EnumDescriptorProto) updates) =>
+      super.copyWith((message) => updates(message as EnumDescriptorProto));
   $pb.BuilderInfo get info_ => _i;
   static EnumDescriptorProto create() => new EnumDescriptorProto();
   static $pb.PbList<EnumDescriptorProto> createRepeated() =>
       new $pb.PbList<EnumDescriptorProto>();
-  static EnumDescriptorProto getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyEnumDescriptorProto();
-    return _defaultInstance;
-  }
-
+  static EnumDescriptorProto getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static EnumDescriptorProto _defaultInstance;
   static void $checkItem(EnumDescriptorProto v) {
     if (v is! EnumDescriptorProto)
@@ -583,9 +550,6 @@
   void clearOptions() => clearField(3);
 }
 
-class _ReadonlyEnumDescriptorProto extends EnumDescriptorProto
-    with $pb.ReadonlyMessageMixin {}
-
 class EnumValueDescriptorProto extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i =
       new $pb.BuilderInfo('EnumValueDescriptorProto')
@@ -603,16 +567,15 @@
       : super.fromJson(i, r);
   EnumValueDescriptorProto clone() =>
       new EnumValueDescriptorProto()..mergeFromMessage(this);
+  EnumValueDescriptorProto copyWith(
+          void Function(EnumValueDescriptorProto) updates) =>
+      super.copyWith((message) => updates(message as EnumValueDescriptorProto));
   $pb.BuilderInfo get info_ => _i;
   static EnumValueDescriptorProto create() => new EnumValueDescriptorProto();
   static $pb.PbList<EnumValueDescriptorProto> createRepeated() =>
       new $pb.PbList<EnumValueDescriptorProto>();
-  static EnumValueDescriptorProto getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyEnumValueDescriptorProto();
-    return _defaultInstance;
-  }
-
+  static EnumValueDescriptorProto getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static EnumValueDescriptorProto _defaultInstance;
   static void $checkItem(EnumValueDescriptorProto v) {
     if (v is! EnumValueDescriptorProto)
@@ -644,9 +607,6 @@
   void clearOptions() => clearField(3);
 }
 
-class _ReadonlyEnumValueDescriptorProto extends EnumValueDescriptorProto
-    with $pb.ReadonlyMessageMixin {}
-
 class ServiceDescriptorProto extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i =
       new $pb.BuilderInfo('ServiceDescriptorProto')
@@ -665,16 +625,15 @@
       : super.fromJson(i, r);
   ServiceDescriptorProto clone() =>
       new ServiceDescriptorProto()..mergeFromMessage(this);
+  ServiceDescriptorProto copyWith(
+          void Function(ServiceDescriptorProto) updates) =>
+      super.copyWith((message) => updates(message as ServiceDescriptorProto));
   $pb.BuilderInfo get info_ => _i;
   static ServiceDescriptorProto create() => new ServiceDescriptorProto();
   static $pb.PbList<ServiceDescriptorProto> createRepeated() =>
       new $pb.PbList<ServiceDescriptorProto>();
-  static ServiceDescriptorProto getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyServiceDescriptorProto();
-    return _defaultInstance;
-  }
-
+  static ServiceDescriptorProto getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static ServiceDescriptorProto _defaultInstance;
   static void $checkItem(ServiceDescriptorProto v) {
     if (v is! ServiceDescriptorProto)
@@ -700,9 +659,6 @@
   void clearOptions() => clearField(3);
 }
 
-class _ReadonlyServiceDescriptorProto extends ServiceDescriptorProto
-    with $pb.ReadonlyMessageMixin {}
-
 class MethodDescriptorProto extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MethodDescriptorProto')
     ..aOS(1, 'name')
@@ -722,16 +678,15 @@
       : super.fromJson(i, r);
   MethodDescriptorProto clone() =>
       new MethodDescriptorProto()..mergeFromMessage(this);
+  MethodDescriptorProto copyWith(
+          void Function(MethodDescriptorProto) updates) =>
+      super.copyWith((message) => updates(message as MethodDescriptorProto));
   $pb.BuilderInfo get info_ => _i;
   static MethodDescriptorProto create() => new MethodDescriptorProto();
   static $pb.PbList<MethodDescriptorProto> createRepeated() =>
       new $pb.PbList<MethodDescriptorProto>();
-  static MethodDescriptorProto getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyMethodDescriptorProto();
-    return _defaultInstance;
-  }
-
+  static MethodDescriptorProto getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static MethodDescriptorProto _defaultInstance;
   static void $checkItem(MethodDescriptorProto v) {
     if (v is! MethodDescriptorProto)
@@ -787,9 +742,6 @@
   void clearServerStreaming() => clearField(6);
 }
 
-class _ReadonlyMethodDescriptorProto extends MethodDescriptorProto
-    with $pb.ReadonlyMessageMixin {}
-
 class FileOptions extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FileOptions')
     ..aOS(1, 'javaPackage')
@@ -827,15 +779,13 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   FileOptions clone() => new FileOptions()..mergeFromMessage(this);
+  FileOptions copyWith(void Function(FileOptions) updates) =>
+      super.copyWith((message) => updates(message as FileOptions));
   $pb.BuilderInfo get info_ => _i;
   static FileOptions create() => new FileOptions();
   static $pb.PbList<FileOptions> createRepeated() =>
       new $pb.PbList<FileOptions>();
-  static FileOptions getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyFileOptions();
-    return _defaultInstance;
-  }
-
+  static FileOptions getDefault() => _defaultInstance ??= create()..freeze();
   static FileOptions _defaultInstance;
   static void $checkItem(FileOptions v) {
     if (v is! FileOptions) $pb.checkItemFailed(v, 'FileOptions');
@@ -980,8 +930,6 @@
   List<UninterpretedOption> get uninterpretedOption => $_getList(17);
 }
 
-class _ReadonlyFileOptions extends FileOptions with $pb.ReadonlyMessageMixin {}
-
 class MessageOptions extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MessageOptions')
     ..aOB(1, 'messageSetWireFormat')
@@ -1000,16 +948,13 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   MessageOptions clone() => new MessageOptions()..mergeFromMessage(this);
+  MessageOptions copyWith(void Function(MessageOptions) updates) =>
+      super.copyWith((message) => updates(message as MessageOptions));
   $pb.BuilderInfo get info_ => _i;
   static MessageOptions create() => new MessageOptions();
   static $pb.PbList<MessageOptions> createRepeated() =>
       new $pb.PbList<MessageOptions>();
-  static MessageOptions getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyMessageOptions();
-    return _defaultInstance;
-  }
-
+  static MessageOptions getDefault() => _defaultInstance ??= create()..freeze();
   static MessageOptions _defaultInstance;
   static void $checkItem(MessageOptions v) {
     if (v is! MessageOptions) $pb.checkItemFailed(v, 'MessageOptions');
@@ -1050,9 +995,6 @@
   List<UninterpretedOption> get uninterpretedOption => $_getList(4);
 }
 
-class _ReadonlyMessageOptions extends MessageOptions
-    with $pb.ReadonlyMessageMixin {}
-
 class FieldOptions extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('FieldOptions')
     ..e<FieldOptions_CType>(
@@ -1085,16 +1027,13 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   FieldOptions clone() => new FieldOptions()..mergeFromMessage(this);
+  FieldOptions copyWith(void Function(FieldOptions) updates) =>
+      super.copyWith((message) => updates(message as FieldOptions));
   $pb.BuilderInfo get info_ => _i;
   static FieldOptions create() => new FieldOptions();
   static $pb.PbList<FieldOptions> createRepeated() =>
       new $pb.PbList<FieldOptions>();
-  static FieldOptions getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyFieldOptions();
-    return _defaultInstance;
-  }
-
+  static FieldOptions getDefault() => _defaultInstance ??= create()..freeze();
   static FieldOptions _defaultInstance;
   static void $checkItem(FieldOptions v) {
     if (v is! FieldOptions) $pb.checkItemFailed(v, 'FieldOptions');
@@ -1151,9 +1090,6 @@
   List<UninterpretedOption> get uninterpretedOption => $_getList(6);
 }
 
-class _ReadonlyFieldOptions extends FieldOptions with $pb.ReadonlyMessageMixin {
-}
-
 class OneofOptions extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('OneofOptions')
     ..pp<UninterpretedOption>(999, 'uninterpretedOption', $pb.PbFieldType.PM,
@@ -1168,16 +1104,13 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   OneofOptions clone() => new OneofOptions()..mergeFromMessage(this);
+  OneofOptions copyWith(void Function(OneofOptions) updates) =>
+      super.copyWith((message) => updates(message as OneofOptions));
   $pb.BuilderInfo get info_ => _i;
   static OneofOptions create() => new OneofOptions();
   static $pb.PbList<OneofOptions> createRepeated() =>
       new $pb.PbList<OneofOptions>();
-  static OneofOptions getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyOneofOptions();
-    return _defaultInstance;
-  }
-
+  static OneofOptions getDefault() => _defaultInstance ??= create()..freeze();
   static OneofOptions _defaultInstance;
   static void $checkItem(OneofOptions v) {
     if (v is! OneofOptions) $pb.checkItemFailed(v, 'OneofOptions');
@@ -1186,9 +1119,6 @@
   List<UninterpretedOption> get uninterpretedOption => $_getList(0);
 }
 
-class _ReadonlyOneofOptions extends OneofOptions with $pb.ReadonlyMessageMixin {
-}
-
 class EnumOptions extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumOptions')
     ..aOB(2, 'allowAlias')
@@ -1205,15 +1135,13 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   EnumOptions clone() => new EnumOptions()..mergeFromMessage(this);
+  EnumOptions copyWith(void Function(EnumOptions) updates) =>
+      super.copyWith((message) => updates(message as EnumOptions));
   $pb.BuilderInfo get info_ => _i;
   static EnumOptions create() => new EnumOptions();
   static $pb.PbList<EnumOptions> createRepeated() =>
       new $pb.PbList<EnumOptions>();
-  static EnumOptions getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyEnumOptions();
-    return _defaultInstance;
-  }
-
+  static EnumOptions getDefault() => _defaultInstance ??= create()..freeze();
   static EnumOptions _defaultInstance;
   static void $checkItem(EnumOptions v) {
     if (v is! EnumOptions) $pb.checkItemFailed(v, 'EnumOptions');
@@ -1238,8 +1166,6 @@
   List<UninterpretedOption> get uninterpretedOption => $_getList(2);
 }
 
-class _ReadonlyEnumOptions extends EnumOptions with $pb.ReadonlyMessageMixin {}
-
 class EnumValueOptions extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EnumValueOptions')
     ..aOB(1, 'deprecated')
@@ -1255,16 +1181,14 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   EnumValueOptions clone() => new EnumValueOptions()..mergeFromMessage(this);
+  EnumValueOptions copyWith(void Function(EnumValueOptions) updates) =>
+      super.copyWith((message) => updates(message as EnumValueOptions));
   $pb.BuilderInfo get info_ => _i;
   static EnumValueOptions create() => new EnumValueOptions();
   static $pb.PbList<EnumValueOptions> createRepeated() =>
       new $pb.PbList<EnumValueOptions>();
-  static EnumValueOptions getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyEnumValueOptions();
-    return _defaultInstance;
-  }
-
+  static EnumValueOptions getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static EnumValueOptions _defaultInstance;
   static void $checkItem(EnumValueOptions v) {
     if (v is! EnumValueOptions) $pb.checkItemFailed(v, 'EnumValueOptions');
@@ -1281,9 +1205,6 @@
   List<UninterpretedOption> get uninterpretedOption => $_getList(1);
 }
 
-class _ReadonlyEnumValueOptions extends EnumValueOptions
-    with $pb.ReadonlyMessageMixin {}
-
 class ServiceOptions extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ServiceOptions')
     ..aOB(33, 'deprecated')
@@ -1299,16 +1220,13 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   ServiceOptions clone() => new ServiceOptions()..mergeFromMessage(this);
+  ServiceOptions copyWith(void Function(ServiceOptions) updates) =>
+      super.copyWith((message) => updates(message as ServiceOptions));
   $pb.BuilderInfo get info_ => _i;
   static ServiceOptions create() => new ServiceOptions();
   static $pb.PbList<ServiceOptions> createRepeated() =>
       new $pb.PbList<ServiceOptions>();
-  static ServiceOptions getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyServiceOptions();
-    return _defaultInstance;
-  }
-
+  static ServiceOptions getDefault() => _defaultInstance ??= create()..freeze();
   static ServiceOptions _defaultInstance;
   static void $checkItem(ServiceOptions v) {
     if (v is! ServiceOptions) $pb.checkItemFailed(v, 'ServiceOptions');
@@ -1325,9 +1243,6 @@
   List<UninterpretedOption> get uninterpretedOption => $_getList(1);
 }
 
-class _ReadonlyServiceOptions extends ServiceOptions
-    with $pb.ReadonlyMessageMixin {}
-
 class MethodOptions extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('MethodOptions')
     ..aOB(33, 'deprecated')
@@ -1350,16 +1265,13 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   MethodOptions clone() => new MethodOptions()..mergeFromMessage(this);
+  MethodOptions copyWith(void Function(MethodOptions) updates) =>
+      super.copyWith((message) => updates(message as MethodOptions));
   $pb.BuilderInfo get info_ => _i;
   static MethodOptions create() => new MethodOptions();
   static $pb.PbList<MethodOptions> createRepeated() =>
       new $pb.PbList<MethodOptions>();
-  static MethodOptions getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyMethodOptions();
-    return _defaultInstance;
-  }
-
+  static MethodOptions getDefault() => _defaultInstance ??= create()..freeze();
   static MethodOptions _defaultInstance;
   static void $checkItem(MethodOptions v) {
     if (v is! MethodOptions) $pb.checkItemFailed(v, 'MethodOptions');
@@ -1384,9 +1296,6 @@
   List<UninterpretedOption> get uninterpretedOption => $_getList(2);
 }
 
-class _ReadonlyMethodOptions extends MethodOptions
-    with $pb.ReadonlyMessageMixin {}
-
 class UninterpretedOption_NamePart extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i =
       new $pb.BuilderInfo('UninterpretedOption_NamePart')
@@ -1402,17 +1311,17 @@
       : super.fromJson(i, r);
   UninterpretedOption_NamePart clone() =>
       new UninterpretedOption_NamePart()..mergeFromMessage(this);
+  UninterpretedOption_NamePart copyWith(
+          void Function(UninterpretedOption_NamePart) updates) =>
+      super.copyWith(
+          (message) => updates(message as UninterpretedOption_NamePart));
   $pb.BuilderInfo get info_ => _i;
   static UninterpretedOption_NamePart create() =>
       new UninterpretedOption_NamePart();
   static $pb.PbList<UninterpretedOption_NamePart> createRepeated() =>
       new $pb.PbList<UninterpretedOption_NamePart>();
-  static UninterpretedOption_NamePart getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyUninterpretedOption_NamePart();
-    return _defaultInstance;
-  }
-
+  static UninterpretedOption_NamePart getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static UninterpretedOption_NamePart _defaultInstance;
   static void $checkItem(UninterpretedOption_NamePart v) {
     if (v is! UninterpretedOption_NamePart)
@@ -1436,9 +1345,6 @@
   void clearIsExtension() => clearField(2);
 }
 
-class _ReadonlyUninterpretedOption_NamePart extends UninterpretedOption_NamePart
-    with $pb.ReadonlyMessageMixin {}
-
 class UninterpretedOption extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('UninterpretedOption')
     ..pp<UninterpretedOption_NamePart>(
@@ -1463,16 +1369,14 @@
       : super.fromJson(i, r);
   UninterpretedOption clone() =>
       new UninterpretedOption()..mergeFromMessage(this);
+  UninterpretedOption copyWith(void Function(UninterpretedOption) updates) =>
+      super.copyWith((message) => updates(message as UninterpretedOption));
   $pb.BuilderInfo get info_ => _i;
   static UninterpretedOption create() => new UninterpretedOption();
   static $pb.PbList<UninterpretedOption> createRepeated() =>
       new $pb.PbList<UninterpretedOption>();
-  static UninterpretedOption getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyUninterpretedOption();
-    return _defaultInstance;
-  }
-
+  static UninterpretedOption getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static UninterpretedOption _defaultInstance;
   static void $checkItem(UninterpretedOption v) {
     if (v is! UninterpretedOption)
@@ -1530,9 +1434,6 @@
   void clearAggregateValue() => clearField(8);
 }
 
-class _ReadonlyUninterpretedOption extends UninterpretedOption
-    with $pb.ReadonlyMessageMixin {}
-
 class SourceCodeInfo_Location extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i =
       new $pb.BuilderInfo('SourceCodeInfo_Location')
@@ -1552,16 +1453,15 @@
       : super.fromJson(i, r);
   SourceCodeInfo_Location clone() =>
       new SourceCodeInfo_Location()..mergeFromMessage(this);
+  SourceCodeInfo_Location copyWith(
+          void Function(SourceCodeInfo_Location) updates) =>
+      super.copyWith((message) => updates(message as SourceCodeInfo_Location));
   $pb.BuilderInfo get info_ => _i;
   static SourceCodeInfo_Location create() => new SourceCodeInfo_Location();
   static $pb.PbList<SourceCodeInfo_Location> createRepeated() =>
       new $pb.PbList<SourceCodeInfo_Location>();
-  static SourceCodeInfo_Location getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlySourceCodeInfo_Location();
-    return _defaultInstance;
-  }
-
+  static SourceCodeInfo_Location getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static SourceCodeInfo_Location _defaultInstance;
   static void $checkItem(SourceCodeInfo_Location v) {
     if (v is! SourceCodeInfo_Location)
@@ -1591,9 +1491,6 @@
   List<String> get leadingDetachedComments => $_getList(4);
 }
 
-class _ReadonlySourceCodeInfo_Location extends SourceCodeInfo_Location
-    with $pb.ReadonlyMessageMixin {}
-
 class SourceCodeInfo extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('SourceCodeInfo')
     ..pp<SourceCodeInfo_Location>(1, 'location', $pb.PbFieldType.PM,
@@ -1608,16 +1505,13 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   SourceCodeInfo clone() => new SourceCodeInfo()..mergeFromMessage(this);
+  SourceCodeInfo copyWith(void Function(SourceCodeInfo) updates) =>
+      super.copyWith((message) => updates(message as SourceCodeInfo));
   $pb.BuilderInfo get info_ => _i;
   static SourceCodeInfo create() => new SourceCodeInfo();
   static $pb.PbList<SourceCodeInfo> createRepeated() =>
       new $pb.PbList<SourceCodeInfo>();
-  static SourceCodeInfo getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlySourceCodeInfo();
-    return _defaultInstance;
-  }
-
+  static SourceCodeInfo getDefault() => _defaultInstance ??= create()..freeze();
   static SourceCodeInfo _defaultInstance;
   static void $checkItem(SourceCodeInfo v) {
     if (v is! SourceCodeInfo) $pb.checkItemFailed(v, 'SourceCodeInfo');
@@ -1626,9 +1520,6 @@
   List<SourceCodeInfo_Location> get location => $_getList(0);
 }
 
-class _ReadonlySourceCodeInfo extends SourceCodeInfo
-    with $pb.ReadonlyMessageMixin {}
-
 class GeneratedCodeInfo_Annotation extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i =
       new $pb.BuilderInfo('GeneratedCodeInfo_Annotation')
@@ -1647,17 +1538,17 @@
       : super.fromJson(i, r);
   GeneratedCodeInfo_Annotation clone() =>
       new GeneratedCodeInfo_Annotation()..mergeFromMessage(this);
+  GeneratedCodeInfo_Annotation copyWith(
+          void Function(GeneratedCodeInfo_Annotation) updates) =>
+      super.copyWith(
+          (message) => updates(message as GeneratedCodeInfo_Annotation));
   $pb.BuilderInfo get info_ => _i;
   static GeneratedCodeInfo_Annotation create() =>
       new GeneratedCodeInfo_Annotation();
   static $pb.PbList<GeneratedCodeInfo_Annotation> createRepeated() =>
       new $pb.PbList<GeneratedCodeInfo_Annotation>();
-  static GeneratedCodeInfo_Annotation getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyGeneratedCodeInfo_Annotation();
-    return _defaultInstance;
-  }
-
+  static GeneratedCodeInfo_Annotation getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static GeneratedCodeInfo_Annotation _defaultInstance;
   static void $checkItem(GeneratedCodeInfo_Annotation v) {
     if (v is! GeneratedCodeInfo_Annotation)
@@ -1691,9 +1582,6 @@
   void clearEnd() => clearField(4);
 }
 
-class _ReadonlyGeneratedCodeInfo_Annotation extends GeneratedCodeInfo_Annotation
-    with $pb.ReadonlyMessageMixin {}
-
 class GeneratedCodeInfo extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('GeneratedCodeInfo')
     ..pp<GeneratedCodeInfo_Annotation>(
@@ -1712,16 +1600,14 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   GeneratedCodeInfo clone() => new GeneratedCodeInfo()..mergeFromMessage(this);
+  GeneratedCodeInfo copyWith(void Function(GeneratedCodeInfo) updates) =>
+      super.copyWith((message) => updates(message as GeneratedCodeInfo));
   $pb.BuilderInfo get info_ => _i;
   static GeneratedCodeInfo create() => new GeneratedCodeInfo();
   static $pb.PbList<GeneratedCodeInfo> createRepeated() =>
       new $pb.PbList<GeneratedCodeInfo>();
-  static GeneratedCodeInfo getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyGeneratedCodeInfo();
-    return _defaultInstance;
-  }
-
+  static GeneratedCodeInfo getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static GeneratedCodeInfo _defaultInstance;
   static void $checkItem(GeneratedCodeInfo v) {
     if (v is! GeneratedCodeInfo) $pb.checkItemFailed(v, 'GeneratedCodeInfo');
@@ -1729,6 +1615,3 @@
 
   List<GeneratedCodeInfo_Annotation> get annotation => $_getList(0);
 }
-
-class _ReadonlyGeneratedCodeInfo extends GeneratedCodeInfo
-    with $pb.ReadonlyMessageMixin {}
diff --git a/lib/src/plugin.pb.dart b/lib/src/plugin.pb.dart
index aee0090..6da3376 100644
--- a/lib/src/plugin.pb.dart
+++ b/lib/src/plugin.pb.dart
@@ -26,14 +26,12 @@
       [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
       : super.fromJson(i, r);
   Version clone() => new Version()..mergeFromMessage(this);
+  Version copyWith(void Function(Version) updates) =>
+      super.copyWith((message) => updates(message as Version));
   $pb.BuilderInfo get info_ => _i;
   static Version create() => new Version();
   static $pb.PbList<Version> createRepeated() => new $pb.PbList<Version>();
-  static Version getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyVersion();
-    return _defaultInstance;
-  }
-
+  static Version getDefault() => _defaultInstance ??= create()..freeze();
   static Version _defaultInstance;
   static void $checkItem(Version v) {
     if (v is! Version) $pb.checkItemFailed(v, 'Version');
@@ -72,8 +70,6 @@
   void clearSuffix() => clearField(4);
 }
 
-class _ReadonlyVersion extends Version with $pb.ReadonlyMessageMixin {}
-
 class CodeGeneratorRequest extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('CodeGeneratorRequest')
     ..pPS(1, 'fileToGenerate')
@@ -96,16 +92,14 @@
       : super.fromJson(i, r);
   CodeGeneratorRequest clone() =>
       new CodeGeneratorRequest()..mergeFromMessage(this);
+  CodeGeneratorRequest copyWith(void Function(CodeGeneratorRequest) updates) =>
+      super.copyWith((message) => updates(message as CodeGeneratorRequest));
   $pb.BuilderInfo get info_ => _i;
   static CodeGeneratorRequest create() => new CodeGeneratorRequest();
   static $pb.PbList<CodeGeneratorRequest> createRepeated() =>
       new $pb.PbList<CodeGeneratorRequest>();
-  static CodeGeneratorRequest getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyCodeGeneratorRequest();
-    return _defaultInstance;
-  }
-
+  static CodeGeneratorRequest getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static CodeGeneratorRequest _defaultInstance;
   static void $checkItem(CodeGeneratorRequest v) {
     if (v is! CodeGeneratorRequest)
@@ -133,9 +127,6 @@
   List<$google$protobuf.FileDescriptorProto> get protoFile => $_getList(3);
 }
 
-class _ReadonlyCodeGeneratorRequest extends CodeGeneratorRequest
-    with $pb.ReadonlyMessageMixin {}
-
 class CodeGeneratorResponse_File extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i =
       new $pb.BuilderInfo('CodeGeneratorResponse_File')
@@ -153,17 +144,17 @@
       : super.fromJson(i, r);
   CodeGeneratorResponse_File clone() =>
       new CodeGeneratorResponse_File()..mergeFromMessage(this);
+  CodeGeneratorResponse_File copyWith(
+          void Function(CodeGeneratorResponse_File) updates) =>
+      super.copyWith(
+          (message) => updates(message as CodeGeneratorResponse_File));
   $pb.BuilderInfo get info_ => _i;
   static CodeGeneratorResponse_File create() =>
       new CodeGeneratorResponse_File();
   static $pb.PbList<CodeGeneratorResponse_File> createRepeated() =>
       new $pb.PbList<CodeGeneratorResponse_File>();
-  static CodeGeneratorResponse_File getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyCodeGeneratorResponse_File();
-    return _defaultInstance;
-  }
-
+  static CodeGeneratorResponse_File getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static CodeGeneratorResponse_File _defaultInstance;
   static void $checkItem(CodeGeneratorResponse_File v) {
     if (v is! CodeGeneratorResponse_File)
@@ -195,9 +186,6 @@
   void clearContent() => clearField(15);
 }
 
-class _ReadonlyCodeGeneratorResponse_File extends CodeGeneratorResponse_File
-    with $pb.ReadonlyMessageMixin {}
-
 class CodeGeneratorResponse extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = new $pb.BuilderInfo('CodeGeneratorResponse')
     ..aOS(1, 'error')
@@ -218,16 +206,15 @@
       : super.fromJson(i, r);
   CodeGeneratorResponse clone() =>
       new CodeGeneratorResponse()..mergeFromMessage(this);
+  CodeGeneratorResponse copyWith(
+          void Function(CodeGeneratorResponse) updates) =>
+      super.copyWith((message) => updates(message as CodeGeneratorResponse));
   $pb.BuilderInfo get info_ => _i;
   static CodeGeneratorResponse create() => new CodeGeneratorResponse();
   static $pb.PbList<CodeGeneratorResponse> createRepeated() =>
       new $pb.PbList<CodeGeneratorResponse>();
-  static CodeGeneratorResponse getDefault() {
-    if (_defaultInstance == null)
-      _defaultInstance = new _ReadonlyCodeGeneratorResponse();
-    return _defaultInstance;
-  }
-
+  static CodeGeneratorResponse getDefault() =>
+      _defaultInstance ??= create()..freeze();
   static CodeGeneratorResponse _defaultInstance;
   static void $checkItem(CodeGeneratorResponse v) {
     if (v is! CodeGeneratorResponse)
@@ -244,6 +231,3 @@
 
   List<CodeGeneratorResponse_File> get file => $_getList(1);
 }
-
-class _ReadonlyCodeGeneratorResponse extends CodeGeneratorResponse
-    with $pb.ReadonlyMessageMixin {}
diff --git a/pubspec.yaml b/pubspec.yaml
index 2e8ed60..b7430bd 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: protoc_plugin
-version: 0.8.2
+version: 0.9.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.9.1
+  protobuf: ^0.10.0
   dart_style: ^1.0.6
 dev_dependencies:
   test: ^1.3.0
diff --git a/test/goldens/grpc_service.pb b/test/goldens/grpc_service.pb
index d1621f5..d2be7d6 100644
--- a/test/goldens/grpc_service.pb
+++ b/test/goldens/grpc_service.pb
@@ -17,18 +17,14 @@
   Empty.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
   Empty.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
   Empty clone() => new Empty()..mergeFromMessage(this);
+  Empty copyWith(void Function(Empty) updates) => super.copyWith((message) => updates(message as Empty));
   $pb.BuilderInfo get info_ => _i;
   static Empty create() => new Empty();
   static $pb.PbList<Empty> createRepeated() => new $pb.PbList<Empty>();
-  static Empty getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyEmpty();
-    return _defaultInstance;
-  }
+  static Empty getDefault() => _defaultInstance ??= create()..freeze();
   static Empty _defaultInstance;
   static void $checkItem(Empty v) {
     if (v is! Empty) $pb.checkItemFailed(v, 'Empty');
   }
 }
 
-class _ReadonlyEmpty extends Empty with $pb.ReadonlyMessageMixin {}
-
diff --git a/test/goldens/imports.pb b/test/goldens/imports.pb
index 13182ef..f313beb 100644
--- a/test/goldens/imports.pb
+++ b/test/goldens/imports.pb
@@ -23,13 +23,11 @@
   M.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
   M.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
   M clone() => new M()..mergeFromMessage(this);
+  M copyWith(void Function(M) updates) => super.copyWith((message) => updates(message as M));
   $pb.BuilderInfo get info_ => _i;
   static M create() => new M();
   static $pb.PbList<M> createRepeated() => new $pb.PbList<M>();
-  static M getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyM();
-    return _defaultInstance;
-  }
+  static M getDefault() => _defaultInstance ??= create()..freeze();
   static M _defaultInstance;
   static void $checkItem(M v) {
     if (v is! M) $pb.checkItemFailed(v, 'M');
@@ -51,5 +49,3 @@
   void clearM2() => clearField(3);
 }
 
-class _ReadonlyM extends M with $pb.ReadonlyMessageMixin {}
-
diff --git a/test/goldens/messageGenerator b/test/goldens/messageGenerator
index 3ffc864..a54f47f 100644
--- a/test/goldens/messageGenerator
+++ b/test/goldens/messageGenerator
@@ -9,13 +9,11 @@
   PhoneNumber.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
   PhoneNumber.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
   PhoneNumber clone() => new PhoneNumber()..mergeFromMessage(this);
+  PhoneNumber copyWith(void Function(PhoneNumber) updates) => super.copyWith((message) => updates(message as PhoneNumber));
   $pb.BuilderInfo get info_ => _i;
   static PhoneNumber create() => new PhoneNumber();
   static $pb.PbList<PhoneNumber> createRepeated() => new $pb.PbList<PhoneNumber>();
-  static PhoneNumber getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyPhoneNumber();
-    return _defaultInstance;
-  }
+  static PhoneNumber getDefault() => _defaultInstance ??= create()..freeze();
   static PhoneNumber _defaultInstance;
   static void $checkItem(PhoneNumber v) {
     if (v is! PhoneNumber) $pb.checkItemFailed(v, 'PhoneNumber');
@@ -37,5 +35,3 @@
   void clearName() => clearField(3);
 }
 
-class _ReadonlyPhoneNumber extends PhoneNumber with $pb.ReadonlyMessageMixin {}
-
diff --git a/test/goldens/oneMessage.pb b/test/goldens/oneMessage.pb
index a89b6ea..7b6ba5d 100644
--- a/test/goldens/oneMessage.pb
+++ b/test/goldens/oneMessage.pb
@@ -19,13 +19,11 @@
   PhoneNumber.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
   PhoneNumber.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
   PhoneNumber clone() => new PhoneNumber()..mergeFromMessage(this);
+  PhoneNumber copyWith(void Function(PhoneNumber) updates) => super.copyWith((message) => updates(message as PhoneNumber));
   $pb.BuilderInfo get info_ => _i;
   static PhoneNumber create() => new PhoneNumber();
   static $pb.PbList<PhoneNumber> createRepeated() => new $pb.PbList<PhoneNumber>();
-  static PhoneNumber getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyPhoneNumber();
-    return _defaultInstance;
-  }
+  static PhoneNumber getDefault() => _defaultInstance ??= create()..freeze();
   static PhoneNumber _defaultInstance;
   static void $checkItem(PhoneNumber v) {
     if (v is! PhoneNumber) $pb.checkItemFailed(v, 'PhoneNumber');
@@ -47,5 +45,3 @@
   void clearName() => clearField(3);
 }
 
-class _ReadonlyPhoneNumber extends PhoneNumber with $pb.ReadonlyMessageMixin {}
-
diff --git a/test/goldens/service.pb b/test/goldens/service.pb
index 6938cf3..50fd16b 100644
--- a/test/goldens/service.pb
+++ b/test/goldens/service.pb
@@ -18,21 +18,17 @@
   Empty.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
   Empty.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
   Empty clone() => new Empty()..mergeFromMessage(this);
+  Empty copyWith(void Function(Empty) updates) => super.copyWith((message) => updates(message as Empty));
   $pb.BuilderInfo get info_ => _i;
   static Empty create() => new Empty();
   static $pb.PbList<Empty> createRepeated() => new $pb.PbList<Empty>();
-  static Empty getDefault() {
-    if (_defaultInstance == null) _defaultInstance = new _ReadonlyEmpty();
-    return _defaultInstance;
-  }
+  static Empty getDefault() => _defaultInstance ??= create()..freeze();
   static Empty _defaultInstance;
   static void $checkItem(Empty v) {
     if (v is! Empty) $pb.checkItemFailed(v, 'Empty');
   }
 }
 
-class _ReadonlyEmpty extends Empty with $pb.ReadonlyMessageMixin {}
-
 class TestApi {
   $pb.RpcClient _client;
   TestApi(this._client);