Introduce GeneratedMessage.isFrozen (#266)

diff --git a/protobuf/CHANGELOG.md b/protobuf/CHANGELOG.md
index 1c544ec..06ed05d 100644
--- a/protobuf/CHANGELOG.md
+++ b/protobuf/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.13.15
+
+* Add new getter `GeneratedMessage.isFrozen` to query if the message has been frozen. 
+
 ## 0.13.14
 
 * Avoid needless copy when reading from a Uint8List buffer.
diff --git a/protobuf/lib/meta.dart b/protobuf/lib/meta.dart
index f50bc77..920ac6e 100644
--- a/protobuf/lib/meta.dart
+++ b/protobuf/lib/meta.dart
@@ -36,6 +36,7 @@
   'hasRequiredFields',
   'hashCode',
   'info_',
+  'isFrozen',
   'isInitialized',
   'mergeFromBuffer',
   'mergeFromCodedBufferReader',
diff --git a/protobuf/lib/src/protobuf/generated_message.dart b/protobuf/lib/src/protobuf/generated_message.dart
index 1ad45fe..24d1d1f 100644
--- a/protobuf/lib/src/protobuf/generated_message.dart
+++ b/protobuf/lib/src/protobuf/generated_message.dart
@@ -61,6 +61,13 @@
     return this;
   }
 
+  /// Returns `true` if this message is marked read-only. Otherwise `false`.
+  ///
+  /// Even when `false`, some sub-message could be read-only.
+  ///
+  /// If `true` all sub-messages are frozen.
+  bool get isFrozen => _fieldSet._isReadOnly;
+
   /// Returns a writable, shallow copy of this message.
   ///
   /// Sub messages will be shared with [this] and will still be frozen if [this]
diff --git a/protobuf/pubspec.yaml b/protobuf/pubspec.yaml
index 8a56cd3..4e2a03f 100644
--- a/protobuf/pubspec.yaml
+++ b/protobuf/pubspec.yaml
@@ -1,5 +1,5 @@
 name: protobuf
-version: 0.13.14
+version: 0.13.15
 author: Dart Team <misc@dartlang.org>
 description: >
   Runtime library for protocol buffers support.
diff --git a/protobuf/test/message_test.dart b/protobuf/test/message_test.dart
index ca94d83..19276ad 100644
--- a/protobuf/test/message_test.dart
+++ b/protobuf/test/message_test.dart
@@ -51,6 +51,19 @@
     expect(b == a, true);
   });
 
+  test('isFrozen works', () {
+    final a = Rec()
+      ..val = 123
+      ..int32s.addAll([1, 2, 3])
+      ..child = (Rec()..val = 100);
+    expect(a.isFrozen, false);
+    a.child.freeze();
+    expect(a.child.isFrozen, true);
+    expect(a.isFrozen, false);
+    a.freeze();
+    expect(a.isFrozen, true);
+  });
+
   test('operator== and hashCode work for a simple record', () {
     var a = Rec();
     expect(a == a, true);