Print extension fields in toString() (#196)

diff --git a/protobuf/CHANGELOG.md b/protobuf/CHANGELOG.md
index c82e40e..d2e2273 100644
--- a/protobuf/CHANGELOG.md
+++ b/protobuf/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.13.2
+
+* Include extension fields in GeneratedMessage.toString().
+
 ## 0.13.1
 
 * Fix issue with not being able to read unknown fields after freezing.
diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart
index f86d2e3..8afea66 100644
--- a/protobuf/lib/src/protobuf/field_set.dart
+++ b/protobuf/lib/src/protobuf/field_set.dart
@@ -585,26 +585,35 @@
       }
     }
 
-    for (FieldInfo fi in _infosSortedByTag) {
-      var fieldValue = _values[fi.index];
-      if (fieldValue == null) continue;
+    void writeFieldValue(fieldValue, String name) {
+      if (fieldValue == null) return;
       if (fieldValue is ByteData) {
         // TODO(skybrian): possibly unused. Delete?
         final value = fieldValue.getUint64(0, Endian.little);
-        renderValue(fi.name, value);
+        renderValue(name, value);
       } else if (fieldValue is List) {
         for (var value in fieldValue) {
-          renderValue(fi.name, value);
+          renderValue(name, value);
         }
       } else if (fieldValue is Map) {
         for (var entry in fieldValue.entries) {
-          renderValue(fi.name, entry);
+          renderValue(name, entry);
         }
       } else {
-        renderValue(fi.name, fieldValue);
+        renderValue(name, fieldValue);
       }
     }
-    // TODO(skybrian) write extension fields? So far we haven't.
+
+    _infosSortedByTag
+        .forEach((FieldInfo fi) => writeFieldValue(_values[fi.index], fi.name));
+
+    if (_hasExtensions) {
+      _extensions._info.keys.toList()
+        ..sort()
+        ..forEach((int tagNumber) => writeFieldValue(
+            _extensions._values[tagNumber],
+            '[${_extensions._info[tagNumber].name}]'));
+    }
     if (_hasUnknownFields) {
       out.write(_unknownFields.toString());
     } else {
diff --git a/protobuf/pubspec.yaml b/protobuf/pubspec.yaml
index 8f7b5f9..59c2242 100644
--- a/protobuf/pubspec.yaml
+++ b/protobuf/pubspec.yaml
@@ -1,5 +1,5 @@
 name: protobuf
-version: 0.13.1
+version: 0.13.2
 author: Dart Team <misc@dartlang.org>
 description: >
   Runtime library for protocol buffers support.
diff --git a/protoc_plugin/test/extension_test.dart b/protoc_plugin/test/extension_test.dart
index 9bdb3ee..7d7fbea 100644
--- a/protoc_plugin/test/extension_test.dart
+++ b/protoc_plugin/test/extension_test.dart
@@ -189,4 +189,25 @@
   test('extension class was renamed to avoid conflict with enum', () {
     expect(ExtensionEnumNameConflictExt.enumConflictExtension.tagNumber, 1);
   });
+
+  test('to toDebugString', () {
+    TestAllExtensions value = new TestAllExtensions()
+      ..setExtension(Unittest.optionalInt32Extension, 1)
+      ..addExtension(Unittest.repeatedStringExtension, 'hello')
+      ..addExtension(Unittest.repeatedStringExtension, 'world')
+      ..setExtension(Unittest.optionalNestedMessageExtension,
+          TestAllTypes_NestedMessage()..i = 42)
+      ..setExtension(
+          Unittest.optionalNestedEnumExtension, TestAllTypes_NestedEnum.BAR);
+
+    String expected = '[optionalInt32Extension]: 1\n'
+        '[optionalNestedMessageExtension]: {\n'
+        '  i: 42\n'
+        '}\n'
+        '[optionalNestedEnumExtension]: BAR\n'
+        '[repeatedStringExtension]: hello\n'
+        '[repeatedStringExtension]: world\n';
+
+    expect(value.toString(), expected);
+  });
 }