Merge pull request #1299 from tatraian/master

Fix compiling clang/libc++ builds. (Issue: #1266)
diff --git a/Makefile.am b/Makefile.am
index 3e21db8..064efdf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -413,6 +413,7 @@
   objectivec/GPBCodedInputStream_PackagePrivate.h                            \
   objectivec/GPBCodedOutputStream.h                                          \
   objectivec/GPBCodedOutputStream.m                                          \
+  objectivec/GPBCodedOutputStream_PackagePrivate.h                           \
   objectivec/GPBDescriptor.h                                                 \
   objectivec/GPBDescriptor.m                                                 \
   objectivec/GPBDescriptor_PackagePrivate.h                                  \
diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
index 6706995..5c2a052 100644
--- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
+++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
@@ -710,5 +710,14 @@
             Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());

             Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));

         }

+

+        [Test]

+        public void CustomDiagnosticMessage_DirectToTextWriterCall()

+        {

+            var message = new ForeignMessage { C = 31 };

+            var writer = new StringWriter();

+            JsonFormatter.Default.Format(message, writer);

+            Assert.AreEqual("{ \"c\": 31 }", writer.ToString());

+        }

     }

 }

diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs
index 90a5ff1..993a89d 100644
--- a/csharp/src/Google.Protobuf/Collections/MapField.cs
+++ b/csharp/src/Google.Protobuf/Collections/MapField.cs
@@ -34,6 +34,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Text;
 using Google.Protobuf.Compatibility;
@@ -474,9 +475,9 @@
         /// </summary>
         public override string ToString()
         {
-            var builder = new StringBuilder();
-            JsonFormatter.Default.WriteDictionary(builder, this);
-            return builder.ToString();
+            var writer = new StringWriter();
+            JsonFormatter.Default.WriteDictionary(writer, this);
+            return writer.ToString();
         }
 
         #region IDictionary explicit interface implementation
diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
index 1cde03b..d1db856 100644
--- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
+++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
@@ -33,6 +33,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.IO;
 using System.Text;
 
 namespace Google.Protobuf.Collections
@@ -474,9 +475,9 @@
         /// </summary>
         public override string ToString()
         {
-            var builder = new StringBuilder();
-            JsonFormatter.Default.WriteList(builder, this);
-            return builder.ToString();
+            var writer = new StringWriter();
+            JsonFormatter.Default.WriteList(writer, this);
+            return writer.ToString();
         }
 
         /// <summary>
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index 60f61fc..eb959c9 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -36,6 +36,7 @@
 using System.Text;
 using Google.Protobuf.Reflection;
 using Google.Protobuf.WellKnownTypes;
+using System.IO;
 using System.Linq;
 using System.Collections.Generic;
 
@@ -141,17 +142,30 @@
         /// <returns>The formatted message.</returns>
         public string Format(IMessage message)
         {
+            var writer = new StringWriter();
+            Format(message, writer);
+            return writer.ToString();
+        }
+
+        /// <summary>
+        /// Formats the specified message as JSON.
+        /// </summary>
+        /// <param name="message">The message to format.</param>
+        /// <param name="writer">The TextWriter to write the formatted message to.</param>
+        /// <returns>The formatted message.</returns>
+        public void Format(IMessage message, TextWriter writer)
+        {
             ProtoPreconditions.CheckNotNull(message, nameof(message));
-            StringBuilder builder = new StringBuilder();
+            ProtoPreconditions.CheckNotNull(writer, nameof(writer));
+
             if (message.Descriptor.IsWellKnownType)
             {
-                WriteWellKnownTypeValue(builder, message.Descriptor, message);
+                WriteWellKnownTypeValue(writer, message.Descriptor, message);
             }
             else
             {
-                WriteMessage(builder, message);
+                WriteMessage(writer, message);
             }
-            return builder.ToString();
         }
 
         /// <summary>
@@ -177,11 +191,11 @@
             return diagnosticFormatter.Format(message);
         }
 
-        private void WriteMessage(StringBuilder builder, IMessage message)
+        private void WriteMessage(TextWriter writer, IMessage message)
         {
             if (message == null)
             {
-                WriteNull(builder);
+                WriteNull(writer);
                 return;
             }
             if (DiagnosticOnly)
@@ -189,16 +203,16 @@
                 ICustomDiagnosticMessage customDiagnosticMessage = message as ICustomDiagnosticMessage;
                 if (customDiagnosticMessage != null)
                 {
-                    builder.Append(customDiagnosticMessage.ToDiagnosticString());
+                    writer.Write(customDiagnosticMessage.ToDiagnosticString());
                     return;
                 }
             }
-            builder.Append("{ ");
-            bool writtenFields = WriteMessageFields(builder, message, false);
-            builder.Append(writtenFields ? " }" : "}");
+            writer.Write("{ ");
+            bool writtenFields = WriteMessageFields(writer, message, false);
+            writer.Write(writtenFields ? " }" : "}");
         }
 
-        private bool WriteMessageFields(StringBuilder builder, IMessage message, bool assumeFirstFieldWritten)
+        private bool WriteMessageFields(TextWriter writer, IMessage message, bool assumeFirstFieldWritten)
         {
             var fields = message.Descriptor.Fields;
             bool first = !assumeFirstFieldWritten;
@@ -221,11 +235,11 @@
                 // Okay, all tests complete: let's write the field value...
                 if (!first)
                 {
-                    builder.Append(PropertySeparator);
+                    writer.Write(PropertySeparator);
                 }
-                WriteString(builder, ToCamelCase(accessor.Descriptor.Name));
-                builder.Append(NameValueSeparator);
-                WriteValue(builder, value);
+                WriteString(writer, ToCamelCase(accessor.Descriptor.Name));
+                writer.Write(NameValueSeparator);
+                WriteValue(writer, value);
                 first = false;
             }            
             return !first;
@@ -309,9 +323,9 @@
             return result.ToString();
         }
         
-        private static void WriteNull(StringBuilder builder)
+        private static void WriteNull(TextWriter writer)
         {
-            builder.Append("null");
+            writer.Write("null");
         }
 
         private static bool IsDefaultValue(IFieldAccessor accessor, object value)
@@ -361,56 +375,56 @@
             }
         }
         
-        private void WriteValue(StringBuilder builder, object value)
+        private void WriteValue(TextWriter writer, object value)
         {
             if (value == null)
             {
-                WriteNull(builder);
+                WriteNull(writer);
             }
             else if (value is bool)
             {
-                builder.Append((bool) value ? "true" : "false");
+                writer.Write((bool)value ? "true" : "false");
             }
             else if (value is ByteString)
             {
                 // Nothing in Base64 needs escaping
-                builder.Append('"');
-                builder.Append(((ByteString) value).ToBase64());
-                builder.Append('"');
+                writer.Write('"');
+                writer.Write(((ByteString)value).ToBase64());
+                writer.Write('"');
             }
             else if (value is string)
             {
-                WriteString(builder, (string) value);
+                WriteString(writer, (string)value);
             }
             else if (value is IDictionary)
             {
-                WriteDictionary(builder, (IDictionary) value);
+                WriteDictionary(writer, (IDictionary)value);
             }
             else if (value is IList)
             {
-                WriteList(builder, (IList) value);
+                WriteList(writer, (IList)value);
             }
             else if (value is int || value is uint)
             {
                 IFormattable formattable = (IFormattable) value;
-                builder.Append(formattable.ToString("d", CultureInfo.InvariantCulture));
+                writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture));
             }
             else if (value is long || value is ulong)
             {
-                builder.Append('"');
+                writer.Write('"');
                 IFormattable formattable = (IFormattable) value;
-                builder.Append(formattable.ToString("d", CultureInfo.InvariantCulture));
-                builder.Append('"');
+                writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture));
+                writer.Write('"');
             }
             else if (value is System.Enum)
             {
                 if (System.Enum.IsDefined(value.GetType(), value))
                 {
-                    WriteString(builder, value.ToString());
+                    WriteString(writer, value.ToString());
                 }
                 else
                 {
-                    WriteValue(builder, (int) value);
+                    WriteValue(writer, (int)value);
                 }
             }
             else if (value is float || value is double)
@@ -418,13 +432,13 @@
                 string text = ((IFormattable) value).ToString("r", CultureInfo.InvariantCulture);
                 if (text == "NaN" || text == "Infinity" || text == "-Infinity")
                 {
-                    builder.Append('"');
-                    builder.Append(text);
-                    builder.Append('"');
+                    writer.Write('"');
+                    writer.Write(text);
+                    writer.Write('"');
                 }
                 else
                 {
-                    builder.Append(text);
+                    writer.Write(text);
                 }
             }
             else if (value is IMessage)
@@ -432,11 +446,11 @@
                 IMessage message = (IMessage) value;
                 if (message.Descriptor.IsWellKnownType)
                 {
-                    WriteWellKnownTypeValue(builder, message.Descriptor, value);
+                    WriteWellKnownTypeValue(writer, message.Descriptor, value);
                 }
                 else
                 {
-                    WriteMessage(builder, (IMessage) value);
+                    WriteMessage(writer, (IMessage)value);
                 }
             }
             else
@@ -451,13 +465,13 @@
         /// values are using the embedded well-known types, in order to allow for dynamic messages
         /// in the future.
         /// </summary>
-        private void WriteWellKnownTypeValue(StringBuilder builder, MessageDescriptor descriptor, object value)
+        private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value)
         {
             // Currently, we can never actually get here, because null values are always handled by the caller. But if we *could*,
             // this would do the right thing.
             if (value == null)
             {
-                WriteNull(builder);
+                WriteNull(writer);
                 return;
             }
             // For wrapper types, the value will either be the (possibly boxed) "native" value,
@@ -472,49 +486,49 @@
                     var message = (IMessage) value;
                     value = message.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.GetValue(message);
                 }
-                WriteValue(builder, value);
+                WriteValue(writer, value);
                 return;
             }
             if (descriptor.FullName == Timestamp.Descriptor.FullName)
             {
-                WriteTimestamp(builder, (IMessage) value);
+                WriteTimestamp(writer, (IMessage)value);
                 return;
             }
             if (descriptor.FullName == Duration.Descriptor.FullName)
             {
-                WriteDuration(builder, (IMessage) value);
+                WriteDuration(writer, (IMessage)value);
                 return;
             }
             if (descriptor.FullName == FieldMask.Descriptor.FullName)
             {
-                WriteFieldMask(builder, (IMessage) value);
+                WriteFieldMask(writer, (IMessage)value);
                 return;
             }
             if (descriptor.FullName == Struct.Descriptor.FullName)
             {
-                WriteStruct(builder, (IMessage) value);
+                WriteStruct(writer, (IMessage)value);
                 return;
             }
             if (descriptor.FullName == ListValue.Descriptor.FullName)
             {
                 var fieldAccessor = descriptor.Fields[ListValue.ValuesFieldNumber].Accessor;
-                WriteList(builder, (IList) fieldAccessor.GetValue((IMessage) value));
+                WriteList(writer, (IList)fieldAccessor.GetValue((IMessage)value));
                 return;
             }
             if (descriptor.FullName == Value.Descriptor.FullName)
             {
-                WriteStructFieldValue(builder, (IMessage) value);
+                WriteStructFieldValue(writer, (IMessage)value);
                 return;
             }
             if (descriptor.FullName == Any.Descriptor.FullName)
             {
-                WriteAny(builder, (IMessage) value);
+                WriteAny(writer, (IMessage)value);
                 return;
             }
-            WriteMessage(builder, (IMessage) value);
+            WriteMessage(writer, (IMessage)value);
         }
 
-        private void WriteTimestamp(StringBuilder builder, IMessage value)
+        private void WriteTimestamp(TextWriter writer, IMessage value)
         {
             // TODO: In the common case where this *is* using the built-in Timestamp type, we could
             // avoid all the reflection at this point, by casting to Timestamp. In the interests of
@@ -522,28 +536,28 @@
             // it still works in that case.
             int nanos = (int) value.Descriptor.Fields[Timestamp.NanosFieldNumber].Accessor.GetValue(value);
             long seconds = (long) value.Descriptor.Fields[Timestamp.SecondsFieldNumber].Accessor.GetValue(value);
-            builder.Append(Timestamp.ToJson(seconds, nanos, DiagnosticOnly));
+            writer.Write(Timestamp.ToJson(seconds, nanos, DiagnosticOnly));
         }
 
-        private void WriteDuration(StringBuilder builder, IMessage value)
+        private void WriteDuration(TextWriter writer, IMessage value)
         {
             // TODO: Same as for WriteTimestamp
             int nanos = (int) value.Descriptor.Fields[Duration.NanosFieldNumber].Accessor.GetValue(value);
             long seconds = (long) value.Descriptor.Fields[Duration.SecondsFieldNumber].Accessor.GetValue(value);
-            builder.Append(Duration.ToJson(seconds, nanos, DiagnosticOnly));
+            writer.Write(Duration.ToJson(seconds, nanos, DiagnosticOnly));
         }
 
-        private void WriteFieldMask(StringBuilder builder, IMessage value)
+        private void WriteFieldMask(TextWriter writer, IMessage value)
         {
             var paths = (IList<string>) value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value);
-            builder.Append(FieldMask.ToJson(paths, DiagnosticOnly));
+            writer.Write(FieldMask.ToJson(paths, DiagnosticOnly));
         }
 
-        private void WriteAny(StringBuilder builder, IMessage value)
+        private void WriteAny(TextWriter writer, IMessage value)
         {
             if (DiagnosticOnly)
             {
-                WriteDiagnosticOnlyAny(builder, value);
+                WriteDiagnosticOnlyAny(writer, value);
                 return;
             }
 
@@ -556,40 +570,40 @@
                 throw new InvalidOperationException($"Type registry has no descriptor for type name '{typeName}'");
             }
             IMessage message = descriptor.Parser.ParseFrom(data);
-            builder.Append("{ ");
-            WriteString(builder, AnyTypeUrlField);
-            builder.Append(NameValueSeparator);
-            WriteString(builder, typeUrl);
+            writer.Write("{ ");
+            WriteString(writer, AnyTypeUrlField);
+            writer.Write(NameValueSeparator);
+            WriteString(writer, typeUrl);
 
             if (descriptor.IsWellKnownType)
             {
-                builder.Append(PropertySeparator);
-                WriteString(builder, AnyWellKnownTypeValueField);
-                builder.Append(NameValueSeparator);
-                WriteWellKnownTypeValue(builder, descriptor, message);
+                writer.Write(PropertySeparator);
+                WriteString(writer, AnyWellKnownTypeValueField);
+                writer.Write(NameValueSeparator);
+                WriteWellKnownTypeValue(writer, descriptor, message);
             }
             else
             {
-                WriteMessageFields(builder, message, true);
+                WriteMessageFields(writer, message, true);
             }
-            builder.Append(" }");
+            writer.Write(" }");
         }
 
-        private void WriteDiagnosticOnlyAny(StringBuilder builder, IMessage value)
+        private void WriteDiagnosticOnlyAny(TextWriter writer, IMessage value)
         {
             string typeUrl = (string) value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
             ByteString data = (ByteString) value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
-            builder.Append("{ ");
-            WriteString(builder, AnyTypeUrlField);
-            builder.Append(NameValueSeparator);
-            WriteString(builder, typeUrl);
-            builder.Append(PropertySeparator);
-            WriteString(builder, AnyDiagnosticValueField);
-            builder.Append(NameValueSeparator);
-            builder.Append('"');
-            builder.Append(data.ToBase64());
-            builder.Append('"');
-            builder.Append(" }");
+            writer.Write("{ ");
+            WriteString(writer, AnyTypeUrlField);
+            writer.Write(NameValueSeparator);
+            WriteString(writer, typeUrl);
+            writer.Write(PropertySeparator);
+            WriteString(writer, AnyDiagnosticValueField);
+            writer.Write(NameValueSeparator);
+            writer.Write('"');
+            writer.Write(data.ToBase64());
+            writer.Write('"');
+            writer.Write(" }");
         }
 
         internal static string GetTypeName(String typeUrl)
@@ -602,9 +616,9 @@
             return parts[1];
         }
 
-        private void WriteStruct(StringBuilder builder, IMessage message)
+        private void WriteStruct(TextWriter writer, IMessage message)
         {
-            builder.Append("{ ");
+            writer.Write("{ ");
             IDictionary fields = (IDictionary) message.Descriptor.Fields[Struct.FieldsFieldNumber].Accessor.GetValue(message);
             bool first = true;
             foreach (DictionaryEntry entry in fields)
@@ -618,17 +632,17 @@
 
                 if (!first)
                 {
-                    builder.Append(PropertySeparator);
+                    writer.Write(PropertySeparator);
                 }
-                WriteString(builder, key);
-                builder.Append(NameValueSeparator);
-                WriteStructFieldValue(builder, value);
+                WriteString(writer, key);
+                writer.Write(NameValueSeparator);
+                WriteStructFieldValue(writer, value);
                 first = false;
             }
-            builder.Append(first ? "}" : " }");
+            writer.Write(first ? "}" : " }");
         }
 
-        private void WriteStructFieldValue(StringBuilder builder, IMessage message)
+        private void WriteStructFieldValue(TextWriter writer, IMessage message)
         {
             var specifiedField = message.Descriptor.Oneofs[0].Accessor.GetCaseFieldDescriptor(message);
             if (specifiedField == null)
@@ -643,48 +657,48 @@
                 case Value.BoolValueFieldNumber:
                 case Value.StringValueFieldNumber:
                 case Value.NumberValueFieldNumber:
-                    WriteValue(builder, value);
+                    WriteValue(writer, value);
                     return;
                 case Value.StructValueFieldNumber:
                 case Value.ListValueFieldNumber:
                     // Structs and ListValues are nested messages, and already well-known types.
                     var nestedMessage = (IMessage) specifiedField.Accessor.GetValue(message);
-                    WriteWellKnownTypeValue(builder, nestedMessage.Descriptor, nestedMessage);
+                    WriteWellKnownTypeValue(writer, nestedMessage.Descriptor, nestedMessage);
                     return;
                 case Value.NullValueFieldNumber:
-                    WriteNull(builder);
+                    WriteNull(writer);
                     return;
                 default:
                     throw new InvalidOperationException("Unexpected case in struct field: " + specifiedField.FieldNumber);
             }
         }
 
-        internal void WriteList(StringBuilder builder, IList list)
+        internal void WriteList(TextWriter writer, IList list)
         {
-            builder.Append("[ ");
+            writer.Write("[ ");
             bool first = true;
             foreach (var value in list)
             {
                 if (!first)
                 {
-                    builder.Append(PropertySeparator);
+                    writer.Write(PropertySeparator);
                 }
-                WriteValue(builder, value);
+                WriteValue(writer, value);
                 first = false;
             }
-            builder.Append(first ? "]" : " ]");
+            writer.Write(first ? "]" : " ]");
         }
 
-        internal void WriteDictionary(StringBuilder builder, IDictionary dictionary)
+        internal void WriteDictionary(TextWriter writer, IDictionary dictionary)
         {
-            builder.Append("{ ");
+            writer.Write("{ ");
             bool first = true;
             // This will box each pair. Could use IDictionaryEnumerator, but that's ugly in terms of disposal.
             foreach (DictionaryEntry pair in dictionary)
             {
                 if (!first)
                 {
-                    builder.Append(PropertySeparator);
+                    writer.Write(PropertySeparator);
                 }
                 string keyText;
                 if (pair.Key is string)
@@ -707,12 +721,12 @@
                     }
                     throw new ArgumentException("Unhandled dictionary key type: " + pair.Key.GetType());
                 }
-                WriteString(builder, keyText);
-                builder.Append(NameValueSeparator);
-                WriteValue(builder, pair.Value);
+                WriteString(writer, keyText);
+                writer.Write(NameValueSeparator);
+                WriteValue(writer, pair.Value);
                 first = false;
             }
-            builder.Append(first ? "}" : " }");
+            writer.Write(first ? "}" : " }");
         }
 
         /// <summary>
@@ -735,15 +749,15 @@
         /// <remarks>
         /// Other than surrogate pair handling, this code is mostly taken from src/google/protobuf/util/internal/json_escaping.cc.
         /// </remarks>
-        internal static void WriteString(StringBuilder builder, string text)
+        internal static void WriteString(TextWriter writer, string text)
         {
-            builder.Append('"');
+            writer.Write('"');
             for (int i = 0; i < text.Length; i++)
             {
                 char c = text[i];
                 if (c < 0xa0)
                 {
-                    builder.Append(CommonRepresentations[c]);
+                    writer.Write(CommonRepresentations[c]);
                     continue;
                 }
                 if (char.IsHighSurrogate(c))
@@ -755,8 +769,8 @@
                     {
                         throw new ArgumentException("String contains low surrogate not followed by high surrogate");
                     }
-                    HexEncodeUtf16CodeUnit(builder, c);
-                    HexEncodeUtf16CodeUnit(builder, text[i]);
+                    HexEncodeUtf16CodeUnit(writer, c);
+                    HexEncodeUtf16CodeUnit(writer, text[i]);
                     continue;
                 }
                 else if (char.IsLowSurrogate(c))
@@ -777,7 +791,7 @@
                     case 0x070f:  // Syriac abbreviation mark
                     case 0x17b4:  // Khmer vowel inherent Aq
                     case 0x17b5:  // Khmer vowel inherent Aa
-                        HexEncodeUtf16CodeUnit(builder, c);
+                        HexEncodeUtf16CodeUnit(writer, c);
                         break;
 
                     default:
@@ -787,27 +801,27 @@
                             (c >= 0x2060 && c <= 0x2064) ||  // Invisible etc.
                             (c >= 0x206a && c <= 0x206f))
                         {
-                            HexEncodeUtf16CodeUnit(builder, c);
+                            HexEncodeUtf16CodeUnit(writer, c);
                         }
                         else
                         {
                             // No handling of surrogates here - that's done earlier
-                            builder.Append(c);
+                            writer.Write(c);
                         }
                         break;
                 }
             }
-            builder.Append('"');
+            writer.Write('"');
         }
 
         private const string Hex = "0123456789abcdef";
-        private static void HexEncodeUtf16CodeUnit(StringBuilder builder, char c)
+        private static void HexEncodeUtf16CodeUnit(TextWriter writer, char c)
         {
-            builder.Append("\\u");
-            builder.Append(Hex[(c >> 12) & 0xf]);
-            builder.Append(Hex[(c >> 8) & 0xf]);
-            builder.Append(Hex[(c >> 4) & 0xf]);
-            builder.Append(Hex[(c >> 0) & 0xf]);
+            writer.Write("\\u");
+            writer.Write(Hex[(c >> 12) & 0xf]);
+            writer.Write(Hex[(c >> 8) & 0xf]);
+            writer.Write(Hex[(c >> 4) & 0xf]);
+            writer.Write(Hex[(c >> 0) & 0xf]);
         }
 
         /// <summary>
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
index df1292d..4bd62cf 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
@@ -33,6 +33,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Text;
 
@@ -57,19 +58,19 @@
             var firstInvalid = paths.FirstOrDefault(p => !ValidatePath(p));
             if (firstInvalid == null)
             {
-                var builder = new StringBuilder();
-                JsonFormatter.WriteString(builder, string.Join(",", paths.Select(JsonFormatter.ToCamelCase)));
-                return builder.ToString();
+                var writer = new StringWriter();
+                JsonFormatter.WriteString(writer, string.Join(",", paths.Select(JsonFormatter.ToCamelCase)));
+                return writer.ToString();
             }
             else
             {
                 if (diagnosticOnly)
                 {
-                    var builder = new StringBuilder();
-                    builder.Append("{ \"@warning\": \"Invalid FieldMask\", \"paths\": ");
-                    JsonFormatter.Default.WriteList(builder, (IList) paths);
-                    builder.Append(" }");
-                    return builder.ToString();
+                    var writer = new StringWriter();
+                    writer.Write("{ \"@warning\": \"Invalid FieldMask\", \"paths\": ");
+                    JsonFormatter.Default.WriteList(writer, (IList)paths);
+                    writer.Write(" }");
+                    return writer.ToString();
                 }
                 else
                 {
diff --git a/objectivec/GPBCodedInputStream.h b/objectivec/GPBCodedInputStream.h
index 42a0494..0619888 100644
--- a/objectivec/GPBCodedInputStream.h
+++ b/objectivec/GPBCodedInputStream.h
@@ -35,52 +35,86 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
-// Reads and decodes protocol message fields.
-// Subclassing of GPBCodedInputStream is NOT supported.
+/// Reads and decodes protocol message fields.
+///
+/// The common uses of protocol buffers shouldn't need to use this class.
+/// @c GPBMessage's provide a @c +parseFromData:error: and @c
+/// +parseFromData:extensionRegistry:error: method that will decode a
+/// message for you.
+///
+/// @note Subclassing of GPBCodedInputStream is NOT supported.
 @interface GPBCodedInputStream : NSObject
 
+/// Creates a new stream wrapping some data.
 + (instancetype)streamWithData:(NSData *)data;
+
+/// Initializes a stream wrapping some data.
 - (instancetype)initWithData:(NSData *)data;
 
-// Attempt to read a field tag, returning zero if we have reached EOF.
-// Protocol message parsers use this to read tags, since a protocol message
-// may legally end wherever a tag occurs, and zero is not a valid tag number.
+/// Attempt to read a field tag, returning zero if we have reached EOF.
+/// Protocol message parsers use this to read tags, since a protocol message
+/// may legally end wherever a tag occurs, and zero is not a valid tag number.
 - (int32_t)readTag;
 
+/// Read and return a double.
 - (double)readDouble;
+/// Read and return a float.
 - (float)readFloat;
+/// Read and return a uint64.
 - (uint64_t)readUInt64;
+/// Read and return a uint32.
 - (uint32_t)readUInt32;
+/// Read and return an int64.
 - (int64_t)readInt64;
+/// Read and return an int32.
 - (int32_t)readInt32;
+/// Read and return a fixed64.
 - (uint64_t)readFixed64;
+/// Read and return a fixed32.
 - (uint32_t)readFixed32;
+/// Read and return an enum (int).
 - (int32_t)readEnum;
+/// Read and return a sfixed32.
 - (int32_t)readSFixed32;
+/// Read and return a sfixed64.
 - (int64_t)readSFixed64;
+/// Read and return a sint32.
 - (int32_t)readSInt32;
+/// Read and return a sint64.
 - (int64_t)readSInt64;
+/// Read and return a boolean.
 - (BOOL)readBool;
+/// Read and return a string.
 - (NSString *)readString;
+/// Read and return length delimited data.
 - (NSData *)readBytes;
 
-// Read an embedded message field value from the stream.
+/// Read an embedded message field value from the stream.
+///
+/// @param message           The message to set fields on as they are read.
+/// @param extensionRegistry An optional extension registry to use to lookup
+///                          extensions for @message.
 - (void)readMessage:(GPBMessage *)message
-    extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry;
+  extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry;
 
-// Reads and discards a single field, given its tag value. Returns NO if the
-// tag is an endgroup tag, in which case nothing is skipped.  Otherwise,
-// returns YES.
+/// Reads and discards a single field, given its tag value.
+///
+/// @param tag The tag number of the field to skip.
+///
+/// @return NO if the tag is an endgroup tag (in which case nothing is skipped),
+///         YES in all other cases.
 - (BOOL)skipField:(int32_t)tag;
 
-// Reads and discards an entire message.  This will read either until EOF
-// or until an endgroup tag, whichever comes first.
+/// Reads and discards an entire message.  This will read either until EOF
+/// or until an endgroup tag, whichever comes first.
 - (void)skipMessage;
 
-// Verifies that the last call to readTag() returned the given tag value.
-// This is used to verify that a nested group ended with the correct end tag.
-// Throws NSParseErrorException if value does not match the last tag.
-- (void)checkLastTagWas:(int32_t)value;
+/// Verifies that the last call to @c -readTag returned the given tag value.
+/// This is used to verify that a nested group ended with the correct end tag.
+/// Throws @c NSParseErrorException if value does not match the last tag.
+///
+/// @param expected The tag that was expected.
+- (void)checkLastTagWas:(int32_t)expected;
 
 @end
 
diff --git a/objectivec/GPBCodedOutputStream.h b/objectivec/GPBCodedOutputStream.h
index 0a47f1c..e67efd2 100644
--- a/objectivec/GPBCodedOutputStream.h
+++ b/objectivec/GPBCodedOutputStream.h
@@ -46,36 +46,63 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+/// Writes out protocol message fields.
+///
+/// The common uses of protocol buffers shouldn't need to use this class.
+/// @c GPBMessage's provide a @c -data method that will serialize the message
+/// for you.
+///
+/// @note Subclassing of GPBCodedOutputStream is NOT supported.
 @interface GPBCodedOutputStream : NSObject
 
-// Creates a new stream to write into data.  Data must be sized to fit or it
-// will error when it runs out of space.
+/// Creates a stream to fill in the given data. Data must be sized to fit or
+/// an error will be raised when out of space.
 + (instancetype)streamWithData:(NSMutableData *)data;
+
+/// Creates a stream to write into the given @c NSOutputStream.
 + (instancetype)streamWithOutputStream:(NSOutputStream *)output;
-+ (instancetype)streamWithOutputStream:(NSOutputStream *)output
-                            bufferSize:(size_t)bufferSize;
 
+/// Initializes a stream to fill in the given data. Data must be sized to fit
+/// or an error will be raised when out of space.
 - (instancetype)initWithData:(NSMutableData *)data;
-- (instancetype)initWithOutputStream:(NSOutputStream *)output;
-- (instancetype)initWithOutputStream:(NSOutputStream *)output
-                          bufferSize:(size_t)bufferSize;
 
+/// Initializes a stream to write into the given @c NSOutputStream.
+- (instancetype)initWithOutputStream:(NSOutputStream *)output;
+
+/// Flush any buffered data out.
 - (void)flush;
 
+/// Write the raw byte out.
 - (void)writeRawByte:(uint8_t)value;
 
+/// Write the tag for the given field number and wire format.
+///
+/// @param fieldNumber The field number.
+/// @param format      The wire format the data for the field will be in.
 - (void)writeTag:(uint32_t)fieldNumber format:(GPBWireFormat)format;
 
+/// Write a 32bit value out in little endian format.
 - (void)writeRawLittleEndian32:(int32_t)value;
+/// Write a 64bit value out in little endian format.
 - (void)writeRawLittleEndian64:(int64_t)value;
 
+/// Write a 32bit value out in varint format.
 - (void)writeRawVarint32:(int32_t)value;
+/// Write a 64bit value out in varint format.
 - (void)writeRawVarint64:(int64_t)value;
 
-// Note that this will truncate 64 bit values to 32.
+/// Write a size_t out as a 32bit varint value.
+///
+/// @note This will truncate 64 bit values to 32.
 - (void)writeRawVarintSizeTAs32:(size_t)value;
 
+/// Writes the contents of an @c NSData out.
 - (void)writeRawData:(NSData *)data;
+/// Writes out the given data.
+///
+/// @param data   The data blob to write out.
+/// @param offset The offset into the blob to start writing out.
+/// @param length The number of bytes from the blob to write out.
 - (void)writeRawPtr:(const void *)data
              offset:(size_t)offset
              length:(size_t)length;
@@ -83,238 +110,213 @@
 //%PDDM-EXPAND _WRITE_DECLS()
 // This block of code is generated, do not edit it directly.
 
+/// Write a double for the given field number.
 - (void)writeDouble:(int32_t)fieldNumber value:(double)value;
+/// Write a packaged array of double for the given field number.
 - (void)writeDoubleArray:(int32_t)fieldNumber
                   values:(GPBDoubleArray *)values
                      tag:(uint32_t)tag;
+/// Write a double without any tag.
 - (void)writeDoubleNoTag:(double)value;
 
+/// Write a float for the given field number.
 - (void)writeFloat:(int32_t)fieldNumber value:(float)value;
+/// Write a packaged array of float for the given field number.
 - (void)writeFloatArray:(int32_t)fieldNumber
                  values:(GPBFloatArray *)values
                     tag:(uint32_t)tag;
+/// Write a float without any tag.
 - (void)writeFloatNoTag:(float)value;
 
+/// Write a uint64_t for the given field number.
 - (void)writeUInt64:(int32_t)fieldNumber value:(uint64_t)value;
+/// Write a packaged array of uint64_t for the given field number.
 - (void)writeUInt64Array:(int32_t)fieldNumber
                   values:(GPBUInt64Array *)values
                      tag:(uint32_t)tag;
+/// Write a uint64_t without any tag.
 - (void)writeUInt64NoTag:(uint64_t)value;
 
+/// Write a int64_t for the given field number.
 - (void)writeInt64:(int32_t)fieldNumber value:(int64_t)value;
+/// Write a packaged array of int64_t for the given field number.
 - (void)writeInt64Array:(int32_t)fieldNumber
                  values:(GPBInt64Array *)values
                     tag:(uint32_t)tag;
+/// Write a int64_t without any tag.
 - (void)writeInt64NoTag:(int64_t)value;
 
+/// Write a int32_t for the given field number.
 - (void)writeInt32:(int32_t)fieldNumber value:(int32_t)value;
+/// Write a packaged array of int32_t for the given field number.
 - (void)writeInt32Array:(int32_t)fieldNumber
                  values:(GPBInt32Array *)values
                     tag:(uint32_t)tag;
+/// Write a int32_t without any tag.
 - (void)writeInt32NoTag:(int32_t)value;
 
+/// Write a uint32_t for the given field number.
 - (void)writeUInt32:(int32_t)fieldNumber value:(uint32_t)value;
+/// Write a packaged array of uint32_t for the given field number.
 - (void)writeUInt32Array:(int32_t)fieldNumber
                   values:(GPBUInt32Array *)values
                      tag:(uint32_t)tag;
+/// Write a uint32_t without any tag.
 - (void)writeUInt32NoTag:(uint32_t)value;
 
+/// Write a uint64_t for the given field number.
 - (void)writeFixed64:(int32_t)fieldNumber value:(uint64_t)value;
+/// Write a packaged array of uint64_t for the given field number.
 - (void)writeFixed64Array:(int32_t)fieldNumber
                    values:(GPBUInt64Array *)values
                       tag:(uint32_t)tag;
+/// Write a uint64_t without any tag.
 - (void)writeFixed64NoTag:(uint64_t)value;
 
+/// Write a uint32_t for the given field number.
 - (void)writeFixed32:(int32_t)fieldNumber value:(uint32_t)value;
+/// Write a packaged array of uint32_t for the given field number.
 - (void)writeFixed32Array:(int32_t)fieldNumber
                    values:(GPBUInt32Array *)values
                       tag:(uint32_t)tag;
+/// Write a uint32_t without any tag.
 - (void)writeFixed32NoTag:(uint32_t)value;
 
+/// Write a int32_t for the given field number.
 - (void)writeSInt32:(int32_t)fieldNumber value:(int32_t)value;
+/// Write a packaged array of int32_t for the given field number.
 - (void)writeSInt32Array:(int32_t)fieldNumber
                   values:(GPBInt32Array *)values
                      tag:(uint32_t)tag;
+/// Write a int32_t without any tag.
 - (void)writeSInt32NoTag:(int32_t)value;
 
+/// Write a int64_t for the given field number.
 - (void)writeSInt64:(int32_t)fieldNumber value:(int64_t)value;
+/// Write a packaged array of int64_t for the given field number.
 - (void)writeSInt64Array:(int32_t)fieldNumber
                   values:(GPBInt64Array *)values
                      tag:(uint32_t)tag;
+/// Write a int64_t without any tag.
 - (void)writeSInt64NoTag:(int64_t)value;
 
+/// Write a int64_t for the given field number.
 - (void)writeSFixed64:(int32_t)fieldNumber value:(int64_t)value;
+/// Write a packaged array of int64_t for the given field number.
 - (void)writeSFixed64Array:(int32_t)fieldNumber
                     values:(GPBInt64Array *)values
                        tag:(uint32_t)tag;
+/// Write a int64_t without any tag.
 - (void)writeSFixed64NoTag:(int64_t)value;
 
+/// Write a int32_t for the given field number.
 - (void)writeSFixed32:(int32_t)fieldNumber value:(int32_t)value;
+/// Write a packaged array of int32_t for the given field number.
 - (void)writeSFixed32Array:(int32_t)fieldNumber
                     values:(GPBInt32Array *)values
                        tag:(uint32_t)tag;
+/// Write a int32_t without any tag.
 - (void)writeSFixed32NoTag:(int32_t)value;
 
+/// Write a BOOL for the given field number.
 - (void)writeBool:(int32_t)fieldNumber value:(BOOL)value;
+/// Write a packaged array of BOOL for the given field number.
 - (void)writeBoolArray:(int32_t)fieldNumber
                 values:(GPBBoolArray *)values
                    tag:(uint32_t)tag;
+/// Write a BOOL without any tag.
 - (void)writeBoolNoTag:(BOOL)value;
 
+/// Write a int32_t for the given field number.
 - (void)writeEnum:(int32_t)fieldNumber value:(int32_t)value;
+/// Write a packaged array of int32_t for the given field number.
 - (void)writeEnumArray:(int32_t)fieldNumber
                 values:(GPBEnumArray *)values
                    tag:(uint32_t)tag;
+/// Write a int32_t without any tag.
 - (void)writeEnumNoTag:(int32_t)value;
 
+/// Write a NSString for the given field number.
 - (void)writeString:(int32_t)fieldNumber value:(NSString *)value;
+/// Write an array of NSString for the given field number.
 - (void)writeStringArray:(int32_t)fieldNumber values:(NSArray<NSString*> *)values;
+/// Write a NSString without any tag.
 - (void)writeStringNoTag:(NSString *)value;
 
+/// Write a GPBMessage for the given field number.
 - (void)writeMessage:(int32_t)fieldNumber value:(GPBMessage *)value;
+/// Write an array of GPBMessage for the given field number.
 - (void)writeMessageArray:(int32_t)fieldNumber values:(NSArray<GPBMessage*> *)values;
+/// Write a GPBMessage without any tag.
 - (void)writeMessageNoTag:(GPBMessage *)value;
 
+/// Write a NSData for the given field number.
 - (void)writeBytes:(int32_t)fieldNumber value:(NSData *)value;
+/// Write an array of NSData for the given field number.
 - (void)writeBytesArray:(int32_t)fieldNumber values:(NSArray<NSData*> *)values;
+/// Write a NSData without any tag.
 - (void)writeBytesNoTag:(NSData *)value;
 
+/// Write a GPBMessage for the given field number.
 - (void)writeGroup:(int32_t)fieldNumber
              value:(GPBMessage *)value;
+/// Write an array of GPBMessage for the given field number.
 - (void)writeGroupArray:(int32_t)fieldNumber values:(NSArray<GPBMessage*> *)values;
+/// Write a GPBMessage without any tag (but does write the endGroup tag).
 - (void)writeGroupNoTag:(int32_t)fieldNumber
                   value:(GPBMessage *)value;
 
+/// Write a GPBUnknownFieldSet for the given field number.
 - (void)writeUnknownGroup:(int32_t)fieldNumber
                     value:(GPBUnknownFieldSet *)value;
+/// Write an array of GPBUnknownFieldSet for the given field number.
 - (void)writeUnknownGroupArray:(int32_t)fieldNumber values:(NSArray<GPBUnknownFieldSet*> *)values;
+/// Write a GPBUnknownFieldSet without any tag (but does write the endGroup tag).
 - (void)writeUnknownGroupNoTag:(int32_t)fieldNumber
                          value:(GPBUnknownFieldSet *)value;
 
 //%PDDM-EXPAND-END _WRITE_DECLS()
 
-// Write a MessageSet extension field to the stream.  For historical reasons,
-// the wire format differs from normal fields.
+/// Write a MessageSet extension field to the stream. For historical reasons,
+/// the wire format differs from normal fields.
 - (void)writeMessageSetExtension:(int32_t)fieldNumber value:(GPBMessage *)value;
 
-// Write an unparsed MessageSet extension field to the stream.  For
-// historical reasons, the wire format differs from normal fields.
+/// Write an unparsed MessageSet extension field to the stream. For
+/// historical reasons, the wire format differs from normal fields.
 - (void)writeRawMessageSetExtension:(int32_t)fieldNumber value:(NSData *)value;
 
 @end
 
-CF_EXTERN_C_BEGIN
-
-size_t GPBComputeDoubleSize(int32_t fieldNumber, double value)
-    __attribute__((const));
-size_t GPBComputeFloatSize(int32_t fieldNumber, float value)
-    __attribute__((const));
-size_t GPBComputeUInt64Size(int32_t fieldNumber, uint64_t value)
-    __attribute__((const));
-size_t GPBComputeInt64Size(int32_t fieldNumber, int64_t value)
-    __attribute__((const));
-size_t GPBComputeInt32Size(int32_t fieldNumber, int32_t value)
-    __attribute__((const));
-size_t GPBComputeFixed64Size(int32_t fieldNumber, uint64_t value)
-    __attribute__((const));
-size_t GPBComputeFixed32Size(int32_t fieldNumber, uint32_t value)
-    __attribute__((const));
-size_t GPBComputeBoolSize(int32_t fieldNumber, BOOL value)
-    __attribute__((const));
-size_t GPBComputeStringSize(int32_t fieldNumber, NSString *value)
-    __attribute__((const));
-size_t GPBComputeGroupSize(int32_t fieldNumber, GPBMessage *value)
-    __attribute__((const));
-size_t GPBComputeUnknownGroupSize(int32_t fieldNumber,
-                                  GPBUnknownFieldSet *value)
-    __attribute__((const));
-size_t GPBComputeMessageSize(int32_t fieldNumber, GPBMessage *value)
-    __attribute__((const));
-size_t GPBComputeBytesSize(int32_t fieldNumber, NSData *value)
-    __attribute__((const));
-size_t GPBComputeUInt32Size(int32_t fieldNumber, uint32_t value)
-    __attribute__((const));
-size_t GPBComputeSFixed32Size(int32_t fieldNumber, int32_t value)
-    __attribute__((const));
-size_t GPBComputeSFixed64Size(int32_t fieldNumber, int64_t value)
-    __attribute__((const));
-size_t GPBComputeSInt32Size(int32_t fieldNumber, int32_t value)
-    __attribute__((const));
-size_t GPBComputeSInt64Size(int32_t fieldNumber, int64_t value)
-    __attribute__((const));
-size_t GPBComputeTagSize(int32_t fieldNumber) __attribute__((const));
-size_t GPBComputeWireFormatTagSize(int field_number, GPBDataType dataType)
-    __attribute__((const));
-
-size_t GPBComputeDoubleSizeNoTag(double value) __attribute__((const));
-size_t GPBComputeFloatSizeNoTag(float value) __attribute__((const));
-size_t GPBComputeUInt64SizeNoTag(uint64_t value) __attribute__((const));
-size_t GPBComputeInt64SizeNoTag(int64_t value) __attribute__((const));
-size_t GPBComputeInt32SizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeFixed64SizeNoTag(uint64_t value) __attribute__((const));
-size_t GPBComputeFixed32SizeNoTag(uint32_t value) __attribute__((const));
-size_t GPBComputeBoolSizeNoTag(BOOL value) __attribute__((const));
-size_t GPBComputeStringSizeNoTag(NSString *value) __attribute__((const));
-size_t GPBComputeGroupSizeNoTag(GPBMessage *value) __attribute__((const));
-size_t GPBComputeUnknownGroupSizeNoTag(GPBUnknownFieldSet *value)
-    __attribute__((const));
-size_t GPBComputeMessageSizeNoTag(GPBMessage *value) __attribute__((const));
-size_t GPBComputeBytesSizeNoTag(NSData *value) __attribute__((const));
-size_t GPBComputeUInt32SizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeEnumSizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeSFixed32SizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeSFixed64SizeNoTag(int64_t value) __attribute__((const));
-size_t GPBComputeSInt32SizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeSInt64SizeNoTag(int64_t value) __attribute__((const));
-
-// Note that this will calculate the size of 64 bit values truncated to 32.
-size_t GPBComputeSizeTSizeAsInt32NoTag(size_t value) __attribute__((const));
-
-size_t GPBComputeRawVarint32Size(int32_t value) __attribute__((const));
-size_t GPBComputeRawVarint64Size(int64_t value) __attribute__((const));
-
-// Note that this will calculate the size of 64 bit values truncated to 32.
-size_t GPBComputeRawVarint32SizeForInteger(NSInteger value)
-    __attribute__((const));
-
-// Compute the number of bytes that would be needed to encode a
-// MessageSet extension to the stream.  For historical reasons,
-// the wire format differs from normal fields.
-size_t GPBComputeMessageSetExtensionSize(int32_t fieldNumber, GPBMessage *value)
-    __attribute__((const));
-
-// Compute the number of bytes that would be needed to encode an
-// unparsed MessageSet extension field to the stream.  For
-// historical reasons, the wire format differs from normal fields.
-size_t GPBComputeRawMessageSetExtensionSize(int32_t fieldNumber, NSData *value)
-    __attribute__((const));
-
-size_t GPBComputeEnumSize(int32_t fieldNumber, int32_t value)
-    __attribute__((const));
-
-CF_EXTERN_C_END
-
 NS_ASSUME_NONNULL_END
 
 // Write methods for types that can be in packed arrays.
 //%PDDM-DEFINE _WRITE_PACKABLE_DECLS(NAME, ARRAY_TYPE, TYPE)
+//%/// Write a TYPE for the given field number.
 //%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE)value;
+//%/// Write a packaged array of TYPE for the given field number.
 //%- (void)write##NAME##Array:(int32_t)fieldNumber
 //%       NAME$S     values:(GPB##ARRAY_TYPE##Array *)values
 //%       NAME$S        tag:(uint32_t)tag;
+//%/// Write a TYPE without any tag.
 //%- (void)write##NAME##NoTag:(TYPE)value;
 //%
 // Write methods for types that aren't in packed arrays.
 //%PDDM-DEFINE _WRITE_UNPACKABLE_DECLS(NAME, TYPE)
+//%/// Write a TYPE for the given field number.
 //%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE *)value;
+//%/// Write an array of TYPE for the given field number.
 //%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray<##TYPE##*> *)values;
+//%/// Write a TYPE without any tag.
 //%- (void)write##NAME##NoTag:(TYPE *)value;
 //%
 // Special write methods for Groups.
 //%PDDM-DEFINE _WRITE_GROUP_DECLS(NAME, TYPE)
+//%/// Write a TYPE for the given field number.
 //%- (void)write##NAME:(int32_t)fieldNumber
 //%       NAME$S value:(TYPE *)value;
+//%/// Write an array of TYPE for the given field number.
 //%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray<##TYPE##*> *)values;
+//%/// Write a TYPE without any tag (but does write the endGroup tag).
 //%- (void)write##NAME##NoTag:(int32_t)fieldNumber
 //%            NAME$S value:(TYPE *)value;
 //%
diff --git a/objectivec/GPBCodedOutputStream.m b/objectivec/GPBCodedOutputStream.m
index 70142e6..fd9ed66 100644
--- a/objectivec/GPBCodedOutputStream.m
+++ b/objectivec/GPBCodedOutputStream.m
@@ -28,7 +28,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
 
 #import <mach/vm_param.h>
 
@@ -178,12 +178,6 @@
   return [self initWithOutputStream:nil data:data];
 }
 
-- (instancetype)initWithOutputStream:(NSOutputStream *)output
-                          bufferSize:(size_t)bufferSize {
-  NSMutableData *data = [NSMutableData dataWithLength:bufferSize];
-  return [self initWithOutputStream:output data:data];
-}
-
 // This initializer isn't exposed, but it is the designated initializer.
 // Setting OutputStream and NSData is to control the buffering behavior/size
 // of the work, but that is more obvious via the bufferSize: version.
@@ -199,15 +193,10 @@
   return self;
 }
 
-+ (instancetype)streamWithOutputStream:(NSOutputStream *)output
-                            bufferSize:(size_t)bufferSize {
-  return [[[self alloc] initWithOutputStream:output
-                                  bufferSize:bufferSize] autorelease];
-}
-
 + (instancetype)streamWithOutputStream:(NSOutputStream *)output {
+  NSMutableData *data = [NSMutableData dataWithLength:PAGE_SIZE];
   return [[[self alloc] initWithOutputStream:output
-                                  bufferSize:PAGE_SIZE] autorelease];
+                                        data:data] autorelease];
 }
 
 + (instancetype)streamWithData:(NSMutableData *)data {
diff --git a/objectivec/GPBCodedOutputStream_PackagePrivate.h b/objectivec/GPBCodedOutputStream_PackagePrivate.h
new file mode 100644
index 0000000..2e7bb4c
--- /dev/null
+++ b/objectivec/GPBCodedOutputStream_PackagePrivate.h
@@ -0,0 +1,126 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import "GPBCodedOutputStream.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+CF_EXTERN_C_BEGIN
+
+size_t GPBComputeDoubleSize(int32_t fieldNumber, double value)
+    __attribute__((const));
+size_t GPBComputeFloatSize(int32_t fieldNumber, float value)
+    __attribute__((const));
+size_t GPBComputeUInt64Size(int32_t fieldNumber, uint64_t value)
+    __attribute__((const));
+size_t GPBComputeInt64Size(int32_t fieldNumber, int64_t value)
+    __attribute__((const));
+size_t GPBComputeInt32Size(int32_t fieldNumber, int32_t value)
+    __attribute__((const));
+size_t GPBComputeFixed64Size(int32_t fieldNumber, uint64_t value)
+    __attribute__((const));
+size_t GPBComputeFixed32Size(int32_t fieldNumber, uint32_t value)
+    __attribute__((const));
+size_t GPBComputeBoolSize(int32_t fieldNumber, BOOL value)
+    __attribute__((const));
+size_t GPBComputeStringSize(int32_t fieldNumber, NSString *value)
+    __attribute__((const));
+size_t GPBComputeGroupSize(int32_t fieldNumber, GPBMessage *value)
+    __attribute__((const));
+size_t GPBComputeUnknownGroupSize(int32_t fieldNumber,
+                                  GPBUnknownFieldSet *value)
+    __attribute__((const));
+size_t GPBComputeMessageSize(int32_t fieldNumber, GPBMessage *value)
+    __attribute__((const));
+size_t GPBComputeBytesSize(int32_t fieldNumber, NSData *value)
+    __attribute__((const));
+size_t GPBComputeUInt32Size(int32_t fieldNumber, uint32_t value)
+    __attribute__((const));
+size_t GPBComputeSFixed32Size(int32_t fieldNumber, int32_t value)
+    __attribute__((const));
+size_t GPBComputeSFixed64Size(int32_t fieldNumber, int64_t value)
+    __attribute__((const));
+size_t GPBComputeSInt32Size(int32_t fieldNumber, int32_t value)
+    __attribute__((const));
+size_t GPBComputeSInt64Size(int32_t fieldNumber, int64_t value)
+    __attribute__((const));
+size_t GPBComputeTagSize(int32_t fieldNumber) __attribute__((const));
+size_t GPBComputeWireFormatTagSize(int field_number, GPBDataType dataType)
+    __attribute__((const));
+
+size_t GPBComputeDoubleSizeNoTag(double value) __attribute__((const));
+size_t GPBComputeFloatSizeNoTag(float value) __attribute__((const));
+size_t GPBComputeUInt64SizeNoTag(uint64_t value) __attribute__((const));
+size_t GPBComputeInt64SizeNoTag(int64_t value) __attribute__((const));
+size_t GPBComputeInt32SizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeFixed64SizeNoTag(uint64_t value) __attribute__((const));
+size_t GPBComputeFixed32SizeNoTag(uint32_t value) __attribute__((const));
+size_t GPBComputeBoolSizeNoTag(BOOL value) __attribute__((const));
+size_t GPBComputeStringSizeNoTag(NSString *value) __attribute__((const));
+size_t GPBComputeGroupSizeNoTag(GPBMessage *value) __attribute__((const));
+size_t GPBComputeUnknownGroupSizeNoTag(GPBUnknownFieldSet *value)
+    __attribute__((const));
+size_t GPBComputeMessageSizeNoTag(GPBMessage *value) __attribute__((const));
+size_t GPBComputeBytesSizeNoTag(NSData *value) __attribute__((const));
+size_t GPBComputeUInt32SizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeEnumSizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeSFixed32SizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeSFixed64SizeNoTag(int64_t value) __attribute__((const));
+size_t GPBComputeSInt32SizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeSInt64SizeNoTag(int64_t value) __attribute__((const));
+
+// Note that this will calculate the size of 64 bit values truncated to 32.
+size_t GPBComputeSizeTSizeAsInt32NoTag(size_t value) __attribute__((const));
+
+size_t GPBComputeRawVarint32Size(int32_t value) __attribute__((const));
+size_t GPBComputeRawVarint64Size(int64_t value) __attribute__((const));
+
+// Note that this will calculate the size of 64 bit values truncated to 32.
+size_t GPBComputeRawVarint32SizeForInteger(NSInteger value)
+    __attribute__((const));
+
+// Compute the number of bytes that would be needed to encode a
+// MessageSet extension to the stream.  For historical reasons,
+// the wire format differs from normal fields.
+size_t GPBComputeMessageSetExtensionSize(int32_t fieldNumber, GPBMessage *value)
+    __attribute__((const));
+
+// Compute the number of bytes that would be needed to encode an
+// unparsed MessageSet extension field to the stream.  For
+// historical reasons, the wire format differs from normal fields.
+size_t GPBComputeRawMessageSetExtensionSize(int32_t fieldNumber, NSData *value)
+    __attribute__((const));
+
+size_t GPBComputeEnumSize(int32_t fieldNumber, int32_t value)
+    __attribute__((const));
+
+CF_EXTERN_C_END
+
+NS_ASSUME_NONNULL_END
diff --git a/objectivec/GPBDictionary.m b/objectivec/GPBDictionary.m
index 6baa2a1..3bd146e 100644
--- a/objectivec/GPBDictionary.m
+++ b/objectivec/GPBDictionary.m
@@ -31,7 +31,7 @@
 #import "GPBDictionary_PackagePrivate.h"
 
 #import "GPBCodedInputStream_PackagePrivate.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
 #import "GPBDescriptor_PackagePrivate.h"
 #import "GPBMessage_PackagePrivate.h"
 #import "GPBUtilities_PackagePrivate.h"
diff --git a/objectivec/GPBExtensionInternals.m b/objectivec/GPBExtensionInternals.m
index 634c336..7d0dcb2 100644
--- a/objectivec/GPBExtensionInternals.m
+++ b/objectivec/GPBExtensionInternals.m
@@ -33,7 +33,7 @@
 #import <objc/runtime.h>
 
 #import "GPBCodedInputStream_PackagePrivate.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
 #import "GPBDescriptor_PackagePrivate.h"
 #import "GPBMessage_PackagePrivate.h"
 #import "GPBUtilities_PackagePrivate.h"
diff --git a/objectivec/GPBExtensionRegistry.h b/objectivec/GPBExtensionRegistry.h
index 0363c70..08a6472 100644
--- a/objectivec/GPBExtensionRegistry.h
+++ b/objectivec/GPBExtensionRegistry.h
@@ -35,30 +35,45 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
-// A table of known extensions, searchable by name or field number.  When
-// parsing a protocol message that might have extensions, you must provide an
-// ExtensionRegistry in which you have registered any extensions that you want
-// to be able to parse.  Otherwise, those extensions will just be treated like
-// unknown fields.
-//
-// The *Root classes provide +extensionRegistry for the extensions defined in a
-// given file *and* all files it imports.  You can also create a
-// GPBExtensionRegistry, and merge those registries to handle parsing extensions
-// defined from non overlapping files.
-//
-//    GPBExtensionRegistry *registry =
-//        [[[MyProtoFileRoot extensionRegistry] copy] autorelease];
-//    [registry addExtension:[OtherMessage neededExtension];  // Not in MyProtoFile
-//    NSError *parseError = nil;
-//    MyMessage *msg = [MyMessage parseData:data
-//                        extensionRegistry:registry
-//                                    error:&parseError];
-//
+/// A table of known extensions, searchable by name or field number.  When
+/// parsing a protocol message that might have extensions, you must provide a
+/// @c GPBExtensionRegistry in which you have registered any extensions that you
+/// want to be able to parse. Otherwise, those extensions will just be treated
+/// like unknown fields.
+///
+/// The @c *Root classes provide @c +extensionRegistry for the extensions defined
+/// in a given file *and* all files it imports. You can also create a
+/// @c GPBExtensionRegistry, and merge those registries to handle parsing
+/// extensions defined from non overlapping files.
+///
+/// @code
+/// GPBExtensionRegistry *registry =
+///     [[[MyProtoFileRoot extensionRegistry] copy] autorelease];
+/// [registry addExtension:[OtherMessage neededExtension];  // Not in MyProtoFile
+/// NSError *parseError = nil;
+/// MyMessage *msg = [MyMessage parseData:data
+///                     extensionRegistry:registry
+///                                 error:&parseError];
+/// @endcode
 @interface GPBExtensionRegistry : NSObject<NSCopying>
 
+/// Add the given @c GPBExtensionDescriptor to this registry.
+///
+/// @param extension The extension description to add.
 - (void)addExtension:(GPBExtensionDescriptor *)extension;
+
+/// Adds all the extensions from another registry to this registry.
+///
+/// @param registry The registry to merge into this registry.
 - (void)addExtensions:(GPBExtensionRegistry *)registry;
 
+/// Looks for the extension registered for the given field number on a given
+/// @c GPBDescriptor.
+///
+/// @param descriptor  The descriptor to look for a registered extension on.
+/// @param fieldNumber The field number of an extension to look for.
+///
+/// @return The registered @c GPBExtensionDescripto or nil if none was found.
 - (nullable GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
                                                 fieldNumber:(NSInteger)fieldNumber;
 
diff --git a/objectivec/GPBMessage.h b/objectivec/GPBMessage.h
index 332393e..58c42d0 100644
--- a/objectivec/GPBMessage.h
+++ b/objectivec/GPBMessage.h
@@ -44,23 +44,27 @@
 
 CF_EXTERN_C_BEGIN
 
-// NSError domain used for errors.
+/// NSError domain used for errors.
 extern NSString *const GPBMessageErrorDomain;
 
+/// Error code for NSError with GPBMessageErrorDomain.
 typedef NS_ENUM(NSInteger, GPBMessageErrorCode) {
+  /// The data being parsed is bad and a message can not be created from it.
   GPBMessageErrorCodeMalformedData = -100,
+  /// A message can't be serialized because it is missing required fields.
   GPBMessageErrorCodeMissingRequiredField = -101,
 };
 
-// In DEBUG ONLY, an NSException is thrown when a parsed message doesn't
-// contain required fields. This key allows you to retrieve the parsed message
-// from the exception's |userInfo| dictionary.
 #ifdef DEBUG
+/// In DEBUG ONLY, an NSException is thrown when a parsed message doesn't
+/// contain required fields. This key allows you to retrieve the parsed message
+/// from the exception's @c userInfo dictionary.
 extern NSString *const GPBExceptionMessageKey;
 #endif  // DEBUG
 
 CF_EXTERN_C_END
 
+/// Base class for all of the generated message classes.
 @interface GPBMessage : NSObject<NSSecureCoding, NSCopying>
 
 // NOTE: If you add a instance method/property to this class that may conflict
@@ -68,108 +72,235 @@
 // The main cases are methods that take no arguments, or setFoo:/hasFoo: type
 // methods.
 
+/// The unknown fields for this message.
+///
+/// Only messages from proto files declared with "proto2" syntax support unknown
+/// fields. For "proto3" syntax, any unknown fields found while parsing are
+/// dropped.
 @property(nonatomic, copy, nullable) GPBUnknownFieldSet *unknownFields;
 
-// Are all required fields in the message and all embedded messages set.
+/// Are all required fields set in the message and all embedded messages.
 @property(nonatomic, readonly, getter=isInitialized) BOOL initialized;
 
-// Returns an autoreleased instance.
+/// Returns an autoreleased instance.
 + (instancetype)message;
 
-// Create a message based on a variety of inputs.  If there is a data parse
-// error, nil is returned and if not NULL, errorPtr is filled in.
-// NOTE: In DEBUG ONLY, the message is also checked for all required field,
-// if one is missing, the parse will fail (returning nil, filling in errorPtr).
+/// Creates a new instance by parsing the data. This method should be sent to
+/// the generated message class that the data should be interpreted as. If
+/// there is an error the method returns nil and the error is returned in
+/// errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+///       fields were provided, and the parse will fail if some are missing.
+///
+/// @param data     The data to parse.
+/// @param errorPtr An optional error pointer to fill in with a failure reason if
+///                 the data can not be parsed.
+///
+/// @return A new instance of the class messaged.
 + (instancetype)parseFromData:(NSData *)data error:(NSError **)errorPtr;
+
+/// Creates a new instance by parsing the data. This method should be sent to
+/// the generated message class that the data should be interpreted as. If
+/// there is an error the method returns nil and the error is returned in
+/// errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+///       fields were provided, and the parse will fail if some are missing.
+///
+/// @param data              The data to parse.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr          An optional error pointer to fill in with a failure
+///                          reason if the data can not be parsed.
+///
+/// @return A new instance of the class messaged.
 + (instancetype)parseFromData:(NSData *)data
             extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry
                         error:(NSError **)errorPtr;
+
+/// Creates a new instance by parsing the data from the given input stream. This
+/// method should be sent to the generated message class that the data should
+/// be interpreted as. If there is an error the method returns nil and the error
+/// is returned in errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+///       fields were provided, and the parse will fail if some are missing.
+///
+/// @param input             The stream to read data from.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr          An optional error pointer to fill in with a failure
+///                          reason if the data can not be parsed.
+///
+/// @return A new instance of the class messaged.
 + (instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input
                         extensionRegistry:
                             (nullable GPBExtensionRegistry *)extensionRegistry
                                     error:(NSError **)errorPtr;
 
-// Create a message based on delimited input.  If there is a data parse
-// error, nil is returned and if not NULL, errorPtr is filled in.
+/// Creates a new instance by parsing the data from the given input stream. This
+/// method should be sent to the generated message class that the data should
+/// be interpreted as. If there is an error the method returns nil and the error
+/// is returned in errorPtr (when provided).
+///
+/// @note Unlike the parseFrom... methods, this never checks to see if all of
+///       the required fields are set. So this method can be used to reload
+///       messages that may not be complete.
+///
+/// @param input             The stream to read data from.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr          An optional error pointer to fill in with a failure
+///                          reason if the data can not be parsed.
+///
+/// @return A new instance of the class messaged.
 + (instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
                                  extensionRegistry:
                                      (nullable GPBExtensionRegistry *)extensionRegistry
                                              error:(NSError **)errorPtr;
 
-// If there is a data parse error, nil is returned and if not NULL, errorPtr is
-// filled in.
-// NOTE: In DEBUG ONLY, the message is also checked for all required field,
-// if one is missing, the parse will fail (returning nil, filling in errorPtr).
+/// Initializes an instance by parsing the data. This method should be sent to
+/// the generated message class that the data should be interpreted as. If
+/// there is an error the method returns nil and the error is returned in
+/// errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+///       fields were provided, and the parse will fail if some are missing.
+///
+/// @param data     The data to parse.
+/// @param errorPtr An optional error pointer to fill in with a failure reason if
+///                 the data can not be parsed.
 - (instancetype)initWithData:(NSData *)data error:(NSError **)errorPtr;
+
+/// Initializes an instance by parsing the data. This method should be sent to
+/// the generated message class that the data should be interpreted as. If
+/// there is an error the method returns nil and the error is returned in
+/// errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+///       fields were provided, and the parse will fail if some are missing.
+///
+/// @param data              The data to parse.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr          An optional error pointer to fill in with a failure
+///                          reason if the data can not be parsed.
 - (instancetype)initWithData:(NSData *)data
            extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry
                        error:(NSError **)errorPtr;
+
+/// Initializes an instance by parsing the data from the given input stream. This
+/// method should be sent to the generated message class that the data should
+/// be interpreted as. If there is an error the method returns nil and the error
+/// is returned in errorPtr (when provided).
+///
+/// @note Unlike the parseFrom... methods, this never checks to see if all of
+///       the required fields are set. So this method can be used to reload
+///       messages that may not be complete.
+///
+/// @param input             The stream to read data from.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr          An optional error pointer to fill in with a failure
+///                          reason if the data can not be parsed.
 - (instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input
                        extensionRegistry:
                            (nullable GPBExtensionRegistry *)extensionRegistry
                                    error:(NSError **)errorPtr;
 
-// Serializes the message and writes it to output.
+/// Writes out the message to the given output stream.
 - (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output;
+/// Writes out the message to the given output stream.
 - (void)writeToOutputStream:(NSOutputStream *)output;
 
-// Serializes the message and writes it to output, but writes the size of the
-// message as a variant before writing the message.
+/// Writes out a varint for the message size followed by the the message to
+/// the given output stream.
 - (void)writeDelimitedToCodedOutputStream:(GPBCodedOutputStream *)output;
+/// Writes out a varint for the message size followed by the the message to
+/// the given output stream.
 - (void)writeDelimitedToOutputStream:(NSOutputStream *)output;
 
-// Serializes the message to an NSData. Note that this value is not cached, so
-// if you are using it repeatedly, cache it yourself. If there is an error
-// while generating the data, nil is returned.
-// NOTE: In DEBUG ONLY, the message is also checked for all required field,
-// if one is missing, nil will be returned.
+/// Serializes the message to a @c NSData.
+///
+/// If there is an error while generating the data, nil is returned.
+///
+/// @note This value is not cached, so if you are using it repeatedly, cache
+///       it yourself.
+///
+/// @note In DEBUG ONLY, the message is also checked for all required field,
+///       if one is missing, nil will be returned.
 - (nullable NSData *)data;
 
-// Same as -[data], except a delimiter is added to the start of the data
-// indicating the size of the message data that follows.
+/// Serializes a varint with the message size followed by the message data,
+/// returning that as a @c NSData.
+///
+/// @note This value is not cached, so if you are using it repeatedly, cache
+///       it yourself.
 - (NSData *)delimitedData;
 
-// Returns the size of the object if it were serialized.
-// This is not a cached value. If you are following a pattern like this:
-//   size_t size = [aMsg serializedSize];
-//   NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
-//   [foo writeSize:size];
-//   [foo appendData:[aMsg data]];
-// you would be better doing:
-//   NSData *data = [aMsg data];
-//   NSUInteger size = [aMsg length];
-//   NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
-//   [foo writeSize:size];
-//   [foo appendData:data];
+/// Calculates the size of the object if it were serialized.
+///
+/// This is not a cached value. If you are following a pattern like this:
+/// @code
+///   size_t size = [aMsg serializedSize];
+///   NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
+///   [foo writeSize:size];
+///   [foo appendData:[aMsg data]];
+/// @endcode
+/// you would be better doing:
+/// @code
+///   NSData *data = [aMsg data];
+///   NSUInteger size = [aMsg length];
+///   NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
+///   [foo writeSize:size];
+///   [foo appendData:data];
+/// @endcode
 - (size_t)serializedSize;
 
-// Return the descriptor for the message
+/// Return the descriptor for the message class.
 + (GPBDescriptor *)descriptor;
+/// Return the descriptor for the message.
 - (GPBDescriptor *)descriptor;
 
-// Extensions use boxed values (NSNumbers) for PODs, NSMutableArrays for
-// repeated. If the extension is a Message one will be auto created for you
-// and returned similar to fields.
+/// Test to see if the given extension is set on the message.
 - (BOOL)hasExtension:(GPBExtensionDescriptor *)extension;
+
+/// Fetches the given extension's value for this message.
+///
+/// Extensions use boxed values (NSNumbers) for PODs and NSMutableArrays for
+/// repeated fields. If the extension is a Message one will be auto created for you
+/// and returned similar to fields.
 - (nullable id)getExtension:(GPBExtensionDescriptor *)extension;
+
+/// Sets the given extension's value for this message. This is only for single
+/// field extensions (i.e. - not repeated fields).
+///
+/// Extensions use boxed values (@c NSNumbers).
 - (void)setExtension:(GPBExtensionDescriptor *)extension value:(nullable id)value;
+
+/// Adds the given value to the extension for this message. This is only for
+/// repeated field extensions. If the field is a repeated POD type the @c value
+/// is a @c NSNumber.
 - (void)addExtension:(GPBExtensionDescriptor *)extension value:(id)value;
+
+/// Replaces the given value at an index for the extension on this message. This
+/// is only for repeated field extensions. If the field is a repeated POD type
+/// the @c value is a @c NSNumber.
 - (void)setExtension:(GPBExtensionDescriptor *)extension
                index:(NSUInteger)index
                value:(id)value;
+
+/// Clears the given extension for this message.
 - (void)clearExtension:(GPBExtensionDescriptor *)extension;
 
-// Resets all fields to their default values.
+/// Resets all of the fields of this message to their default values.
 - (void)clear;
 
-// Parses a message of this type from the input and merges it with this
-// message.
-// NOTE: This will throw if there is an error parsing the data.
+/// Parses a message of this type from the input and merges it with this
+/// message.
+///
+/// @note This will throw if there is an error parsing the data.
 - (void)mergeFromData:(NSData *)data
     extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry;
 
-// Merges the fields from another message (of the same type) into this
-// message.
+/// Merges the fields from another message (of the same type) into this
+/// message.
 - (void)mergeFrom:(GPBMessage *)other;
 
 @end
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m
index fdb695e..d5e8d37 100644
--- a/objectivec/GPBMessage.m
+++ b/objectivec/GPBMessage.m
@@ -35,7 +35,7 @@
 
 #import "GPBArray_PackagePrivate.h"
 #import "GPBCodedInputStream_PackagePrivate.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
 #import "GPBDescriptor_PackagePrivate.h"
 #import "GPBDictionary_PackagePrivate.h"
 #import "GPBExtensionInternals.h"
diff --git a/objectivec/GPBRootObject.h b/objectivec/GPBRootObject.h
index e2af5d9..c05b5c6 100644
--- a/objectivec/GPBRootObject.h
+++ b/objectivec/GPBRootObject.h
@@ -34,11 +34,12 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
-// All Root Objects derive from GPBRootObject. It supplies a registry
-// for derived classes to register their extensions to.
+/// Every generated proto file defines a local "Root" class that exposes a
+/// @c GPBExtensionRegistry for all the extensions defined by that file and
+/// the files it depends on.
 @interface GPBRootObject : NSObject
 
-// Per class registry.
+/// An extension registry for the given file and all the files it depends on.
 + (GPBExtensionRegistry *)extensionRegistry;
 
 @end
diff --git a/objectivec/GPBUnknownField.h b/objectivec/GPBUnknownField.h
index 43709ee..0f301e4 100644
--- a/objectivec/GPBUnknownField.h
+++ b/objectivec/GPBUnknownField.h
@@ -37,22 +37,51 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+/// Store an unknown field. These are used in conjunction with @c GPBUnknownFieldSet
 @interface GPBUnknownField : NSObject<NSCopying>
 
+/// The field number the data is stored under.
 @property(nonatomic, readonly, assign) int32_t number;
 
-// Only one of these will be set.
+/// An array of varint values for this field.
 @property(nonatomic, readonly, strong) GPBUInt64Array *varintList;
+
+/// An array of fixed32 values for this field.
 @property(nonatomic, readonly, strong) GPBUInt32Array *fixed32List;
+
+/// An array of fixed64 values for this field.
 @property(nonatomic, readonly, strong) GPBUInt64Array *fixed64List;
+
+/// An array of data values for this field.
 @property(nonatomic, readonly, strong) NSArray<NSData*> *lengthDelimitedList;
+
+/// An array of groups of values for this field.
 @property(nonatomic, readonly, strong) NSArray<GPBUnknownFieldSet*> *groupList;
 
-// Only one of these should be used per Field.
+
+/// Add a value to the varintList.
+///
+/// @param value The value to add.
 - (void)addVarint:(uint64_t)value;
+
+/// Add a value to the fixed32List.
+///
+/// @param value The value to add.
 - (void)addFixed32:(uint32_t)value;
+
+/// Add a value to the fixed64List.
+///
+/// @param value The value to add.
 - (void)addFixed64:(uint64_t)value;
+
+/// Add a value to the lengthDelimitedList.
+///
+/// @param value The value to add.
 - (void)addLengthDelimited:(NSData *)value;
+
+/// Add a value to the groupList.
+///
+/// @param value The value to add.
 - (void)addGroup:(GPBUnknownFieldSet *)value;
 
 @end
diff --git a/objectivec/GPBUnknownField.m b/objectivec/GPBUnknownField.m
index 22ed66a..0e29bde 100644
--- a/objectivec/GPBUnknownField.m
+++ b/objectivec/GPBUnknownField.m
@@ -31,7 +31,7 @@
 #import "GPBUnknownField_PackagePrivate.h"
 
 #import "GPBArray.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
 
 @implementation GPBUnknownField {
  @protected
diff --git a/objectivec/GPBUnknownFieldSet.h b/objectivec/GPBUnknownFieldSet.h
index 8db0132..cf61299 100644
--- a/objectivec/GPBUnknownFieldSet.h
+++ b/objectivec/GPBUnknownFieldSet.h
@@ -34,15 +34,30 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+/// A collection of unknown fields.
 @interface GPBUnknownFieldSet : NSObject<NSCopying>
 
+/// Tests to see if the given field number has a value.
+///
+/// @param number The field number to check.
+///
+/// @return YES if there is an unknown field for the given field number.
 - (BOOL)hasField:(int32_t)number;
+
+/// Fetches the @c GPBUnknownField for the given field number.
+///
+/// @param number The field number to look up.
+///
+/// @return The @c GPBUnknownField or nil.
 - (nullable GPBUnknownField *)getField:(int32_t)number;
+
+/// Returns the number of fields in this set.
 - (NSUInteger)countOfFields;
 
+/// Adds the given field to the set.
 - (void)addField:(GPBUnknownField *)field;
 
-// Returns an NSArray of the GPBUnknownFields sorted by the field numbers.
+/// Returns an NSArray of the @c GPBUnknownFields sorted by the field numbers.
 - (NSArray<GPBUnknownField*> *)sortedFields;
 
 @end
diff --git a/objectivec/GPBUtilities.h b/objectivec/GPBUtilities.h
index 5b55104..b720932 100644
--- a/objectivec/GPBUtilities.h
+++ b/objectivec/GPBUtilities.h
@@ -38,24 +38,34 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
-// Generates a string that should be a valid "Text Format" for the C++ version
-// of Protocol Buffers. lineIndent can be nil if no additional line indent is
-// needed. The comments provide the names according to the ObjC library, they
-// most likely won't exactly match the original .proto file.
+/// Generates a string that should be a valid "Text Format" for the C++ version
+/// of Protocol Buffers.
+///
+///  @param message    The message to generate from.
+///  @param lineIndent A string to use as the prefix for all lines generated. Can
+///                    be nil if no extra indent is needed.
+///
+/// @return A @c NSString with the Text Format of the message.
 NSString *GPBTextFormatForMessage(GPBMessage *message,
                                   NSString * __nullable lineIndent);
+
+/// Generates a string that should be a valid "Text Format" for the C++ version
+/// of Protocol Buffers.
+///
+///  @param unknownSet The unknown field set to generate from.
+///  @param lineIndent A string to use as the prefix for all lines generated. Can
+///                    be nil if no extra indent is needed.
+///
+/// @return A @c NSString with the Text Format of the unknown field set.
 NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet * __nullable unknownSet,
                                           NSString * __nullable lineIndent);
 
-//
-// Test if the given field is set on a message.
-//
+/// Test if the given field is set on a message.
 BOOL GPBMessageHasFieldNumberSet(GPBMessage *self, uint32_t fieldNumber);
+/// Test if the given field is set on a message.
 BOOL GPBMessageHasFieldSet(GPBMessage *self, GPBFieldDescriptor *field);
 
-//
-// Clear the given field of a message.
-//
+/// Clear the given field of a message.
 void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field);
 
 //%PDDM-EXPAND GPB_ACCESSORS()
@@ -68,60 +78,100 @@
 
 // Single Fields
 
+/// Gets the value of a bytes field.
 NSData *GPBGetMessageBytesField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a bytes field.
 void GPBSetMessageBytesField(GPBMessage *self, GPBFieldDescriptor *field, NSData *value);
 
+/// Gets the value of a string field.
 NSString *GPBGetMessageStringField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a string field.
 void GPBSetMessageStringField(GPBMessage *self, GPBFieldDescriptor *field, NSString *value);
 
+/// Gets the value of a message field.
 GPBMessage *GPBGetMessageMessageField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a message field.
 void GPBSetMessageMessageField(GPBMessage *self, GPBFieldDescriptor *field, GPBMessage *value);
 
+/// Gets the value of a group field.
 GPBMessage *GPBGetMessageGroupField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a group field.
 void GPBSetMessageGroupField(GPBMessage *self, GPBFieldDescriptor *field, GPBMessage *value);
 
+/// Gets the value of a bool field.
 BOOL GPBGetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a bool field.
 void GPBSetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field, BOOL value);
 
+/// Gets the value of an int32 field.
 int32_t GPBGetMessageInt32Field(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of an int32 field.
 void GPBSetMessageInt32Field(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
 
+/// Gets the value of an uint32 field.
 uint32_t GPBGetMessageUInt32Field(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of an uint32 field.
 void GPBSetMessageUInt32Field(GPBMessage *self, GPBFieldDescriptor *field, uint32_t value);
 
+/// Gets the value of an int64 field.
 int64_t GPBGetMessageInt64Field(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of an int64 field.
 void GPBSetMessageInt64Field(GPBMessage *self, GPBFieldDescriptor *field, int64_t value);
 
+/// Gets the value of an uint64 field.
 uint64_t GPBGetMessageUInt64Field(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of an uint64 field.
 void GPBSetMessageUInt64Field(GPBMessage *self, GPBFieldDescriptor *field, uint64_t value);
 
+/// Gets the value of a float field.
 float GPBGetMessageFloatField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a float field.
 void GPBSetMessageFloatField(GPBMessage *self, GPBFieldDescriptor *field, float value);
 
+/// Gets the value of a double field.
 double GPBGetMessageDoubleField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a double field.
 void GPBSetMessageDoubleField(GPBMessage *self, GPBFieldDescriptor *field, double value);
 
-// Get/Set the given enum field of a message.  You can only Set values that are
-// members of the enum.  For proto3, when doing a Get, if the value isn't a
-// memeber of the enum, kGPBUnrecognizedEnumeratorValue will be returned. The
-// the functions with "Raw" in the will bypass all checks.
+/// Get the given enum field of a message. For proto3, if the value isn't a
+/// member of the enum, @c kGPBUnrecognizedEnumeratorValue will be returned.
+/// GPBGetMessageRawEnumField will bypass the check and return whatever value
+/// was set.
 int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Set the given enum field of a message. You can only set values that are
+/// members of the enum.
 void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+/// Get the given enum field of a message. No check is done to ensure the value
+/// was defined in the enum.
 int32_t GPBGetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Set the given enum field of a message. You can set the value to anything,
+/// even a value that is not a member of the enum.
 void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
 
 // Repeated Fields
 
-// The object will/should be GPB*Array or NSMutableArray based on the field's
-// type.
+/// Gets the value of a repeated field.
+///
+/// The result will be @c GPB*Array or @c NSMutableArray based on the
+/// field's type.
 id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a repeated field.
+///
+/// The value should be @c GPB*Array or @c NSMutableArray based on the
+/// field's type.
 void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array);
 
 // Map Fields
 
-// The object will/should be GPB*Dictionary or NSMutableDictionary based on the
-// field's type.
+/// Gets the value of a map<> field.
+///
+/// The result will be @c GPB*Dictionary or @c NSMutableDictionary based on
+/// the field's type.
 id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a map<> field.
+///
+/// The object should be @c GPB*Dictionary or @c NSMutableDictionary based
+/// on the field's type.
 void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, id dictionary);
 
 //%PDDM-EXPAND-END GPB_ACCESSORS()
@@ -144,44 +194,64 @@
 //%
 //%// Single Fields
 //%
-//%GPB_ACCESSOR_SINGLE_FULL(Bytes, NSData, *)
-//%GPB_ACCESSOR_SINGLE_FULL(String, NSString, *)
-//%GPB_ACCESSOR_SINGLE_FULL(Message, GPBMessage, *)
-//%GPB_ACCESSOR_SINGLE_FULL(Group, GPBMessage, *)
-//%GPB_ACCESSOR_SINGLE(Bool, BOOL)
-//%GPB_ACCESSOR_SINGLE(Int32, int32_t)
-//%GPB_ACCESSOR_SINGLE(UInt32, uint32_t)
-//%GPB_ACCESSOR_SINGLE(Int64, int64_t)
-//%GPB_ACCESSOR_SINGLE(UInt64, uint64_t)
-//%GPB_ACCESSOR_SINGLE(Float, float)
-//%GPB_ACCESSOR_SINGLE(Double, double)
-//%// Get/Set the given enum field of a message.  You can only Set values that are
-//%// members of the enum.  For proto3, when doing a Get, if the value isn't a
-//%// memeber of the enum, kGPBUnrecognizedEnumeratorValue will be returned. The
-//%// the functions with "Raw" in the will bypass all checks.
+//%GPB_ACCESSOR_SINGLE_FULL(Bytes, NSData, , *)
+//%GPB_ACCESSOR_SINGLE_FULL(String, NSString, , *)
+//%GPB_ACCESSOR_SINGLE_FULL(Message, GPBMessage, , *)
+//%GPB_ACCESSOR_SINGLE_FULL(Group, GPBMessage, , *)
+//%GPB_ACCESSOR_SINGLE(Bool, BOOL, )
+//%GPB_ACCESSOR_SINGLE(Int32, int32_t, n)
+//%GPB_ACCESSOR_SINGLE(UInt32, uint32_t, n)
+//%GPB_ACCESSOR_SINGLE(Int64, int64_t, n)
+//%GPB_ACCESSOR_SINGLE(UInt64, uint64_t, n)
+//%GPB_ACCESSOR_SINGLE(Float, float, )
+//%GPB_ACCESSOR_SINGLE(Double, double, )
+//%/// Get the given enum field of a message. For proto3, if the value isn't a
+//%/// member of the enum, @c kGPBUnrecognizedEnumeratorValue will be returned.
+//%/// GPBGetMessageRawEnumField will bypass the check and return whatever value
+//%/// was set.
 //%int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Set the given enum field of a message. You can only set values that are
+//%/// members of the enum.
 //%void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+//%/// Get the given enum field of a message. No check is done to ensure the value
+//%/// was defined in the enum.
 //%int32_t GPBGetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Set the given enum field of a message. You can set the value to anything,
+//%/// even a value that is not a member of the enum.
 //%void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
 //%
 //%// Repeated Fields
 //%
-//%// The object will/should be GPB*Array or NSMutableArray based on the field's
-//%// type.
+//%/// Gets the value of a repeated field.
+//%///
+//%/// The result will be @c GPB*Array or @c NSMutableArray based on the
+//%/// field's type.
 //%id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Sets the value of a repeated field.
+//%///
+//%/// The value should be @c GPB*Array or @c NSMutableArray based on the
+//%/// field's type.
 //%void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array);
 //%
 //%// Map Fields
 //%
-//%// The object will/should be GPB*Dictionary or NSMutableDictionary based on the
-//%// field's type.
+//%/// Gets the value of a map<> field.
+//%///
+//%/// The result will be @c GPB*Dictionary or @c NSMutableDictionary based on
+//%/// the field's type.
 //%id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Sets the value of a map<> field.
+//%///
+//%/// The object should be @c GPB*Dictionary or @c NSMutableDictionary based
+//%/// on the field's type.
 //%void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, id dictionary);
 //%
 
-//%PDDM-DEFINE GPB_ACCESSOR_SINGLE(NAME, TYPE)
-//%GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, )
-//%PDDM-DEFINE GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, TisP)
+//%PDDM-DEFINE GPB_ACCESSOR_SINGLE(NAME, TYPE, AN)
+//%GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, AN, )
+//%PDDM-DEFINE GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, AN, TisP)
+//%/// Gets the value of a##AN NAME$L field.
 //%TYPE TisP##GPBGetMessage##NAME##Field(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Sets the value of a##AN NAME$L field.
 //%void GPBSetMessage##NAME##Field(GPBMessage *self, GPBFieldDescriptor *field, TYPE TisP##value);
 //%
diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
index 6b34b9b..78c3f9b 100644
--- a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
@@ -188,6 +188,7 @@
 		F4487C7C1AAE06AC00531423 /* GPBUtilities_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUtilities_PackagePrivate.h; sourceTree = "<group>"; };
 		F4487C7E1AAF62CD00531423 /* GPBMessageTests+Serialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Serialization.m"; sourceTree = "<group>"; };
 		F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Merge.m"; sourceTree = "<group>"; };
+		F44929001C866B1900C2548A /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedOutputStream_PackagePrivate.h; sourceTree = "<group>"; };
 		F451D3F51A8AAE8700B8A22C /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBProtocolBuffers_RuntimeSupport.h; sourceTree = "<group>"; };
 		F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = "<group>"; };
 		F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = "<group>"; };
@@ -368,9 +369,10 @@
 		7461B4860F94F96B00A0C422 /* IO */ = {
 			isa = PBXGroup;
 			children = (
-				7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
 				51457B5F18D0B7AF00CCC606 /* GPBCodedInputStream_PackagePrivate.h */,
+				7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
 				7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */,
+				F44929001C866B1900C2548A /* GPBCodedOutputStream_PackagePrivate.h */,
 				7461B4900F94F99000A0C422 /* GPBCodedOutputStream.h */,
 				7461B4910F94F99000A0C422 /* GPBCodedOutputStream.m */,
 				7461B4E70F94F99000A0C422 /* GPBWireFormat.h */,
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
index e9d3fc9..5d96c05 100644
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
@@ -209,6 +209,7 @@
 		F4487C7D1AAE06C500531423 /* GPBUtilities_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUtilities_PackagePrivate.h; sourceTree = "<group>"; };
 		F4487C801AAF62FC00531423 /* GPBMessageTests+Serialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Serialization.m"; sourceTree = "<group>"; };
 		F4487C841AAF6AC500531423 /* GPBMessageTests+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Merge.m"; sourceTree = "<group>"; };
+		F44929021C866B3B00C2548A /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedOutputStream_PackagePrivate.h; sourceTree = "<group>"; };
 		F451D3F61A8AAEA600B8A22C /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBProtocolBuffers_RuntimeSupport.h; sourceTree = "<group>"; };
 		F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = "<group>"; };
 		F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = "<group>"; };
@@ -405,9 +406,10 @@
 		7461B4860F94F96B00A0C422 /* IO */ = {
 			isa = PBXGroup;
 			children = (
-				7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
 				51457B5F18D0B7AF00CCC606 /* GPBCodedInputStream_PackagePrivate.h */,
+				7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
 				7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */,
+				F44929021C866B3B00C2548A /* GPBCodedOutputStream_PackagePrivate.h */,
 				7461B4900F94F99000A0C422 /* GPBCodedOutputStream.h */,
 				7461B4910F94F99000A0C422 /* GPBCodedOutputStream.m */,
 				7461B4E70F94F99000A0C422 /* GPBWireFormat.h */,
diff --git a/objectivec/Tests/GPBCodedOuputStreamTests.m b/objectivec/Tests/GPBCodedOuputStreamTests.m
index 77d8803..0723b64 100644
--- a/objectivec/Tests/GPBCodedOuputStreamTests.m
+++ b/objectivec/Tests/GPBCodedOuputStreamTests.m
@@ -30,11 +30,30 @@
 
 #import "GPBTestUtilities.h"
 
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
 #import "GPBCodedInputStream.h"
 #import "GPBUtilities_PackagePrivate.h"
 #import "google/protobuf/Unittest.pbobjc.h"
 
+@interface GPBCodedOutputStream (InternalMethods)
+// Declared in the .m file, expose for testing.
+- (instancetype)initWithOutputStream:(NSOutputStream *)output
+                                data:(NSMutableData *)data;
+@end
+
+@interface GPBCodedOutputStream (Helper)
++ (instancetype)streamWithOutputStream:(NSOutputStream *)output
+                            bufferSize:(size_t)bufferSize;
+@end
+
+@implementation GPBCodedOutputStream (Helper)
++ (instancetype)streamWithOutputStream:(NSOutputStream *)output
+                            bufferSize:(size_t)bufferSize {
+  NSMutableData *data = [NSMutableData dataWithLength:bufferSize];
+  return [[[self alloc] initWithOutputStream:output data:data] autorelease];
+}
+@end
+
 @interface CodedOutputStreamTests : GPBTestCase
 @end
 
diff --git a/objectivec/Tests/GPBMessageTests.m b/objectivec/Tests/GPBMessageTests.m
index 7b37ca9..4354615 100644
--- a/objectivec/Tests/GPBMessageTests.m
+++ b/objectivec/Tests/GPBMessageTests.m
@@ -1820,6 +1820,24 @@
   XCTAssertEqualObjects(enumDescriptor, expectedDescriptor);
 }
 
+- (void)testPropertyNaming {
+  // objectivec_helpers.cc has some special handing to get proper all caps
+  // for a few cases to meet objc developer expectations.
+  //
+  // This "test" confirms that the expected names are generated, otherwise the
+  // test itself will fail to compile.
+  ObjCPropertyNaming *msg = [ObjCPropertyNaming message];
+  // On their own, at the end, in the middle.
+  msg.URL = @"good";
+  msg.thumbnailURL = @"good";
+  msg.URLFoo = @"good";
+  msg.someURLBlah = @"good";
+  msg.HTTP = @"good";
+  msg.HTTPS = @"good";
+  // No caps since it was "urls".
+  [msg.urlsArray addObject:@"good"];
+}
+
 - (void)testEnumNaming {
   // objectivec_helpers.cc has some interesting cases to deal with in
   // EnumValueName/EnumValueShortName.  Confirm that things generated as
diff --git a/objectivec/Tests/unittest_objc.proto b/objectivec/Tests/unittest_objc.proto
index 3bb9276..9483cb1 100644
--- a/objectivec/Tests/unittest_objc.proto
+++ b/objectivec/Tests/unittest_objc.proto
@@ -112,6 +112,18 @@
   serializedSize = 6;
 }
 
+message ObjCPropertyNaming {
+  // Test that the properties properly get things all caps.
+  optional string url           = 1;
+  optional string thumbnail_url = 2;
+  optional string url_foo       = 3;
+  optional string some_url_blah = 4;
+  optional string http          = 5;
+  optional string https         = 6;
+  // This one doesn't.
+  repeated string urls          = 7;
+}
+
 // EnumValueShortName: The short names shouldn't get suffixes/prefixes.
 enum Foo {
   SERIALIZED_SIZE = 1;
diff --git a/objectivec/google/protobuf/Any.pbobjc.h b/objectivec/google/protobuf/Any.pbobjc.h
index 9866b5b..a204ae9 100644
--- a/objectivec/google/protobuf/Any.pbobjc.h
+++ b/objectivec/google/protobuf/Any.pbobjc.h
@@ -15,13 +15,15 @@
 
 #pragma mark - GPBAnyRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBAnyRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBAny
@@ -31,61 +33,61 @@
   GPBAny_FieldNumber_Value = 2,
 };
 
-// `Any` contains an arbitrary serialized message along with a URL
-// that describes the type of the serialized message.
-//
-//
-// 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"
-//     }
+/// `Any` contains an arbitrary serialized message along with a URL
+/// that describes the type of the serialized message.
+///
+///
+/// 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"
+///     }
 @interface GPBAny : GPBMessage
 
-// A URL/resource name whose content describes the type of the
-// serialized message.
-//
-// For URLs which use the schema `http`, `https`, or no schema, the
-// following restrictions and interpretations apply:
-//
-// * If no schema is provided, `https` is assumed.
-// * The last segment of the URL's path must represent the fully
-//   qualified name of the type (as in `path/google.protobuf.Duration`).
-// * 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.)
-//
-// Schemas other than `http`, `https` (or the empty schema) might be
-// used with implementation specific semantics.
+/// A URL/resource name whose content describes the type of the
+/// serialized message.
+///
+/// For URLs which use the schema `http`, `https`, or no schema, the
+/// following restrictions and interpretations apply:
+///
+/// * If no schema is provided, `https` is assumed.
+/// * The last segment of the URL's path must represent the fully
+///   qualified name of the type (as in `path/google.protobuf.Duration`).
+/// * 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.)
+///
+/// Schemas other than `http`, `https` (or the empty schema) might be
+/// used with implementation specific semantics.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL;
 
-// Must be valid serialized data of the above specified type.
+/// Must be valid serialized data of the above specified type.
 @property(nonatomic, readwrite, copy, null_resettable) NSData *value;
 
 @end
diff --git a/objectivec/google/protobuf/Api.pbobjc.h b/objectivec/google/protobuf/Api.pbobjc.h
index 8d82b15..271a166 100644
--- a/objectivec/google/protobuf/Api.pbobjc.h
+++ b/objectivec/google/protobuf/Api.pbobjc.h
@@ -21,13 +21,15 @@
 
 #pragma mark - GPBApiRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBApiRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBApi
@@ -42,58 +44,67 @@
   GPBApi_FieldNumber_Syntax = 7,
 };
 
-// Api is a light-weight descriptor for a protocol buffer service.
+/// Api is a light-weight descriptor for a protocol buffer service.
 @interface GPBApi : GPBMessage
 
-// The fully qualified name of this api, including package name
-// followed by the api's simple name.
+/// The fully qualified name of this api, including package name
+/// followed by the api's simple name.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
 
-// The methods of this api, in unspecified order.
+/// The methods of this api, in unspecified order.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMethod*> *methodsArray;
+/// The number of items in @c methodsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger methodsArray_Count;
 
-// Any metadata attached to the API.
+/// Any metadata attached to the API.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
-// A version string for this api. If specified, must have the form
-// `major-version.minor-version`, as in `1.10`. If the minor version
-// is omitted, it defaults to zero. If the entire version field is
-// empty, the major version is derived from the package name, as
-// outlined below. If the field is not empty, the version in the
-// package name will be verified to be consistent with what is
-// provided here.
-//
-// The versioning schema uses [semantic
-// versioning](http://semver.org) where the major version number
-// indicates a breaking change and the minor version an additive,
-// non-breaking change. Both version numbers are signals to users
-// what to expect from different versions, and should be carefully
-// chosen based on the product plan.
-//
-// The major version is also reflected in the package name of the
-// API, which must end in `v<major-version>`, as in
-// `google.feature.v1`. For major versions 0 and 1, the suffix can
-// be omitted. Zero major versions must only be used for
-// experimental, none-GA apis.
+/// A version string for this api. If specified, must have the form
+/// `major-version.minor-version`, as in `1.10`. If the minor version
+/// is omitted, it defaults to zero. If the entire version field is
+/// empty, the major version is derived from the package name, as
+/// outlined below. If the field is not empty, the version in the
+/// package name will be verified to be consistent with what is
+/// provided here.
+///
+/// The versioning schema uses [semantic
+/// versioning](http://semver.org) where the major version number
+/// indicates a breaking change and the minor version an additive,
+/// non-breaking change. Both version numbers are signals to users
+/// what to expect from different versions, and should be carefully
+/// chosen based on the product plan.
+///
+/// The major version is also reflected in the package name of the
+/// API, which must end in `v<major-version>`, as in
+/// `google.feature.v1`. For major versions 0 and 1, the suffix can
+/// be omitted. Zero major versions must only be used for
+/// experimental, none-GA apis.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *version;
 
-// Source context for the protocol buffer service represented by this
-// message.
-@property(nonatomic, readwrite) BOOL hasSourceContext;
+/// Source context for the protocol buffer service represented by this
+/// message.
 @property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
 
-// Included APIs. See [Mixin][].
+/// Included APIs. See [Mixin][].
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMixin*> *mixinsArray;
+/// The number of items in @c mixinsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger mixinsArray_Count;
 
-// The source syntax of the service.
+/// The source syntax of the service.
 @property(nonatomic, readwrite) enum GPBSyntax syntax;
 
 @end
 
+/// Fetches the raw value of a @c GPBApi's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
 int32_t GPBApi_Syntax_RawValue(GPBApi *message);
+/// Sets the raw value of an @c GPBApi's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
 void SetGPBApi_Syntax_RawValue(GPBApi *message, int32_t value);
 
 #pragma mark - GPBMethod
@@ -108,34 +119,40 @@
   GPBMethod_FieldNumber_Syntax = 7,
 };
 
-// Method represents a method of an api.
+/// Method represents a method of an api.
 @interface GPBMethod : GPBMessage
 
-// The simple name of this method.
+/// The simple name of this method.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
 
-// A URL of the input message type.
+/// A URL of the input message type.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *requestTypeURL;
 
-// If true, the request is streamed.
+/// If true, the request is streamed.
 @property(nonatomic, readwrite) BOOL requestStreaming;
 
-// The URL of the output message type.
+/// The URL of the output message type.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *responseTypeURL;
 
-// If true, the response is streamed.
+/// If true, the response is streamed.
 @property(nonatomic, readwrite) BOOL responseStreaming;
 
-// Any metadata attached to the method.
+/// Any metadata attached to the method.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
-// The source syntax of this method.
+/// The source syntax of this method.
 @property(nonatomic, readwrite) enum GPBSyntax syntax;
 
 @end
 
+/// Fetches the raw value of a @c GPBMethod's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
 int32_t GPBMethod_Syntax_RawValue(GPBMethod *message);
+/// Sets the raw value of an @c GPBMethod's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
 void SetGPBMethod_Syntax_RawValue(GPBMethod *message, int32_t value);
 
 #pragma mark - GPBMixin
@@ -145,90 +162,90 @@
   GPBMixin_FieldNumber_Root = 2,
 };
 
-// Declares an API to be included in this API. The including API must
-// redeclare all the methods from the included API, but documentation
-// and options are inherited as follows:
-//
-// - If after comment and whitespace stripping, the documentation
-//   string of the redeclared method is empty, it will be inherited
-//   from the original method.
-//
-// - Each annotation belonging to the service config (http,
-//   visibility) which is not set in the redeclared method will be
-//   inherited.
-//
-// - If an http annotation is inherited, the path pattern will be
-//   modified as follows. Any version prefix will be replaced by the
-//   version of the including API plus the [root][] path if specified.
-//
-// Example of a simple mixin:
-//
-//     package google.acl.v1;
-//     service AccessControl {
-//       // Get the underlying ACL object.
-//       rpc GetAcl(GetAclRequest) returns (Acl) {
-//         option (google.api.http).get = "/v1/{resource=**}:getAcl";
-//       }
-//     }
-//
-//     package google.storage.v2;
-//     service Storage {
-//       rpc GetAcl(GetAclRequest) returns (Acl);
-//
-//       // Get a data record.
-//       rpc GetData(GetDataRequest) returns (Data) {
-//         option (google.api.http).get = "/v2/{resource=**}";
-//       }
-//     }
-//
-// Example of a mixin configuration:
-//
-//     apis:
-//     - name: google.storage.v2.Storage
-//       mixins:
-//       - name: google.acl.v1.AccessControl
-//
-// The mixin construct implies that all methods in `AccessControl` are
-// also declared with same name and request/response types in
-// `Storage`. A documentation generator or annotation processor will
-// see the effective `Storage.GetAcl` method after inherting
-// documentation and annotations as follows:
-//
-//     service Storage {
-//       // Get the underlying ACL object.
-//       rpc GetAcl(GetAclRequest) returns (Acl) {
-//         option (google.api.http).get = "/v2/{resource=**}:getAcl";
-//       }
-//       ...
-//     }
-//
-// Note how the version in the path pattern changed from `v1` to `v2`.
-//
-// If the `root` field in the mixin is specified, it should be a
-// relative path under which inherited HTTP paths are placed. Example:
-//
-//     apis:
-//     - name: google.storage.v2.Storage
-//       mixins:
-//       - name: google.acl.v1.AccessControl
-//         root: acls
-//
-// This implies the following inherited HTTP annotation:
-//
-//     service Storage {
-//       // Get the underlying ACL object.
-//       rpc GetAcl(GetAclRequest) returns (Acl) {
-//         option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
-//       }
-//       ...
-//     }
+/// Declares an API to be included in this API. The including API must
+/// redeclare all the methods from the included API, but documentation
+/// and options are inherited as follows:
+///
+/// - If after comment and whitespace stripping, the documentation
+///   string of the redeclared method is empty, it will be inherited
+///   from the original method.
+///
+/// - Each annotation belonging to the service config (http,
+///   visibility) which is not set in the redeclared method will be
+///   inherited.
+///
+/// - If an http annotation is inherited, the path pattern will be
+///   modified as follows. Any version prefix will be replaced by the
+///   version of the including API plus the [root][] path if specified.
+///
+/// Example of a simple mixin:
+///
+///     package google.acl.v1;
+///     service AccessControl {
+///       // Get the underlying ACL object.
+///       rpc GetAcl(GetAclRequest) returns (Acl) {
+///         option (google.api.http).get = "/v1/{resource=**}:getAcl";
+///       }
+///     }
+///
+///     package google.storage.v2;
+///     service Storage {
+///       rpc GetAcl(GetAclRequest) returns (Acl);
+///
+///       // Get a data record.
+///       rpc GetData(GetDataRequest) returns (Data) {
+///         option (google.api.http).get = "/v2/{resource=**}";
+///       }
+///     }
+///
+/// Example of a mixin configuration:
+///
+///     apis:
+///     - name: google.storage.v2.Storage
+///       mixins:
+///       - name: google.acl.v1.AccessControl
+///
+/// The mixin construct implies that all methods in `AccessControl` are
+/// also declared with same name and request/response types in
+/// `Storage`. A documentation generator or annotation processor will
+/// see the effective `Storage.GetAcl` method after inherting
+/// documentation and annotations as follows:
+///
+///     service Storage {
+///       // Get the underlying ACL object.
+///       rpc GetAcl(GetAclRequest) returns (Acl) {
+///         option (google.api.http).get = "/v2/{resource=**}:getAcl";
+///       }
+///       ...
+///     }
+///
+/// Note how the version in the path pattern changed from `v1` to `v2`.
+///
+/// If the `root` field in the mixin is specified, it should be a
+/// relative path under which inherited HTTP paths are placed. Example:
+///
+///     apis:
+///     - name: google.storage.v2.Storage
+///       mixins:
+///       - name: google.acl.v1.AccessControl
+///         root: acls
+///
+/// This implies the following inherited HTTP annotation:
+///
+///     service Storage {
+///       // Get the underlying ACL object.
+///       rpc GetAcl(GetAclRequest) returns (Acl) {
+///         option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
+///       }
+///       ...
+///     }
 @interface GPBMixin : GPBMessage
 
-// The fully qualified name of the API which is included.
+/// The fully qualified name of the API which is included.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
 
-// If non-empty specifies a path under which inherited HTTP paths
-// are rooted.
+/// If non-empty specifies a path under which inherited HTTP paths
+/// are rooted.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *root;
 
 @end
diff --git a/objectivec/google/protobuf/Descriptor.pbobjc.h b/objectivec/google/protobuf/Descriptor.pbobjc.h
index 2ab2024..109711c 100644
--- a/objectivec/google/protobuf/Descriptor.pbobjc.h
+++ b/objectivec/google/protobuf/Descriptor.pbobjc.h
@@ -39,85 +39,91 @@
 #pragma mark - Enum GPBFieldDescriptorProto_Type
 
 typedef GPB_ENUM(GPBFieldDescriptorProto_Type) {
-  // 0 is reserved for errors.
-  // Order is weird for historical reasons.
+  /// 0 is reserved for errors.
+  /// Order is weird for historical reasons.
   GPBFieldDescriptorProto_Type_TypeDouble = 1,
   GPBFieldDescriptorProto_Type_TypeFloat = 2,
 
-  // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
-  // negative values are likely.
+  /// Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
+  /// negative values are likely.
   GPBFieldDescriptorProto_Type_TypeInt64 = 3,
   GPBFieldDescriptorProto_Type_TypeUint64 = 4,
 
-  // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
-  // negative values are likely.
+  /// Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
+  /// negative values are likely.
   GPBFieldDescriptorProto_Type_TypeInt32 = 5,
   GPBFieldDescriptorProto_Type_TypeFixed64 = 6,
   GPBFieldDescriptorProto_Type_TypeFixed32 = 7,
   GPBFieldDescriptorProto_Type_TypeBool = 8,
   GPBFieldDescriptorProto_Type_TypeString = 9,
 
-  // Tag-delimited aggregate.
+  /// Tag-delimited aggregate.
   GPBFieldDescriptorProto_Type_TypeGroup = 10,
 
-  // Length-delimited aggregate.
+  /// Length-delimited aggregate.
   GPBFieldDescriptorProto_Type_TypeMessage = 11,
 
-  // New in version 2.
+  /// New in version 2.
   GPBFieldDescriptorProto_Type_TypeBytes = 12,
   GPBFieldDescriptorProto_Type_TypeUint32 = 13,
   GPBFieldDescriptorProto_Type_TypeEnum = 14,
   GPBFieldDescriptorProto_Type_TypeSfixed32 = 15,
   GPBFieldDescriptorProto_Type_TypeSfixed64 = 16,
 
-  // Uses ZigZag encoding.
+  /// Uses ZigZag encoding.
   GPBFieldDescriptorProto_Type_TypeSint32 = 17,
 
-  // Uses ZigZag encoding.
+  /// Uses ZigZag encoding.
   GPBFieldDescriptorProto_Type_TypeSint64 = 18,
 };
 
 GPBEnumDescriptor *GPBFieldDescriptorProto_Type_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBFieldDescriptorProto_Type_IsValidValue(int32_t value);
 
 #pragma mark - Enum GPBFieldDescriptorProto_Label
 
 typedef GPB_ENUM(GPBFieldDescriptorProto_Label) {
-  // 0 is reserved for errors
+  /// 0 is reserved for errors
   GPBFieldDescriptorProto_Label_LabelOptional = 1,
   GPBFieldDescriptorProto_Label_LabelRequired = 2,
 
-  // TODO(sanjay): Should we add LABEL_MAP?
+  /// TODO(sanjay): Should we add LABEL_MAP?
   GPBFieldDescriptorProto_Label_LabelRepeated = 3,
 };
 
 GPBEnumDescriptor *GPBFieldDescriptorProto_Label_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBFieldDescriptorProto_Label_IsValidValue(int32_t value);
 
 #pragma mark - Enum GPBFileOptions_OptimizeMode
 
-// Generated classes can be optimized for speed or code size.
+/// Generated classes can be optimized for speed or code size.
 typedef GPB_ENUM(GPBFileOptions_OptimizeMode) {
-  // Generate complete code for parsing, serialization,
+  /// Generate complete code for parsing, serialization,
   GPBFileOptions_OptimizeMode_Speed = 1,
 
-  // etc.
+  /// etc.
   GPBFileOptions_OptimizeMode_CodeSize = 2,
 
-  // Generate code using MessageLite and the lite runtime.
+  /// Generate code using MessageLite and the lite runtime.
   GPBFileOptions_OptimizeMode_LiteRuntime = 3,
 };
 
 GPBEnumDescriptor *GPBFileOptions_OptimizeMode_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBFileOptions_OptimizeMode_IsValidValue(int32_t value);
 
 #pragma mark - Enum GPBFieldOptions_CType
 
 typedef GPB_ENUM(GPBFieldOptions_CType) {
-  // Default mode.
+  /// Default mode.
   GPBFieldOptions_CType_String = 0,
   GPBFieldOptions_CType_Cord = 1,
   GPBFieldOptions_CType_StringPiece = 2,
@@ -125,34 +131,40 @@
 
 GPBEnumDescriptor *GPBFieldOptions_CType_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBFieldOptions_CType_IsValidValue(int32_t value);
 
 #pragma mark - Enum GPBFieldOptions_JSType
 
 typedef GPB_ENUM(GPBFieldOptions_JSType) {
-  // Use the default type.
+  /// Use the default type.
   GPBFieldOptions_JSType_JsNormal = 0,
 
-  // Use JavaScript strings.
+  /// Use JavaScript strings.
   GPBFieldOptions_JSType_JsString = 1,
 
-  // Use JavaScript numbers.
+  /// Use JavaScript numbers.
   GPBFieldOptions_JSType_JsNumber = 2,
 };
 
 GPBEnumDescriptor *GPBFieldOptions_JSType_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBFieldOptions_JSType_IsValidValue(int32_t value);
 
 #pragma mark - GPBDescriptorRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBDescriptorRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBFileDescriptorSet
@@ -161,11 +173,12 @@
   GPBFileDescriptorSet_FieldNumber_FileArray = 1,
 };
 
-// The protocol compiler can output a FileDescriptorSet containing the .proto
-// files it parses.
+/// The protocol compiler can output a FileDescriptorSet containing the .proto
+/// files it parses.
 @interface GPBFileDescriptorSet : GPBMessage
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBFileDescriptorProto*> *fileArray;
+/// The number of items in @c fileArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger fileArray_Count;
 
 @end
@@ -187,57 +200,69 @@
   GPBFileDescriptorProto_FieldNumber_Syntax = 12,
 };
 
-// Describes a complete .proto file.
+/// Describes a complete .proto file.
 @interface GPBFileDescriptorProto : GPBMessage
 
-// file name, relative to root of source tree
-@property(nonatomic, readwrite) BOOL hasName;
+/// file name, relative to root of source tree
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+/// Test to see if @c name has been set.
+@property(nonatomic, readwrite) BOOL hasName;
 
-// e.g. "foo", "foo.bar", etc.
-@property(nonatomic, readwrite) BOOL hasPackage;
+/// e.g. "foo", "foo.bar", etc.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *package;
+/// Test to see if @c package has been set.
+@property(nonatomic, readwrite) BOOL hasPackage;
 
-// Names of files imported by this file.
+/// Names of files imported by this file.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *dependencyArray;
+/// The number of items in @c dependencyArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger dependencyArray_Count;
 
-// Indexes of the public imported files in the dependency list above.
+/// Indexes of the public imported files in the dependency list above.
 @property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *publicDependencyArray;
+/// The number of items in @c publicDependencyArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger publicDependencyArray_Count;
 
-// Indexes of the weak imported files in the dependency list.
-// For Google-internal migration only. Do not use.
+/// Indexes of the weak imported files in the dependency list.
+/// For Google-internal migration only. Do not use.
 @property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *weakDependencyArray;
+/// The number of items in @c weakDependencyArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger weakDependencyArray_Count;
 
-// All top-level definitions in this file.
+/// All top-level definitions in this file.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBDescriptorProto*> *messageTypeArray;
+/// The number of items in @c messageTypeArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger messageTypeArray_Count;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBEnumDescriptorProto*> *enumTypeArray;
+/// The number of items in @c enumTypeArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger enumTypeArray_Count;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBServiceDescriptorProto*> *serviceArray;
+/// The number of items in @c serviceArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger serviceArray_Count;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBFieldDescriptorProto*> *extensionArray;
+/// The number of items in @c extensionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger extensionArray_Count;
 
-@property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong, null_resettable) GPBFileOptions *options;
+/// Test to see if @c options has been set.
+@property(nonatomic, readwrite) BOOL hasOptions;
 
-// This field contains optional information about the original source code.
-// You may safely remove this entire field without harming runtime
-// functionality of the descriptors -- the information is needed only by
-// development tools.
-@property(nonatomic, readwrite) BOOL hasSourceCodeInfo;
+/// This field contains optional information about the original source code.
+/// You may safely remove this entire field without harming runtime
+/// functionality of the descriptors -- the information is needed only by
+/// development tools.
 @property(nonatomic, readwrite, strong, null_resettable) GPBSourceCodeInfo *sourceCodeInfo;
+/// Test to see if @c sourceCodeInfo has been set.
+@property(nonatomic, readwrite) BOOL hasSourceCodeInfo;
 
-// The syntax of the proto file.
-// The supported values are "proto2" and "proto3".
-@property(nonatomic, readwrite) BOOL hasSyntax;
+/// The syntax of the proto file.
+/// The supported values are "proto2" and "proto3".
 @property(nonatomic, readwrite, copy, null_resettable) NSString *syntax;
+/// Test to see if @c syntax has been set.
+@property(nonatomic, readwrite) BOOL hasSyntax;
 
 @end
 
@@ -256,39 +281,49 @@
   GPBDescriptorProto_FieldNumber_ReservedNameArray = 10,
 };
 
-// Describes a message type.
+/// Describes a message type.
 @interface GPBDescriptorProto : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasName;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+/// Test to see if @c name has been set.
+@property(nonatomic, readwrite) BOOL hasName;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBFieldDescriptorProto*> *fieldArray;
+/// The number of items in @c fieldArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger fieldArray_Count;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBFieldDescriptorProto*> *extensionArray;
+/// The number of items in @c extensionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger extensionArray_Count;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBDescriptorProto*> *nestedTypeArray;
+/// The number of items in @c nestedTypeArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger nestedTypeArray_Count;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBEnumDescriptorProto*> *enumTypeArray;
+/// The number of items in @c enumTypeArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger enumTypeArray_Count;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBDescriptorProto_ExtensionRange*> *extensionRangeArray;
+/// The number of items in @c extensionRangeArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger extensionRangeArray_Count;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOneofDescriptorProto*> *oneofDeclArray;
+/// The number of items in @c oneofDeclArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger oneofDeclArray_Count;
 
-@property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong, null_resettable) GPBMessageOptions *options;
+/// Test to see if @c options has been set.
+@property(nonatomic, readwrite) BOOL hasOptions;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBDescriptorProto_ReservedRange*> *reservedRangeArray;
+/// The number of items in @c reservedRangeArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger reservedRangeArray_Count;
 
-// Reserved field names, which may not be used by fields in the same message.
-// A given name may only be reserved once.
+/// Reserved field names, which may not be used by fields in the same message.
+/// A given name may only be reserved once.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *reservedNameArray;
+/// The number of items in @c reservedNameArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger reservedNameArray_Count;
 
 @end
@@ -302,12 +337,12 @@
 
 @interface GPBDescriptorProto_ExtensionRange : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasStart;
 @property(nonatomic, readwrite) int32_t start;
 
-@property(nonatomic, readwrite) BOOL hasEnd;
+@property(nonatomic, readwrite) BOOL hasStart;
 @property(nonatomic, readwrite) int32_t end;
 
+@property(nonatomic, readwrite) BOOL hasEnd;
 @end
 
 #pragma mark - GPBDescriptorProto_ReservedRange
@@ -317,19 +352,19 @@
   GPBDescriptorProto_ReservedRange_FieldNumber_End = 2,
 };
 
-// Range of reserved tag numbers. Reserved tag numbers may not be used by
-// fields or extension ranges in the same message. Reserved ranges may
-// not overlap.
+/// Range of reserved tag numbers. Reserved tag numbers may not be used by
+/// fields or extension ranges in the same message. Reserved ranges may
+/// not overlap.
 @interface GPBDescriptorProto_ReservedRange : GPBMessage
 
-// Inclusive.
-@property(nonatomic, readwrite) BOOL hasStart;
+/// Inclusive.
 @property(nonatomic, readwrite) int32_t start;
 
-// Exclusive.
-@property(nonatomic, readwrite) BOOL hasEnd;
+@property(nonatomic, readwrite) BOOL hasStart;
+/// Exclusive.
 @property(nonatomic, readwrite) int32_t end;
 
+@property(nonatomic, readwrite) BOOL hasEnd;
 @end
 
 #pragma mark - GPBFieldDescriptorProto
@@ -347,58 +382,64 @@
   GPBFieldDescriptorProto_FieldNumber_JsonName = 10,
 };
 
-// Describes a field within a message.
+/// Describes a field within a message.
 @interface GPBFieldDescriptorProto : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasName;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+/// Test to see if @c name has been set.
+@property(nonatomic, readwrite) BOOL hasName;
 
-@property(nonatomic, readwrite) BOOL hasNumber;
 @property(nonatomic, readwrite) int32_t number;
 
-@property(nonatomic, readwrite) BOOL hasLabel;
+@property(nonatomic, readwrite) BOOL hasNumber;
 @property(nonatomic, readwrite) GPBFieldDescriptorProto_Label label;
 
-// If type_name is set, this need not be set.  If both this and type_name
-// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
-@property(nonatomic, readwrite) BOOL hasType;
+@property(nonatomic, readwrite) BOOL hasLabel;
+/// If type_name is set, this need not be set.  If both this and type_name
+/// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
 @property(nonatomic, readwrite) GPBFieldDescriptorProto_Type type;
 
-// For message and enum types, this is the name of the type.  If the name
-// starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
-// rules are used to find the type (i.e. first the nested types within this
-// message are searched, then within the parent, on up to the root
-// namespace).
-@property(nonatomic, readwrite) BOOL hasTypeName;
+@property(nonatomic, readwrite) BOOL hasType;
+/// For message and enum types, this is the name of the type.  If the name
+/// starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
+/// rules are used to find the type (i.e. first the nested types within this
+/// message are searched, then within the parent, on up to the root
+/// namespace).
 @property(nonatomic, readwrite, copy, null_resettable) NSString *typeName;
+/// Test to see if @c typeName has been set.
+@property(nonatomic, readwrite) BOOL hasTypeName;
 
-// For extensions, this is the name of the type being extended.  It is
-// resolved in the same manner as type_name.
-@property(nonatomic, readwrite) BOOL hasExtendee;
+/// For extensions, this is the name of the type being extended.  It is
+/// resolved in the same manner as type_name.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *extendee;
+/// Test to see if @c extendee has been set.
+@property(nonatomic, readwrite) BOOL hasExtendee;
 
-// For numeric types, contains the original text representation of the value.
-// For booleans, "true" or "false".
-// For strings, contains the default text contents (not escaped in any way).
-// For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
-// TODO(kenton):  Base-64 encode?
-@property(nonatomic, readwrite) BOOL hasDefaultValue;
+/// For numeric types, contains the original text representation of the value.
+/// For booleans, "true" or "false".
+/// For strings, contains the default text contents (not escaped in any way).
+/// For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
+/// TODO(kenton):  Base-64 encode?
 @property(nonatomic, readwrite, copy, null_resettable) NSString *defaultValue;
+/// Test to see if @c defaultValue has been set.
+@property(nonatomic, readwrite) BOOL hasDefaultValue;
 
-// If set, gives the index of a oneof in the containing type's oneof_decl
-// list.  This field is a member of that oneof.
-@property(nonatomic, readwrite) BOOL hasOneofIndex;
+/// If set, gives the index of a oneof in the containing type's oneof_decl
+/// list.  This field is a member of that oneof.
 @property(nonatomic, readwrite) int32_t oneofIndex;
 
-// JSON name of this field. The value is set by protocol compiler. If the
-// user has set a "json_name" option on this field, that option's value
-// will be used. Otherwise, it's deduced from the field's name by converting
-// it to camelCase.
-@property(nonatomic, readwrite) BOOL hasJsonName;
+@property(nonatomic, readwrite) BOOL hasOneofIndex;
+/// JSON name of this field. The value is set by protocol compiler. If the
+/// user has set a "json_name" option on this field, that option's value
+/// will be used. Otherwise, it's deduced from the field's name by converting
+/// it to camelCase.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *jsonName;
+/// Test to see if @c jsonName has been set.
+@property(nonatomic, readwrite) BOOL hasJsonName;
 
-@property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong, null_resettable) GPBFieldOptions *options;
+/// Test to see if @c options has been set.
+@property(nonatomic, readwrite) BOOL hasOptions;
 
 @end
 
@@ -408,11 +449,12 @@
   GPBOneofDescriptorProto_FieldNumber_Name = 1,
 };
 
-// Describes a oneof.
+/// Describes a oneof.
 @interface GPBOneofDescriptorProto : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasName;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+/// Test to see if @c name has been set.
+@property(nonatomic, readwrite) BOOL hasName;
 
 @end
 
@@ -424,17 +466,20 @@
   GPBEnumDescriptorProto_FieldNumber_Options = 3,
 };
 
-// Describes an enum type.
+/// Describes an enum type.
 @interface GPBEnumDescriptorProto : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasName;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+/// Test to see if @c name has been set.
+@property(nonatomic, readwrite) BOOL hasName;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBEnumValueDescriptorProto*> *valueArray;
+/// The number of items in @c valueArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger valueArray_Count;
 
-@property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong, null_resettable) GPBEnumOptions *options;
+/// Test to see if @c options has been set.
+@property(nonatomic, readwrite) BOOL hasOptions;
 
 @end
 
@@ -446,17 +491,19 @@
   GPBEnumValueDescriptorProto_FieldNumber_Options = 3,
 };
 
-// Describes a value within an enum.
+/// Describes a value within an enum.
 @interface GPBEnumValueDescriptorProto : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasName;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+/// Test to see if @c name has been set.
+@property(nonatomic, readwrite) BOOL hasName;
 
-@property(nonatomic, readwrite) BOOL hasNumber;
 @property(nonatomic, readwrite) int32_t number;
 
-@property(nonatomic, readwrite) BOOL hasOptions;
+@property(nonatomic, readwrite) BOOL hasNumber;
 @property(nonatomic, readwrite, strong, null_resettable) GPBEnumValueOptions *options;
+/// Test to see if @c options has been set.
+@property(nonatomic, readwrite) BOOL hasOptions;
 
 @end
 
@@ -468,17 +515,20 @@
   GPBServiceDescriptorProto_FieldNumber_Options = 3,
 };
 
-// Describes a service.
+/// Describes a service.
 @interface GPBServiceDescriptorProto : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasName;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+/// Test to see if @c name has been set.
+@property(nonatomic, readwrite) BOOL hasName;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMethodDescriptorProto*> *methodArray;
+/// The number of items in @c methodArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger methodArray_Count;
 
-@property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong, null_resettable) GPBServiceOptions *options;
+/// Test to see if @c options has been set.
+@property(nonatomic, readwrite) BOOL hasOptions;
 
 @end
 
@@ -493,31 +543,35 @@
   GPBMethodDescriptorProto_FieldNumber_ServerStreaming = 6,
 };
 
-// Describes a method of a service.
+/// Describes a method of a service.
 @interface GPBMethodDescriptorProto : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasName;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+/// Test to see if @c name has been set.
+@property(nonatomic, readwrite) BOOL hasName;
 
-// Input and output type names.  These are resolved in the same way as
-// FieldDescriptorProto.type_name, but must refer to a message type.
-@property(nonatomic, readwrite) BOOL hasInputType;
+/// Input and output type names.  These are resolved in the same way as
+/// FieldDescriptorProto.type_name, but must refer to a message type.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *inputType;
+/// Test to see if @c inputType has been set.
+@property(nonatomic, readwrite) BOOL hasInputType;
 
-@property(nonatomic, readwrite) BOOL hasOutputType;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *outputType;
+/// Test to see if @c outputType has been set.
+@property(nonatomic, readwrite) BOOL hasOutputType;
 
-@property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong, null_resettable) GPBMethodOptions *options;
+/// Test to see if @c options has been set.
+@property(nonatomic, readwrite) BOOL hasOptions;
 
-// Identifies if client streams multiple client messages
-@property(nonatomic, readwrite) BOOL hasClientStreaming;
+/// Identifies if client streams multiple client messages
 @property(nonatomic, readwrite) BOOL clientStreaming;
 
-// Identifies if server streams multiple server messages
-@property(nonatomic, readwrite) BOOL hasServerStreaming;
+@property(nonatomic, readwrite) BOOL hasClientStreaming;
+/// Identifies if server streams multiple server messages
 @property(nonatomic, readwrite) BOOL serverStreaming;
 
+@property(nonatomic, readwrite) BOOL hasServerStreaming;
 @end
 
 #pragma mark - GPBFileOptions
@@ -543,112 +597,118 @@
 
 @interface GPBFileOptions : GPBMessage
 
-// Sets the Java package where classes generated from this .proto will be
-// placed.  By default, the proto package is used, but this is often
-// inappropriate because proto packages do not normally start with backwards
-// domain names.
-@property(nonatomic, readwrite) BOOL hasJavaPackage;
+/// Sets the Java package where classes generated from this .proto will be
+/// placed.  By default, the proto package is used, but this is often
+/// inappropriate because proto packages do not normally start with backwards
+/// domain names.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *javaPackage;
+/// Test to see if @c javaPackage has been set.
+@property(nonatomic, readwrite) BOOL hasJavaPackage;
 
-// If set, all the classes from the .proto file are wrapped in a single
-// outer class with the given name.  This applies to both Proto1
-// (equivalent to the old "--one_java_file" option) and Proto2 (where
-// a .proto always translates to a single class, but you may want to
-// explicitly choose the class name).
-@property(nonatomic, readwrite) BOOL hasJavaOuterClassname;
+/// If set, all the classes from the .proto file are wrapped in a single
+/// outer class with the given name.  This applies to both Proto1
+/// (equivalent to the old "--one_java_file" option) and Proto2 (where
+/// a .proto always translates to a single class, but you may want to
+/// explicitly choose the class name).
 @property(nonatomic, readwrite, copy, null_resettable) NSString *javaOuterClassname;
+/// Test to see if @c javaOuterClassname has been set.
+@property(nonatomic, readwrite) BOOL hasJavaOuterClassname;
 
-// If set true, then the Java code generator will generate a separate .java
-// file for each top-level message, enum, and service defined in the .proto
-// file.  Thus, these types will *not* be nested inside the outer class
-// named by java_outer_classname.  However, the outer class will still be
-// generated to contain the file's getDescriptor() method as well as any
-// top-level extensions defined in the file.
-@property(nonatomic, readwrite) BOOL hasJavaMultipleFiles;
+/// If set true, then the Java code generator will generate a separate .java
+/// file for each top-level message, enum, and service defined in the .proto
+/// file.  Thus, these types will *not* be nested inside the outer class
+/// named by java_outer_classname.  However, the outer class will still be
+/// generated to contain the file's getDescriptor() method as well as any
+/// top-level extensions defined in the file.
 @property(nonatomic, readwrite) BOOL javaMultipleFiles;
 
-// If set true, then the Java code generator will generate equals() and
-// hashCode() methods for all messages defined in the .proto file.
-// This increases generated code size, potentially substantially for large
-// protos, which may harm a memory-constrained application.
-// - In the full runtime this is a speed optimization, as the
-// AbstractMessage base class includes reflection-based implementations of
-// these methods.
-// - In the lite runtime, setting this option changes the semantics of
-// equals() and hashCode() to more closely match those of the full runtime;
-// the generated methods compute their results based on field values rather
-// than object identity. (Implementations should not assume that hashcodes
-// will be consistent across runtimes or versions of the protocol compiler.)
-@property(nonatomic, readwrite) BOOL hasJavaGenerateEqualsAndHash;
+@property(nonatomic, readwrite) BOOL hasJavaMultipleFiles;
+/// If set true, then the Java code generator will generate equals() and
+/// hashCode() methods for all messages defined in the .proto file.
+/// This increases generated code size, potentially substantially for large
+/// protos, which may harm a memory-constrained application.
+/// - In the full runtime this is a speed optimization, as the
+/// AbstractMessage base class includes reflection-based implementations of
+/// these methods.
+/// - In the lite runtime, setting this option changes the semantics of
+/// equals() and hashCode() to more closely match those of the full runtime;
+/// the generated methods compute their results based on field values rather
+/// than object identity. (Implementations should not assume that hashcodes
+/// will be consistent across runtimes or versions of the protocol compiler.)
 @property(nonatomic, readwrite) BOOL javaGenerateEqualsAndHash;
 
-// If set true, then the Java2 code generator will generate code that
-// throws an exception whenever an attempt is made to assign a non-UTF-8
-// byte sequence to a string field.
-// Message reflection will do the same.
-// However, an extension field still accepts non-UTF-8 byte sequences.
-// This option has no effect on when used with the lite runtime.
-@property(nonatomic, readwrite) BOOL hasJavaStringCheckUtf8;
+@property(nonatomic, readwrite) BOOL hasJavaGenerateEqualsAndHash;
+/// If set true, then the Java2 code generator will generate code that
+/// throws an exception whenever an attempt is made to assign a non-UTF-8
+/// byte sequence to a string field.
+/// Message reflection will do the same.
+/// However, an extension field still accepts non-UTF-8 byte sequences.
+/// This option has no effect on when used with the lite runtime.
 @property(nonatomic, readwrite) BOOL javaStringCheckUtf8;
 
-@property(nonatomic, readwrite) BOOL hasOptimizeFor;
+@property(nonatomic, readwrite) BOOL hasJavaStringCheckUtf8;
 @property(nonatomic, readwrite) GPBFileOptions_OptimizeMode optimizeFor;
 
-// Sets the Go package where structs generated from this .proto will be
-// placed. If omitted, the Go package will be derived from the following:
-//   - The basename of the package import path, if provided.
-//   - Otherwise, the package statement in the .proto file, if present.
-//   - Otherwise, the basename of the .proto file, without extension.
-@property(nonatomic, readwrite) BOOL hasGoPackage;
+@property(nonatomic, readwrite) BOOL hasOptimizeFor;
+/// Sets the Go package where structs generated from this .proto will be
+/// placed. If omitted, the Go package will be derived from the following:
+///   - The basename of the package import path, if provided.
+///   - Otherwise, the package statement in the .proto file, if present.
+///   - Otherwise, the basename of the .proto file, without extension.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *goPackage;
+/// Test to see if @c goPackage has been set.
+@property(nonatomic, readwrite) BOOL hasGoPackage;
 
-// Should generic services be generated in each language?  "Generic" services
-// are not specific to any particular RPC system.  They are generated by the
-// main code generators in each language (without additional plugins).
-// Generic services were the only kind of service generation supported by
-// early versions of google.protobuf.
-//
-// Generic services are now considered deprecated in favor of using plugins
-// that generate code specific to your particular RPC system.  Therefore,
-// these default to false.  Old code which depends on generic services should
-// explicitly set them to true.
-@property(nonatomic, readwrite) BOOL hasCcGenericServices;
+/// Should generic services be generated in each language?  "Generic" services
+/// are not specific to any particular RPC system.  They are generated by the
+/// main code generators in each language (without additional plugins).
+/// Generic services were the only kind of service generation supported by
+/// early versions of google.protobuf.
+///
+/// Generic services are now considered deprecated in favor of using plugins
+/// that generate code specific to your particular RPC system.  Therefore,
+/// these default to false.  Old code which depends on generic services should
+/// explicitly set them to true.
 @property(nonatomic, readwrite) BOOL ccGenericServices;
 
-@property(nonatomic, readwrite) BOOL hasJavaGenericServices;
+@property(nonatomic, readwrite) BOOL hasCcGenericServices;
 @property(nonatomic, readwrite) BOOL javaGenericServices;
 
-@property(nonatomic, readwrite) BOOL hasPyGenericServices;
+@property(nonatomic, readwrite) BOOL hasJavaGenericServices;
 @property(nonatomic, readwrite) BOOL pyGenericServices;
 
-// Is this file deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for everything in the file, or it will be completely ignored; in the very
-// least, this is a formalization for deprecating files.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
+@property(nonatomic, readwrite) BOOL hasPyGenericServices;
+/// Is this file deprecated?
+/// Depending on the target platform, this can emit Deprecated annotations
+/// for everything in the file, or it will be completely ignored; in the very
+/// least, this is a formalization for deprecating files.
 @property(nonatomic, readwrite) BOOL deprecated;
 
-// Enables the use of arenas for the proto messages in this file. This applies
-// only to generated classes for C++.
-@property(nonatomic, readwrite) BOOL hasCcEnableArenas;
+@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// Enables the use of arenas for the proto messages in this file. This applies
+/// only to generated classes for C++.
 @property(nonatomic, readwrite) BOOL ccEnableArenas;
 
-// Sets the objective c class prefix which is prepended to all objective c
-// generated classes from this .proto. There is no default.
-@property(nonatomic, readwrite) BOOL hasObjcClassPrefix;
+@property(nonatomic, readwrite) BOOL hasCcEnableArenas;
+/// Sets the objective c class prefix which is prepended to all objective c
+/// generated classes from this .proto. There is no default.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *objcClassPrefix;
+/// Test to see if @c objcClassPrefix has been set.
+@property(nonatomic, readwrite) BOOL hasObjcClassPrefix;
 
-// Namespace for generated classes; defaults to the package.
-@property(nonatomic, readwrite) BOOL hasCsharpNamespace;
+/// Namespace for generated classes; defaults to the package.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *csharpNamespace;
+/// Test to see if @c csharpNamespace has been set.
+@property(nonatomic, readwrite) BOOL hasCsharpNamespace;
 
-// Whether the nano proto compiler should generate in the deprecated non-nano
-// suffixed package.
-@property(nonatomic, readwrite) BOOL hasJavananoUseDeprecatedPackage;
+/// Whether the nano proto compiler should generate in the deprecated non-nano
+/// suffixed package.
 @property(nonatomic, readwrite) BOOL javananoUseDeprecatedPackage;
 
-// The parser stores options it doesn't recognize here. See above.
+@property(nonatomic, readwrite) BOOL hasJavananoUseDeprecatedPackage;
+/// The parser stores options it doesn't recognize here. See above.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBUninterpretedOption*> *uninterpretedOptionArray;
+/// The number of items in @c uninterpretedOptionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
@@ -665,66 +725,67 @@
 
 @interface GPBMessageOptions : GPBMessage
 
-// Set true to use the old proto1 MessageSet wire format for extensions.
-// This is provided for backwards-compatibility with the MessageSet wire
-// format.  You should not use this for any other reason:  It's less
-// efficient, has fewer features, and is more complicated.
-//
-// The message must be defined exactly as follows:
-//   message Foo {
-//     option message_set_wire_format = true;
-//     extensions 4 to max;
-//   }
-// Note that the message cannot have any defined fields; MessageSets only
-// have extensions.
-//
-// All extensions of your type must be singular messages; e.g. they cannot
-// be int32s, enums, or repeated messages.
-//
-// Because this is an option, the above two restrictions are not enforced by
-// the protocol compiler.
-@property(nonatomic, readwrite) BOOL hasMessageSetWireFormat;
+/// Set true to use the old proto1 MessageSet wire format for extensions.
+/// This is provided for backwards-compatibility with the MessageSet wire
+/// format.  You should not use this for any other reason:  It's less
+/// efficient, has fewer features, and is more complicated.
+///
+/// The message must be defined exactly as follows:
+///   message Foo {
+///     option message_set_wire_format = true;
+///     extensions 4 to max;
+///   }
+/// Note that the message cannot have any defined fields; MessageSets only
+/// have extensions.
+///
+/// All extensions of your type must be singular messages; e.g. they cannot
+/// be int32s, enums, or repeated messages.
+///
+/// Because this is an option, the above two restrictions are not enforced by
+/// the protocol compiler.
 @property(nonatomic, readwrite) BOOL messageSetWireFormat;
 
-// Disables the generation of the standard "descriptor()" accessor, which can
-// conflict with a field of the same name.  This is meant to make migration
-// from proto1 easier; new code should avoid fields named "descriptor".
-@property(nonatomic, readwrite) BOOL hasNoStandardDescriptorAccessor;
+@property(nonatomic, readwrite) BOOL hasMessageSetWireFormat;
+/// Disables the generation of the standard "descriptor()" accessor, which can
+/// conflict with a field of the same name.  This is meant to make migration
+/// from proto1 easier; new code should avoid fields named "descriptor".
 @property(nonatomic, readwrite) BOOL noStandardDescriptorAccessor;
 
-// Is this message deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the message, or it will be completely ignored; in the very least,
-// this is a formalization for deprecating messages.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
+@property(nonatomic, readwrite) BOOL hasNoStandardDescriptorAccessor;
+/// Is this message deprecated?
+/// Depending on the target platform, this can emit Deprecated annotations
+/// for the message, or it will be completely ignored; in the very least,
+/// this is a formalization for deprecating messages.
 @property(nonatomic, readwrite) BOOL deprecated;
 
-// Whether the message is an automatically generated map entry type for the
-// maps field.
-//
-// For maps fields:
-//     map<KeyType, ValueType> map_field = 1;
-// The parsed descriptor looks like:
-//     message MapFieldEntry {
-//         option map_entry = true;
-//         optional KeyType key = 1;
-//         optional ValueType value = 2;
-//     }
-//     repeated MapFieldEntry map_field = 1;
-//
-// Implementations may choose not to generate the map_entry=true message, but
-// use a native map in the target language to hold the keys and values.
-// The reflection APIs in such implementions still need to work as
-// if the field is a repeated message field.
-//
-// NOTE: Do not set the option in .proto files. Always use the maps syntax
-// instead. The option should only be implicitly set by the proto compiler
-// parser.
-@property(nonatomic, readwrite) BOOL hasMapEntry;
+@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// Whether the message is an automatically generated map entry type for the
+/// maps field.
+///
+/// For maps fields:
+///     map<KeyType, ValueType> map_field = 1;
+/// The parsed descriptor looks like:
+///     message MapFieldEntry {
+///         option map_entry = true;
+///         optional KeyType key = 1;
+///         optional ValueType value = 2;
+///     }
+///     repeated MapFieldEntry map_field = 1;
+///
+/// Implementations may choose not to generate the map_entry=true message, but
+/// use a native map in the target language to hold the keys and values.
+/// The reflection APIs in such implementions still need to work as
+/// if the field is a repeated message field.
+///
+/// NOTE: Do not set the option in .proto files. Always use the maps syntax
+/// instead. The option should only be implicitly set by the proto compiler
+/// parser.
 @property(nonatomic, readwrite) BOOL mapEntry;
 
-// The parser stores options it doesn't recognize here. See above.
+@property(nonatomic, readwrite) BOOL hasMapEntry;
+/// The parser stores options it doesn't recognize here. See above.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBUninterpretedOption*> *uninterpretedOptionArray;
+/// The number of items in @c uninterpretedOptionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
@@ -743,77 +804,78 @@
 
 @interface GPBFieldOptions : GPBMessage
 
-// The ctype option instructs the C++ code generator to use a different
-// representation of the field than it normally would.  See the specific
-// options below.  This option is not yet implemented in the open source
-// release -- sorry, we'll try to include it in a future version!
-@property(nonatomic, readwrite) BOOL hasCtype;
+/// The ctype option instructs the C++ code generator to use a different
+/// representation of the field than it normally would.  See the specific
+/// options below.  This option is not yet implemented in the open source
+/// release -- sorry, we'll try to include it in a future version!
 @property(nonatomic, readwrite) GPBFieldOptions_CType ctype;
 
-// The packed option can be enabled for repeated primitive fields to enable
-// a more efficient representation on the wire. Rather than repeatedly
-// writing the tag and type for each element, the entire array is encoded as
-// a single length-delimited blob. In proto3, only explicit setting it to
-// false will avoid using packed encoding.
-@property(nonatomic, readwrite) BOOL hasPacked;
+@property(nonatomic, readwrite) BOOL hasCtype;
+/// The packed option can be enabled for repeated primitive fields to enable
+/// a more efficient representation on the wire. Rather than repeatedly
+/// writing the tag and type for each element, the entire array is encoded as
+/// a single length-delimited blob. In proto3, only explicit setting it to
+/// false will avoid using packed encoding.
 @property(nonatomic, readwrite) BOOL packed;
 
-// The jstype option determines the JavaScript type used for values of the
-// field.  The option is permitted only for 64 bit integral and fixed types
-// (int64, uint64, sint64, fixed64, sfixed64).  By default these types are
-// represented as JavaScript strings.  This avoids loss of precision that can
-// happen when a large value is converted to a floating point JavaScript
-// numbers.  Specifying JS_NUMBER for the jstype causes the generated
-// JavaScript code to use the JavaScript "number" type instead of strings.
-// This option is an enum to permit additional types to be added,
-// e.g. goog.math.Integer.
-@property(nonatomic, readwrite) BOOL hasJstype;
+@property(nonatomic, readwrite) BOOL hasPacked;
+/// The jstype option determines the JavaScript type used for values of the
+/// field.  The option is permitted only for 64 bit integral and fixed types
+/// (int64, uint64, sint64, fixed64, sfixed64).  By default these types are
+/// represented as JavaScript strings.  This avoids loss of precision that can
+/// happen when a large value is converted to a floating point JavaScript
+/// numbers.  Specifying JS_NUMBER for the jstype causes the generated
+/// JavaScript code to use the JavaScript "number" type instead of strings.
+/// This option is an enum to permit additional types to be added,
+/// e.g. goog.math.Integer.
 @property(nonatomic, readwrite) GPBFieldOptions_JSType jstype;
 
-// Should this field be parsed lazily?  Lazy applies only to message-type
-// fields.  It means that when the outer message is initially parsed, the
-// inner message's contents will not be parsed but instead stored in encoded
-// form.  The inner message will actually be parsed when it is first accessed.
-//
-// This is only a hint.  Implementations are free to choose whether to use
-// eager or lazy parsing regardless of the value of this option.  However,
-// setting this option true suggests that the protocol author believes that
-// using lazy parsing on this field is worth the additional bookkeeping
-// overhead typically needed to implement it.
-//
-// This option does not affect the public interface of any generated code;
-// all method signatures remain the same.  Furthermore, thread-safety of the
-// interface is not affected by this option; const methods remain safe to
-// call from multiple threads concurrently, while non-const methods continue
-// to require exclusive access.
-//
-//
-// Note that implementations may choose not to check required fields within
-// a lazy sub-message.  That is, calling IsInitialized() on the outher message
-// may return true even if the inner message has missing required fields.
-// This is necessary because otherwise the inner message would have to be
-// parsed in order to perform the check, defeating the purpose of lazy
-// parsing.  An implementation which chooses not to check required fields
-// must be consistent about it.  That is, for any particular sub-message, the
-// implementation must either *always* check its required fields, or *never*
-// check its required fields, regardless of whether or not the message has
-// been parsed.
-@property(nonatomic, readwrite) BOOL hasLazy;
+@property(nonatomic, readwrite) BOOL hasJstype;
+/// Should this field be parsed lazily?  Lazy applies only to message-type
+/// fields.  It means that when the outer message is initially parsed, the
+/// inner message's contents will not be parsed but instead stored in encoded
+/// form.  The inner message will actually be parsed when it is first accessed.
+///
+/// This is only a hint.  Implementations are free to choose whether to use
+/// eager or lazy parsing regardless of the value of this option.  However,
+/// setting this option true suggests that the protocol author believes that
+/// using lazy parsing on this field is worth the additional bookkeeping
+/// overhead typically needed to implement it.
+///
+/// This option does not affect the public interface of any generated code;
+/// all method signatures remain the same.  Furthermore, thread-safety of the
+/// interface is not affected by this option; const methods remain safe to
+/// call from multiple threads concurrently, while non-const methods continue
+/// to require exclusive access.
+///
+///
+/// Note that implementations may choose not to check required fields within
+/// a lazy sub-message.  That is, calling IsInitialized() on the outher message
+/// may return true even if the inner message has missing required fields.
+/// This is necessary because otherwise the inner message would have to be
+/// parsed in order to perform the check, defeating the purpose of lazy
+/// parsing.  An implementation which chooses not to check required fields
+/// must be consistent about it.  That is, for any particular sub-message, the
+/// implementation must either *always* check its required fields, or *never*
+/// check its required fields, regardless of whether or not the message has
+/// been parsed.
 @property(nonatomic, readwrite) BOOL lazy;
 
-// Is this field deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for accessors, or it will be completely ignored; in the very least, this
-// is a formalization for deprecating fields.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
+@property(nonatomic, readwrite) BOOL hasLazy;
+/// Is this field deprecated?
+/// Depending on the target platform, this can emit Deprecated annotations
+/// for accessors, or it will be completely ignored; in the very least, this
+/// is a formalization for deprecating fields.
 @property(nonatomic, readwrite) BOOL deprecated;
 
-// For Google-internal migration only. Do not use.
-@property(nonatomic, readwrite) BOOL hasWeak;
+@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// For Google-internal migration only. Do not use.
 @property(nonatomic, readwrite) BOOL weak;
 
-// The parser stores options it doesn't recognize here. See above.
+@property(nonatomic, readwrite) BOOL hasWeak;
+/// The parser stores options it doesn't recognize here. See above.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBUninterpretedOption*> *uninterpretedOptionArray;
+/// The number of items in @c uninterpretedOptionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
@@ -828,20 +890,21 @@
 
 @interface GPBEnumOptions : GPBMessage
 
-// Set this option to true to allow mapping different tag names to the same
-// value.
-@property(nonatomic, readwrite) BOOL hasAllowAlias;
+/// Set this option to true to allow mapping different tag names to the same
+/// value.
 @property(nonatomic, readwrite) BOOL allowAlias;
 
-// Is this enum deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the enum, or it will be completely ignored; in the very least, this
-// is a formalization for deprecating enums.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
+@property(nonatomic, readwrite) BOOL hasAllowAlias;
+/// Is this enum deprecated?
+/// Depending on the target platform, this can emit Deprecated annotations
+/// for the enum, or it will be completely ignored; in the very least, this
+/// is a formalization for deprecating enums.
 @property(nonatomic, readwrite) BOOL deprecated;
 
-// The parser stores options it doesn't recognize here. See above.
+@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// The parser stores options it doesn't recognize here. See above.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBUninterpretedOption*> *uninterpretedOptionArray;
+/// The number of items in @c uninterpretedOptionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
@@ -855,15 +918,16 @@
 
 @interface GPBEnumValueOptions : GPBMessage
 
-// Is this enum value deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the enum value, or it will be completely ignored; in the very least,
-// this is a formalization for deprecating enum values.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// Is this enum value deprecated?
+/// Depending on the target platform, this can emit Deprecated annotations
+/// for the enum value, or it will be completely ignored; in the very least,
+/// this is a formalization for deprecating enum values.
 @property(nonatomic, readwrite) BOOL deprecated;
 
-// The parser stores options it doesn't recognize here. See above.
+@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// The parser stores options it doesn't recognize here. See above.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBUninterpretedOption*> *uninterpretedOptionArray;
+/// The number of items in @c uninterpretedOptionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
@@ -877,15 +941,16 @@
 
 @interface GPBServiceOptions : GPBMessage
 
-// Is this service deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the service, or it will be completely ignored; in the very least,
-// this is a formalization for deprecating services.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// Is this service deprecated?
+/// Depending on the target platform, this can emit Deprecated annotations
+/// for the service, or it will be completely ignored; in the very least,
+/// this is a formalization for deprecating services.
 @property(nonatomic, readwrite) BOOL deprecated;
 
-// The parser stores options it doesn't recognize here. See above.
+@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// The parser stores options it doesn't recognize here. See above.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBUninterpretedOption*> *uninterpretedOptionArray;
+/// The number of items in @c uninterpretedOptionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
@@ -899,15 +964,16 @@
 
 @interface GPBMethodOptions : GPBMessage
 
-// Is this method deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the method, or it will be completely ignored; in the very least,
-// this is a formalization for deprecating methods.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// Is this method deprecated?
+/// Depending on the target platform, this can emit Deprecated annotations
+/// for the method, or it will be completely ignored; in the very least,
+/// this is a formalization for deprecating methods.
 @property(nonatomic, readwrite) BOOL deprecated;
 
-// The parser stores options it doesn't recognize here. See above.
+@property(nonatomic, readwrite) BOOL hasDeprecated;
+/// The parser stores options it doesn't recognize here. See above.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBUninterpretedOption*> *uninterpretedOptionArray;
+/// The number of items in @c uninterpretedOptionArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
@@ -924,36 +990,40 @@
   GPBUninterpretedOption_FieldNumber_AggregateValue = 8,
 };
 
-// A message representing a option the parser does not recognize. This only
-// appears in options protos created by the compiler::Parser class.
-// DescriptorPool resolves these when building Descriptor objects. Therefore,
-// options protos in descriptor objects (e.g. returned by Descriptor::options(),
-// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
-// in them.
+/// A message representing a option the parser does not recognize. This only
+/// appears in options protos created by the compiler::Parser class.
+/// DescriptorPool resolves these when building Descriptor objects. Therefore,
+/// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+/// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+/// in them.
 @interface GPBUninterpretedOption : GPBMessage
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBUninterpretedOption_NamePart*> *nameArray;
+/// The number of items in @c nameArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger nameArray_Count;
 
-// The value of the uninterpreted option, in whatever type the tokenizer
-// identified it as during parsing. Exactly one of these should be set.
-@property(nonatomic, readwrite) BOOL hasIdentifierValue;
+/// The value of the uninterpreted option, in whatever type the tokenizer
+/// identified it as during parsing. Exactly one of these should be set.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *identifierValue;
+/// Test to see if @c identifierValue has been set.
+@property(nonatomic, readwrite) BOOL hasIdentifierValue;
 
-@property(nonatomic, readwrite) BOOL hasPositiveIntValue;
 @property(nonatomic, readwrite) uint64_t positiveIntValue;
 
-@property(nonatomic, readwrite) BOOL hasNegativeIntValue;
+@property(nonatomic, readwrite) BOOL hasPositiveIntValue;
 @property(nonatomic, readwrite) int64_t negativeIntValue;
 
-@property(nonatomic, readwrite) BOOL hasDoubleValue;
+@property(nonatomic, readwrite) BOOL hasNegativeIntValue;
 @property(nonatomic, readwrite) double doubleValue;
 
-@property(nonatomic, readwrite) BOOL hasStringValue;
+@property(nonatomic, readwrite) BOOL hasDoubleValue;
 @property(nonatomic, readwrite, copy, null_resettable) NSData *stringValue;
+/// Test to see if @c stringValue has been set.
+@property(nonatomic, readwrite) BOOL hasStringValue;
 
-@property(nonatomic, readwrite) BOOL hasAggregateValue;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *aggregateValue;
+/// Test to see if @c aggregateValue has been set.
+@property(nonatomic, readwrite) BOOL hasAggregateValue;
 
 @end
 
@@ -964,19 +1034,20 @@
   GPBUninterpretedOption_NamePart_FieldNumber_IsExtension = 2,
 };
 
-// The name of the uninterpreted option.  Each string represents a segment in
-// a dot-separated name.  is_extension is true iff a segment represents an
-// extension (denoted with parentheses in options specs in .proto files).
-// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
-// "foo.(bar.baz).qux".
+/// The name of the uninterpreted option.  Each string represents a segment in
+/// a dot-separated name.  is_extension is true iff a segment represents an
+/// extension (denoted with parentheses in options specs in .proto files).
+/// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+/// "foo.(bar.baz).qux".
 @interface GPBUninterpretedOption_NamePart : GPBMessage
 
-@property(nonatomic, readwrite) BOOL hasNamePart;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *namePart;
+/// Test to see if @c namePart has been set.
+@property(nonatomic, readwrite) BOOL hasNamePart;
 
-@property(nonatomic, readwrite) BOOL hasIsExtension;
 @property(nonatomic, readwrite) BOOL isExtension;
 
+@property(nonatomic, readwrite) BOOL hasIsExtension;
 @end
 
 #pragma mark - GPBSourceCodeInfo
@@ -985,54 +1056,55 @@
   GPBSourceCodeInfo_FieldNumber_LocationArray = 1,
 };
 
-// Encapsulates information about the original source file from which a
-// FileDescriptorProto was generated.
+/// Encapsulates information about the original source file from which a
+/// FileDescriptorProto was generated.
 @interface GPBSourceCodeInfo : GPBMessage
 
-// A Location identifies a piece of source code in a .proto file which
-// corresponds to a particular definition.  This information is intended
-// to be useful to IDEs, code indexers, documentation generators, and similar
-// tools.
-//
-// For example, say we have a file like:
-//   message Foo {
-//     optional string foo = 1;
-//   }
-// Let's look at just the field definition:
-//   optional string foo = 1;
-//   ^       ^^     ^^  ^  ^^^
-//   a       bc     de  f  ghi
-// We have the following locations:
-//   span   path               represents
-//   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
-//   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
-//   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
-//   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
-//   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
-//
-// Notes:
-// - A location may refer to a repeated field itself (i.e. not to any
-//   particular index within it).  This is used whenever a set of elements are
-//   logically enclosed in a single code segment.  For example, an entire
-//   extend block (possibly containing multiple extension definitions) will
-//   have an outer location whose path refers to the "extensions" repeated
-//   field without an index.
-// - Multiple locations may have the same path.  This happens when a single
-//   logical declaration is spread out across multiple places.  The most
-//   obvious example is the "extend" block again -- there may be multiple
-//   extend blocks in the same scope, each of which will have the same path.
-// - A location's span is not always a subset of its parent's span.  For
-//   example, the "extendee" of an extension declaration appears at the
-//   beginning of the "extend" block and is shared by all extensions within
-//   the block.
-// - Just because a location's span is a subset of some other location's span
-//   does not mean that it is a descendent.  For example, a "group" defines
-//   both a type and a field in a single declaration.  Thus, the locations
-//   corresponding to the type and field and their components will overlap.
-// - Code which tries to interpret locations should probably be designed to
-//   ignore those that it doesn't understand, as more types of locations could
-//   be recorded in the future.
+/// A Location identifies a piece of source code in a .proto file which
+/// corresponds to a particular definition.  This information is intended
+/// to be useful to IDEs, code indexers, documentation generators, and similar
+/// tools.
+///
+/// For example, say we have a file like:
+///   message Foo {
+///     optional string foo = 1;
+///   }
+/// Let's look at just the field definition:
+///   optional string foo = 1;
+///   ^       ^^     ^^  ^  ^^^
+///   a       bc     de  f  ghi
+/// We have the following locations:
+///   span   path               represents
+///   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
+///   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
+///   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
+///   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
+///   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
+///
+/// Notes:
+/// - A location may refer to a repeated field itself (i.e. not to any
+///   particular index within it).  This is used whenever a set of elements are
+///   logically enclosed in a single code segment.  For example, an entire
+///   extend block (possibly containing multiple extension definitions) will
+///   have an outer location whose path refers to the "extensions" repeated
+///   field without an index.
+/// - Multiple locations may have the same path.  This happens when a single
+///   logical declaration is spread out across multiple places.  The most
+///   obvious example is the "extend" block again -- there may be multiple
+///   extend blocks in the same scope, each of which will have the same path.
+/// - A location's span is not always a subset of its parent's span.  For
+///   example, the "extendee" of an extension declaration appears at the
+///   beginning of the "extend" block and is shared by all extensions within
+///   the block.
+/// - Just because a location's span is a subset of some other location's span
+///   does not mean that it is a descendent.  For example, a "group" defines
+///   both a type and a field in a single declaration.  Thus, the locations
+///   corresponding to the type and field and their components will overlap.
+/// - Code which tries to interpret locations should probably be designed to
+///   ignore those that it doesn't understand, as more types of locations could
+///   be recorded in the future.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBSourceCodeInfo_Location*> *locationArray;
+/// The number of items in @c locationArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger locationArray_Count;
 
 @end
@@ -1049,94 +1121,99 @@
 
 @interface GPBSourceCodeInfo_Location : GPBMessage
 
-// Identifies which part of the FileDescriptorProto was defined at this
-// location.
-//
-// Each element is a field number or an index.  They form a path from
-// the root FileDescriptorProto to the place where the definition.  For
-// example, this path:
-//   [ 4, 3, 2, 7, 1 ]
-// refers to:
-//   file.message_type(3)  // 4, 3
-//       .field(7)         // 2, 7
-//       .name()           // 1
-// This is because FileDescriptorProto.message_type has field number 4:
-//   repeated DescriptorProto message_type = 4;
-// and DescriptorProto.field has field number 2:
-//   repeated FieldDescriptorProto field = 2;
-// and FieldDescriptorProto.name has field number 1:
-//   optional string name = 1;
-//
-// Thus, the above path gives the location of a field name.  If we removed
-// the last element:
-//   [ 4, 3, 2, 7 ]
-// this path refers to the whole field declaration (from the beginning
-// of the label to the terminating semicolon).
+/// Identifies which part of the FileDescriptorProto was defined at this
+/// location.
+///
+/// Each element is a field number or an index.  They form a path from
+/// the root FileDescriptorProto to the place where the definition.  For
+/// example, this path:
+///   [ 4, 3, 2, 7, 1 ]
+/// refers to:
+///   file.message_type(3)  // 4, 3
+///       .field(7)         // 2, 7
+///       .name()           // 1
+/// This is because FileDescriptorProto.message_type has field number 4:
+///   repeated DescriptorProto message_type = 4;
+/// and DescriptorProto.field has field number 2:
+///   repeated FieldDescriptorProto field = 2;
+/// and FieldDescriptorProto.name has field number 1:
+///   optional string name = 1;
+///
+/// Thus, the above path gives the location of a field name.  If we removed
+/// the last element:
+///   [ 4, 3, 2, 7 ]
+/// this path refers to the whole field declaration (from the beginning
+/// of the label to the terminating semicolon).
 @property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *pathArray;
+/// The number of items in @c pathArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger pathArray_Count;
 
-// Always has exactly three or four elements: start line, start column,
-// end line (optional, otherwise assumed same as start line), end column.
-// These are packed into a single field for efficiency.  Note that line
-// and column numbers are zero-based -- typically you will want to add
-// 1 to each before displaying to a user.
+/// Always has exactly three or four elements: start line, start column,
+/// end line (optional, otherwise assumed same as start line), end column.
+/// These are packed into a single field for efficiency.  Note that line
+/// and column numbers are zero-based -- typically you will want to add
+/// 1 to each before displaying to a user.
 @property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *spanArray;
+/// The number of items in @c spanArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger spanArray_Count;
 
-// If this SourceCodeInfo represents a complete declaration, these are any
-// comments appearing before and after the declaration which appear to be
-// attached to the declaration.
-//
-// A series of line comments appearing on consecutive lines, with no other
-// tokens appearing on those lines, will be treated as a single comment.
-//
-// leading_detached_comments will keep paragraphs of comments that appear
-// before (but not connected to) the current element. Each paragraph,
-// separated by empty lines, will be one comment element in the repeated
-// field.
-//
-// Only the comment content is provided; comment markers (e.g. //) are
-// stripped out.  For block comments, leading whitespace and an asterisk
-// will be stripped from the beginning of each line other than the first.
-// Newlines are included in the output.
-//
-// Examples:
-//
-//   optional int32 foo = 1;  // Comment attached to foo.
-//   // Comment attached to bar.
-//   optional int32 bar = 2;
-//
-//   optional string baz = 3;
-//   // Comment attached to baz.
-//   // Another line attached to baz.
-//
-//   // Comment attached to qux.
-//   //
-//   // Another line attached to qux.
-//   optional double qux = 4;
-//
-//   // Detached comment for corge. This is not leading or trailing comments
-//   // to qux or corge because there are blank lines separating it from
-//   // both.
-//
-//   // Detached comment for corge paragraph 2.
-//
-//   optional string corge = 5;
-//   /* Block comment attached
-//    * to corge.  Leading asterisks
-//    * will be removed. */
-//   /* Block comment attached to
-//    * grault. */
-//   optional int32 grault = 6;
-//
-//   // ignored detached comments.
-@property(nonatomic, readwrite) BOOL hasLeadingComments;
+/// If this SourceCodeInfo represents a complete declaration, these are any
+/// comments appearing before and after the declaration which appear to be
+/// attached to the declaration.
+///
+/// A series of line comments appearing on consecutive lines, with no other
+/// tokens appearing on those lines, will be treated as a single comment.
+///
+/// leading_detached_comments will keep paragraphs of comments that appear
+/// before (but not connected to) the current element. Each paragraph,
+/// separated by empty lines, will be one comment element in the repeated
+/// field.
+///
+/// Only the comment content is provided; comment markers (e.g. //) are
+/// stripped out.  For block comments, leading whitespace and an asterisk
+/// will be stripped from the beginning of each line other than the first.
+/// Newlines are included in the output.
+///
+/// Examples:
+///
+///   optional int32 foo = 1;  // Comment attached to foo.
+///   // Comment attached to bar.
+///   optional int32 bar = 2;
+///
+///   optional string baz = 3;
+///   // Comment attached to baz.
+///   // Another line attached to baz.
+///
+///   // Comment attached to qux.
+///   //
+///   // Another line attached to qux.
+///   optional double qux = 4;
+///
+///   // Detached comment for corge. This is not leading or trailing comments
+///   // to qux or corge because there are blank lines separating it from
+///   // both.
+///
+///   // Detached comment for corge paragraph 2.
+///
+///   optional string corge = 5;
+///   /* Block comment attached
+///    * to corge.  Leading asterisks
+///    * will be removed. */
+///   /* Block comment attached to
+///    * grault. */
+///   optional int32 grault = 6;
+///
+///   // ignored detached comments.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *leadingComments;
+/// Test to see if @c leadingComments has been set.
+@property(nonatomic, readwrite) BOOL hasLeadingComments;
 
-@property(nonatomic, readwrite) BOOL hasTrailingComments;
 @property(nonatomic, readwrite, copy, null_resettable) NSString *trailingComments;
+/// Test to see if @c trailingComments has been set.
+@property(nonatomic, readwrite) BOOL hasTrailingComments;
 
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *leadingDetachedCommentsArray;
+/// The number of items in @c leadingDetachedCommentsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger leadingDetachedCommentsArray_Count;
 
 @end
@@ -1147,14 +1224,15 @@
   GPBGeneratedCodeInfo_FieldNumber_AnnotationArray = 1,
 };
 
-// Describes the relationship between generated code and its original source
-// file. A GeneratedCodeInfo message is associated with only one generated
-// source file, but may contain references to different source .proto files.
+/// Describes the relationship between generated code and its original source
+/// file. A GeneratedCodeInfo message is associated with only one generated
+/// source file, but may contain references to different source .proto files.
 @interface GPBGeneratedCodeInfo : GPBMessage
 
-// An Annotation connects some span of text in generated code to an element
-// of its generating .proto file.
+/// An Annotation connects some span of text in generated code to an element
+/// of its generating .proto file.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBGeneratedCodeInfo_Annotation*> *annotationArray;
+/// The number of items in @c annotationArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger annotationArray_Count;
 
 @end
@@ -1170,26 +1248,28 @@
 
 @interface GPBGeneratedCodeInfo_Annotation : GPBMessage
 
-// Identifies the element in the original source .proto file. This field
-// is formatted the same as SourceCodeInfo.Location.path.
+/// Identifies the element in the original source .proto file. This field
+/// is formatted the same as SourceCodeInfo.Location.path.
 @property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *pathArray;
+/// The number of items in @c pathArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger pathArray_Count;
 
-// Identifies the filesystem path to the original source .proto.
-@property(nonatomic, readwrite) BOOL hasSourceFile;
+/// Identifies the filesystem path to the original source .proto.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *sourceFile;
+/// Test to see if @c sourceFile has been set.
+@property(nonatomic, readwrite) BOOL hasSourceFile;
 
-// Identifies the starting offset in bytes in the generated code
-// that relates to the identified object.
-@property(nonatomic, readwrite) BOOL hasBegin;
+/// Identifies the starting offset in bytes in the generated code
+/// that relates to the identified object.
 @property(nonatomic, readwrite) int32_t begin;
 
-// Identifies the ending offset in bytes in the generated code that
-// relates to the identified offset. The end offset should be one past
-// the last relevant byte (so the length of the text = end - begin).
-@property(nonatomic, readwrite) BOOL hasEnd;
+@property(nonatomic, readwrite) BOOL hasBegin;
+/// Identifies the ending offset in bytes in the generated code that
+/// relates to the identified offset. The end offset should be one past
+/// the last relevant byte (so the length of the text = end - begin).
 @property(nonatomic, readwrite) int32_t end;
 
+@property(nonatomic, readwrite) BOOL hasEnd;
 @end
 
 NS_ASSUME_NONNULL_END
diff --git a/objectivec/google/protobuf/Duration.pbobjc.h b/objectivec/google/protobuf/Duration.pbobjc.h
index b592640..ebf9119 100644
--- a/objectivec/google/protobuf/Duration.pbobjc.h
+++ b/objectivec/google/protobuf/Duration.pbobjc.h
@@ -15,13 +15,15 @@
 
 #pragma mark - GPBDurationRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBDurationRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBDuration
@@ -31,58 +33,58 @@
   GPBDuration_FieldNumber_Nanos = 2,
 };
 
-// A Duration represents a signed, fixed-length span of time represented
-// as a count of seconds and fractions of seconds at nanosecond
-// resolution. It is independent of any calendar and concepts like "day"
-// or "month". It is related to Timestamp in that the difference between
-// two Timestamp values is a Duration and it can be added or subtracted
-// from a Timestamp. Range is approximately +-10,000 years.
-//
-// Example 1: Compute Duration from two Timestamps in pseudo code.
-//
-//     Timestamp start = ...;
-//     Timestamp end = ...;
-//     Duration duration = ...;
-//
-//     duration.seconds = end.seconds - start.seconds;
-//     duration.nanos = end.nanos - start.nanos;
-//
-//     if (duration.seconds < 0 && duration.nanos > 0) {
-//       duration.seconds += 1;
-//       duration.nanos -= 1000000000;
-//     } else if (durations.seconds > 0 && duration.nanos < 0) {
-//       duration.seconds -= 1;
-//       duration.nanos += 1000000000;
-//     }
-//
-// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
-//
-//     Timestamp start = ...;
-//     Duration duration = ...;
-//     Timestamp end = ...;
-//
-//     end.seconds = start.seconds + duration.seconds;
-//     end.nanos = start.nanos + duration.nanos;
-//
-//     if (end.nanos < 0) {
-//       end.seconds -= 1;
-//       end.nanos += 1000000000;
-//     } else if (end.nanos >= 1000000000) {
-//       end.seconds += 1;
-//       end.nanos -= 1000000000;
-//     }
+/// A Duration represents a signed, fixed-length span of time represented
+/// as a count of seconds and fractions of seconds at nanosecond
+/// resolution. It is independent of any calendar and concepts like "day"
+/// or "month". It is related to Timestamp in that the difference between
+/// two Timestamp values is a Duration and it can be added or subtracted
+/// from a Timestamp. Range is approximately +-10,000 years.
+///
+/// Example 1: Compute Duration from two Timestamps in pseudo code.
+///
+///     Timestamp start = ...;
+///     Timestamp end = ...;
+///     Duration duration = ...;
+///
+///     duration.seconds = end.seconds - start.seconds;
+///     duration.nanos = end.nanos - start.nanos;
+///
+///     if (duration.seconds < 0 && duration.nanos > 0) {
+///       duration.seconds += 1;
+///       duration.nanos -= 1000000000;
+///     } else if (durations.seconds > 0 && duration.nanos < 0) {
+///       duration.seconds -= 1;
+///       duration.nanos += 1000000000;
+///     }
+///
+/// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
+///
+///     Timestamp start = ...;
+///     Duration duration = ...;
+///     Timestamp end = ...;
+///
+///     end.seconds = start.seconds + duration.seconds;
+///     end.nanos = start.nanos + duration.nanos;
+///
+///     if (end.nanos < 0) {
+///       end.seconds -= 1;
+///       end.nanos += 1000000000;
+///     } else if (end.nanos >= 1000000000) {
+///       end.seconds += 1;
+///       end.nanos -= 1000000000;
+///     }
 @interface GPBDuration : GPBMessage
 
-// Signed seconds of the span of time. Must be from -315,576,000,000
-// to +315,576,000,000 inclusive.
+/// Signed seconds of the span of time. Must be from -315,576,000,000
+/// to +315,576,000,000 inclusive.
 @property(nonatomic, readwrite) int64_t seconds;
 
-// Signed fractions of a second at nanosecond resolution of the span
-// of time. Durations less than one second are represented with a 0
-// `seconds` field and a positive or negative `nanos` field. For durations
-// of one second or more, a non-zero value for the `nanos` field must be
-// of the same sign as the `seconds` field. Must be from -999,999,999
-// to +999,999,999 inclusive.
+/// Signed fractions of a second at nanosecond resolution of the span
+/// of time. Durations less than one second are represented with a 0
+/// `seconds` field and a positive or negative `nanos` field. For durations
+/// of one second or more, a non-zero value for the `nanos` field must be
+/// of the same sign as the `seconds` field. Must be from -999,999,999
+/// to +999,999,999 inclusive.
 @property(nonatomic, readwrite) int32_t nanos;
 
 @end
diff --git a/objectivec/google/protobuf/Empty.pbobjc.h b/objectivec/google/protobuf/Empty.pbobjc.h
index bace614..ca09f71 100644
--- a/objectivec/google/protobuf/Empty.pbobjc.h
+++ b/objectivec/google/protobuf/Empty.pbobjc.h
@@ -15,26 +15,28 @@
 
 #pragma mark - GPBEmptyRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBEmptyRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBEmpty
 
-// A generic empty message that you can re-use to avoid defining duplicated
-// empty messages in your APIs. A typical example is to use it as the request
-// or the response type of an API method. For instance:
-//
-//     service Foo {
-//       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
-//     }
-//
-// The JSON representation for `Empty` is empty JSON object `{}`.
+/// A generic empty message that you can re-use to avoid defining duplicated
+/// empty messages in your APIs. A typical example is to use it as the request
+/// or the response type of an API method. For instance:
+///
+///     service Foo {
+///       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
+///     }
+///
+/// The JSON representation for `Empty` is empty JSON object `{}`.
 @interface GPBEmpty : GPBMessage
 
 @end
diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.h b/objectivec/google/protobuf/FieldMask.pbobjc.h
index f4bc265..f861a98 100644
--- a/objectivec/google/protobuf/FieldMask.pbobjc.h
+++ b/objectivec/google/protobuf/FieldMask.pbobjc.h
@@ -15,13 +15,15 @@
 
 #pragma mark - GPBFieldMaskRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBFieldMaskRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBFieldMask
@@ -30,132 +32,133 @@
   GPBFieldMask_FieldNumber_PathsArray = 1,
 };
 
-// `FieldMask` represents a set of symbolic field paths, for example:
-//
-//     paths: "f.a"
-//     paths: "f.b.d"
-//
-// Here `f` represents a field in some root message, `a` and `b`
-// fields in the message found in `f`, and `d` a field found in the
-// message in `f.b`.
-//
-// Field masks are used to specify a subset of fields that should be
-// returned by a get operation or modified by an update operation.
-// Field masks also have a custom JSON encoding (see below).
-//
-// # Field Masks in Projections
-//
-// When used in the context of a projection, a response message or
-// sub-message is filtered by the API to only contain those fields as
-// specified in the mask. For example, if the mask in the previous
-// example is applied to a response message as follows:
-//
-//     f {
-//       a : 22
-//       b {
-//         d : 1
-//         x : 2
-//       }
-//       y : 13
-//     }
-//     z: 8
-//
-// The result will not contain specific values for fields x,y and z
-// (their value will be set to the default, and omitted in proto text
-// output):
-//
-//
-//     f {
-//       a : 22
-//       b {
-//         d : 1
-//       }
-//     }
-//
-// A repeated field is not allowed except at the last position of a
-// field mask.
-//
-// If a FieldMask object is not present in a get operation, the
-// operation applies to all fields (as if a FieldMask of all fields
-// had been specified).
-//
-// Note that a field mask does not necessarily applies to the
-// top-level response message. In case of a REST get operation, the
-// field mask applies directly to the response, but in case of a REST
-// list operation, the mask instead applies to each individual message
-// in the returned resource list. In case of a REST custom method,
-// other definitions may be used. Where the mask applies will be
-// clearly documented together with its declaration in the API.  In
-// any case, the effect on the returned resource/resources is required
-// behavior for APIs.
-//
-// # Field Masks in Update Operations
-//
-// A field mask in update operations specifies which fields of the
-// targeted resource are going to be updated. The API is required
-// to only change the values of the fields as specified in the mask
-// and leave the others untouched. If a resource is passed in to
-// describe the updated values, the API ignores the values of all
-// fields not covered by the mask.
-//
-// In order to reset a field's value to the default, the field must
-// be in the mask and set to the default value in the provided resource.
-// Hence, in order to reset all fields of a resource, provide a default
-// instance of the resource and set all fields in the mask, or do
-// not provide a mask as described below.
-//
-// If a field mask is not present on update, the operation applies to
-// all fields (as if a field mask of all fields has been specified).
-// Note that in the presence of schema evolution, this may mean that
-// fields the client does not know and has therefore not filled into
-// the request will be reset to their default. If this is unwanted
-// behavior, a specific service may require a client to always specify
-// a field mask, producing an error if not.
-//
-// As with get operations, the location of the resource which
-// describes the updated values in the request message depends on the
-// operation kind. In any case, the effect of the field mask is
-// required to be honored by the API.
-//
-// ## Considerations for HTTP REST
-//
-// The HTTP kind of an update operation which uses a field mask must
-// be set to PATCH instead of PUT in order to satisfy HTTP semantics
-// (PUT must only be used for full updates).
-//
-// # JSON Encoding of Field Masks
-//
-// In JSON, a field mask is encoded as a single string where paths are
-// separated by a comma. Fields name in each path are converted
-// to/from lower-camel naming conventions.
-//
-// As an example, consider the following message declarations:
-//
-//     message Profile {
-//       User user = 1;
-//       Photo photo = 2;
-//     }
-//     message User {
-//       string display_name = 1;
-//       string address = 2;
-//     }
-//
-// In proto a field mask for `Profile` may look as such:
-//
-//     mask {
-//       paths: "user.display_name"
-//       paths: "photo"
-//     }
-//
-// In JSON, the same mask is represented as below:
-//
-//     {
-//       mask: "user.displayName,photo"
-//     }
+/// `FieldMask` represents a set of symbolic field paths, for example:
+///
+///     paths: "f.a"
+///     paths: "f.b.d"
+///
+/// Here `f` represents a field in some root message, `a` and `b`
+/// fields in the message found in `f`, and `d` a field found in the
+/// message in `f.b`.
+///
+/// Field masks are used to specify a subset of fields that should be
+/// returned by a get operation or modified by an update operation.
+/// Field masks also have a custom JSON encoding (see below).
+///
+/// # Field Masks in Projections
+///
+/// When used in the context of a projection, a response message or
+/// sub-message is filtered by the API to only contain those fields as
+/// specified in the mask. For example, if the mask in the previous
+/// example is applied to a response message as follows:
+///
+///     f {
+///       a : 22
+///       b {
+///         d : 1
+///         x : 2
+///       }
+///       y : 13
+///     }
+///     z: 8
+///
+/// The result will not contain specific values for fields x,y and z
+/// (their value will be set to the default, and omitted in proto text
+/// output):
+///
+///
+///     f {
+///       a : 22
+///       b {
+///         d : 1
+///       }
+///     }
+///
+/// A repeated field is not allowed except at the last position of a
+/// field mask.
+///
+/// If a FieldMask object is not present in a get operation, the
+/// operation applies to all fields (as if a FieldMask of all fields
+/// had been specified).
+///
+/// Note that a field mask does not necessarily applies to the
+/// top-level response message. In case of a REST get operation, the
+/// field mask applies directly to the response, but in case of a REST
+/// list operation, the mask instead applies to each individual message
+/// in the returned resource list. In case of a REST custom method,
+/// other definitions may be used. Where the mask applies will be
+/// clearly documented together with its declaration in the API.  In
+/// any case, the effect on the returned resource/resources is required
+/// behavior for APIs.
+///
+/// # Field Masks in Update Operations
+///
+/// A field mask in update operations specifies which fields of the
+/// targeted resource are going to be updated. The API is required
+/// to only change the values of the fields as specified in the mask
+/// and leave the others untouched. If a resource is passed in to
+/// describe the updated values, the API ignores the values of all
+/// fields not covered by the mask.
+///
+/// In order to reset a field's value to the default, the field must
+/// be in the mask and set to the default value in the provided resource.
+/// Hence, in order to reset all fields of a resource, provide a default
+/// instance of the resource and set all fields in the mask, or do
+/// not provide a mask as described below.
+///
+/// If a field mask is not present on update, the operation applies to
+/// all fields (as if a field mask of all fields has been specified).
+/// Note that in the presence of schema evolution, this may mean that
+/// fields the client does not know and has therefore not filled into
+/// the request will be reset to their default. If this is unwanted
+/// behavior, a specific service may require a client to always specify
+/// a field mask, producing an error if not.
+///
+/// As with get operations, the location of the resource which
+/// describes the updated values in the request message depends on the
+/// operation kind. In any case, the effect of the field mask is
+/// required to be honored by the API.
+///
+/// ## Considerations for HTTP REST
+///
+/// The HTTP kind of an update operation which uses a field mask must
+/// be set to PATCH instead of PUT in order to satisfy HTTP semantics
+/// (PUT must only be used for full updates).
+///
+/// # JSON Encoding of Field Masks
+///
+/// In JSON, a field mask is encoded as a single string where paths are
+/// separated by a comma. Fields name in each path are converted
+/// to/from lower-camel naming conventions.
+///
+/// As an example, consider the following message declarations:
+///
+///     message Profile {
+///       User user = 1;
+///       Photo photo = 2;
+///     }
+///     message User {
+///       string display_name = 1;
+///       string address = 2;
+///     }
+///
+/// In proto a field mask for `Profile` may look as such:
+///
+///     mask {
+///       paths: "user.display_name"
+///       paths: "photo"
+///     }
+///
+/// In JSON, the same mask is represented as below:
+///
+///     {
+///       mask: "user.displayName,photo"
+///     }
 @interface GPBFieldMask : GPBMessage
 
-// The set of field mask paths.
+/// The set of field mask paths.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *pathsArray;
+/// The number of items in @c pathsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger pathsArray_Count;
 
 @end
diff --git a/objectivec/google/protobuf/SourceContext.pbobjc.h b/objectivec/google/protobuf/SourceContext.pbobjc.h
index 8480db1..546db67 100644
--- a/objectivec/google/protobuf/SourceContext.pbobjc.h
+++ b/objectivec/google/protobuf/SourceContext.pbobjc.h
@@ -15,13 +15,15 @@
 
 #pragma mark - GPBSourceContextRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBSourceContextRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBSourceContext
@@ -30,12 +32,12 @@
   GPBSourceContext_FieldNumber_FileName = 1,
 };
 
-// `SourceContext` represents information about the source of a
-// protobuf element, like the file in which it is defined.
+/// `SourceContext` represents information about the source of a
+/// protobuf element, like the file in which it is defined.
 @interface GPBSourceContext : GPBMessage
 
-// The path-qualified name of the .proto file that contained the associated
-// protobuf element.  For example: `"google/protobuf/source.proto"`.
+/// The path-qualified name of the .proto file that contained the associated
+/// protobuf element.  For example: `"google/protobuf/source.proto"`.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *fileName;
 
 @end
diff --git a/objectivec/google/protobuf/Struct.pbobjc.h b/objectivec/google/protobuf/Struct.pbobjc.h
index 293dea4..7b9c45a 100644
--- a/objectivec/google/protobuf/Struct.pbobjc.h
+++ b/objectivec/google/protobuf/Struct.pbobjc.h
@@ -19,29 +19,36 @@
 
 #pragma mark - Enum GPBNullValue
 
-// `NullValue` is a singleton enumeration to represent the null value for the
-// `Value` type union.
-//
-//  The JSON representation for `NullValue` is JSON `null`.
+/// `NullValue` is a singleton enumeration to represent the null value for the
+/// `Value` type union.
+///
+///  The JSON representation for `NullValue` is JSON `null`.
 typedef GPB_ENUM(GPBNullValue) {
+  /// Value used if any message's field encounters a value that is not defined
+  /// by this enum. The message will also have C functions to get/set the rawValue
+  /// of the field.
   GPBNullValue_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
-  // Null value.
+  /// Null value.
   GPBNullValue_NullValue = 0,
 };
 
 GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBNullValue_IsValidValue(int32_t value);
 
 #pragma mark - GPBStructRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBStructRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBStruct
@@ -50,18 +57,19 @@
   GPBStruct_FieldNumber_Fields = 1,
 };
 
-// `Struct` represents a structured data value, consisting of fields
-// which map to dynamically typed values. In some languages, `Struct`
-// might be supported by a native representation. For example, in
-// scripting languages like JS a struct is represented as an
-// object. The details of that representation are described together
-// with the proto support for the language.
-//
-// The JSON representation for `Struct` is JSON object.
+/// `Struct` represents a structured data value, consisting of fields
+/// which map to dynamically typed values. In some languages, `Struct`
+/// might be supported by a native representation. For example, in
+/// scripting languages like JS a struct is represented as an
+/// object. The details of that representation are described together
+/// with the proto support for the language.
+///
+/// The JSON representation for `Struct` is JSON object.
 @interface GPBStruct : GPBMessage
 
-// Map of dynamically typed values.
+/// Map of dynamically typed values.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary<NSString*, GPBValue*> *fields;
+/// The number of items in @c fields without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger fields_Count;
 
 @end
@@ -87,40 +95,46 @@
   GPBValue_Kind_OneOfCase_ListValue = 6,
 };
 
-// `Value` represents a dynamically typed value which can be either
-// null, a number, a string, a boolean, a recursive struct value, or a
-// list of values. A producer of value is expected to set one of that
-// variants, absence of any variant indicates an error.
-//
-// The JSON representation for `Value` is JSON value.
+/// `Value` represents a dynamically typed value which can be either
+/// null, a number, a string, a boolean, a recursive struct value, or a
+/// list of values. A producer of value is expected to set one of that
+/// variants, absence of any variant indicates an error.
+///
+/// The JSON representation for `Value` is JSON value.
 @interface GPBValue : GPBMessage
 
-// The kind of value.
+/// The kind of value.
 @property(nonatomic, readonly) GPBValue_Kind_OneOfCase kindOneOfCase;
 
-// Represents a null value.
+/// Represents a null value.
 @property(nonatomic, readwrite) GPBNullValue nullValue;
 
-// Represents a double value.
+/// Represents a double value.
 @property(nonatomic, readwrite) double numberValue;
 
-// Represents a string value.
+/// Represents a string value.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue;
 
-// Represents a boolean value.
+/// Represents a boolean value.
 @property(nonatomic, readwrite) BOOL boolValue;
 
-// Represents a structured value.
+/// Represents a structured value.
 @property(nonatomic, readwrite, strong, null_resettable) GPBStruct *structValue;
 
-// Represents a repeated `Value`.
+/// Represents a repeated `Value`.
 @property(nonatomic, readwrite, strong, null_resettable) GPBListValue *listValue;
 
 @end
 
+/// Fetches the raw value of a @c GPBValue's @c nullValue property, even
+/// if the value was not defined by the enum at the time the code was generated.
 int32_t GPBValue_NullValue_RawValue(GPBValue *message);
+/// Sets the raw value of an @c GPBValue's @c nullValue property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
 void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value);
 
+/// Clears whatever value was set for the oneof 'kind'.
 void GPBValue_ClearKindOneOfCase(GPBValue *message);
 
 #pragma mark - GPBListValue
@@ -129,13 +143,14 @@
   GPBListValue_FieldNumber_ValuesArray = 1,
 };
 
-// `ListValue` is a wrapper around a repeated field of values.
-//
-// The JSON representation for `ListValue` is JSON array.
+/// `ListValue` is a wrapper around a repeated field of values.
+///
+/// The JSON representation for `ListValue` is JSON array.
 @interface GPBListValue : GPBMessage
 
-// Repeated field of dynamically typed values.
+/// Repeated field of dynamically typed values.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBValue*> *valuesArray;
+/// The number of items in @c valuesArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger valuesArray_Count;
 
 @end
diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.h b/objectivec/google/protobuf/Timestamp.pbobjc.h
index 79b24ec..d17c286 100644
--- a/objectivec/google/protobuf/Timestamp.pbobjc.h
+++ b/objectivec/google/protobuf/Timestamp.pbobjc.h
@@ -15,13 +15,15 @@
 
 #pragma mark - GPBTimestampRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBTimestampRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBTimestamp
@@ -31,70 +33,70 @@
   GPBTimestamp_FieldNumber_Nanos = 2,
 };
 
-// A Timestamp represents a point in time independent of any time zone
-// or calendar, represented as seconds and fractions of seconds at
-// nanosecond resolution in UTC Epoch time. It is encoded using the
-// Proleptic Gregorian Calendar which extends the Gregorian calendar
-// backwards to year one. It is encoded assuming all minutes are 60
-// seconds long, i.e. leap seconds are "smeared" so that no leap second
-// table is needed for interpretation. Range is from
-// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
-// By restricting to that range, we ensure that we can convert to
-// and from  RFC 3339 date strings.
-// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
-//
-// Example 1: Compute Timestamp from POSIX `time()`.
-//
-//     Timestamp timestamp;
-//     timestamp.set_seconds(time(NULL));
-//     timestamp.set_nanos(0);
-//
-// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
-//
-//     struct timeval tv;
-//     gettimeofday(&tv, NULL);
-//
-//     Timestamp timestamp;
-//     timestamp.set_seconds(tv.tv_sec);
-//     timestamp.set_nanos(tv.tv_usec * 1000);
-//
-// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
-//
-//     FILETIME ft;
-//     GetSystemTimeAsFileTime(&ft);
-//     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
-//
-//     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
-//     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
-//     Timestamp timestamp;
-//     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
-//     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
-//
-// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
-//
-//     long millis = System.currentTimeMillis();
-//
-//     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
-//         .setNanos((int) ((millis % 1000) * 1000000)).build();
-//
-//
-// Example 5: Compute Timestamp from current time in Python.
-//
-//     now = time.time()
-//     seconds = int(now)
-//     nanos = int((now - seconds) * 10**9)
-//     timestamp = Timestamp(seconds=seconds, nanos=nanos)
+/// A Timestamp represents a point in time independent of any time zone
+/// or calendar, represented as seconds and fractions of seconds at
+/// nanosecond resolution in UTC Epoch time. It is encoded using the
+/// Proleptic Gregorian Calendar which extends the Gregorian calendar
+/// backwards to year one. It is encoded assuming all minutes are 60
+/// seconds long, i.e. leap seconds are "smeared" so that no leap second
+/// table is needed for interpretation. Range is from
+/// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
+/// By restricting to that range, we ensure that we can convert to
+/// and from  RFC 3339 date strings.
+/// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
+///
+/// Example 1: Compute Timestamp from POSIX `time()`.
+///
+///     Timestamp timestamp;
+///     timestamp.set_seconds(time(NULL));
+///     timestamp.set_nanos(0);
+///
+/// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
+///
+///     struct timeval tv;
+///     gettimeofday(&tv, NULL);
+///
+///     Timestamp timestamp;
+///     timestamp.set_seconds(tv.tv_sec);
+///     timestamp.set_nanos(tv.tv_usec * 1000);
+///
+/// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
+///
+///     FILETIME ft;
+///     GetSystemTimeAsFileTime(&ft);
+///     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+///
+///     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
+///     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
+///     Timestamp timestamp;
+///     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
+///     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+///
+/// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
+///
+///     long millis = System.currentTimeMillis();
+///
+///     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
+///         .setNanos((int) ((millis % 1000) * 1000000)).build();
+///
+///
+/// Example 5: Compute Timestamp from current time in Python.
+///
+///     now = time.time()
+///     seconds = int(now)
+///     nanos = int((now - seconds) * 10**9)
+///     timestamp = Timestamp(seconds=seconds, nanos=nanos)
 @interface GPBTimestamp : GPBMessage
 
-// Represents seconds of UTC time since Unix epoch
-// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
-// 9999-12-31T23:59:59Z inclusive.
+/// Represents seconds of UTC time since Unix epoch
+/// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
+/// 9999-12-31T23:59:59Z inclusive.
 @property(nonatomic, readwrite) int64_t seconds;
 
-// Non-negative fractions of a second at nanosecond resolution. Negative
-// second values with fractions must still have non-negative nanos values
-// that count forward in time. Must be from 0 to 999,999,999
-// inclusive.
+/// Non-negative fractions of a second at nanosecond resolution. Negative
+/// second values with fractions must still have non-negative nanos values
+/// that count forward in time. Must be from 0 to 999,999,999
+/// inclusive.
 @property(nonatomic, readwrite) int32_t nanos;
 
 @end
diff --git a/objectivec/google/protobuf/Type.pbobjc.h b/objectivec/google/protobuf/Type.pbobjc.h
index a7d03a2..9301e4f 100644
--- a/objectivec/google/protobuf/Type.pbobjc.h
+++ b/objectivec/google/protobuf/Type.pbobjc.h
@@ -21,118 +21,135 @@
 
 #pragma mark - Enum GPBSyntax
 
-// The syntax in which a protocol buffer element is defined.
+/// The syntax in which a protocol buffer element is defined.
 typedef GPB_ENUM(GPBSyntax) {
+  /// Value used if any message's field encounters a value that is not defined
+  /// by this enum. The message will also have C functions to get/set the rawValue
+  /// of the field.
   GPBSyntax_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
-  // Syntax `proto2`.
+  /// Syntax `proto2`.
   GPBSyntax_SyntaxProto2 = 0,
 
-  // Syntax `proto3`.
+  /// Syntax `proto3`.
   GPBSyntax_SyntaxProto3 = 1,
 };
 
 GPBEnumDescriptor *GPBSyntax_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBSyntax_IsValidValue(int32_t value);
 
 #pragma mark - Enum GPBField_Kind
 
-// Basic field types.
+/// Basic field types.
 typedef GPB_ENUM(GPBField_Kind) {
+  /// Value used if any message's field encounters a value that is not defined
+  /// by this enum. The message will also have C functions to get/set the rawValue
+  /// of the field.
   GPBField_Kind_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
-  // Field type unknown.
+  /// Field type unknown.
   GPBField_Kind_TypeUnknown = 0,
 
-  // Field type double.
+  /// Field type double.
   GPBField_Kind_TypeDouble = 1,
 
-  // Field type float.
+  /// Field type float.
   GPBField_Kind_TypeFloat = 2,
 
-  // Field type int64.
+  /// Field type int64.
   GPBField_Kind_TypeInt64 = 3,
 
-  // Field type uint64.
+  /// Field type uint64.
   GPBField_Kind_TypeUint64 = 4,
 
-  // Field type int32.
+  /// Field type int32.
   GPBField_Kind_TypeInt32 = 5,
 
-  // Field type fixed64.
+  /// Field type fixed64.
   GPBField_Kind_TypeFixed64 = 6,
 
-  // Field type fixed32.
+  /// Field type fixed32.
   GPBField_Kind_TypeFixed32 = 7,
 
-  // Field type bool.
+  /// Field type bool.
   GPBField_Kind_TypeBool = 8,
 
-  // Field type string.
+  /// Field type string.
   GPBField_Kind_TypeString = 9,
 
-  // Field type group. Proto2 syntax only, and deprecated.
+  /// Field type group. Proto2 syntax only, and deprecated.
   GPBField_Kind_TypeGroup = 10,
 
-  // Field type message.
+  /// Field type message.
   GPBField_Kind_TypeMessage = 11,
 
-  // Field type bytes.
+  /// Field type bytes.
   GPBField_Kind_TypeBytes = 12,
 
-  // Field type uint32.
+  /// Field type uint32.
   GPBField_Kind_TypeUint32 = 13,
 
-  // Field type enum.
+  /// Field type enum.
   GPBField_Kind_TypeEnum = 14,
 
-  // Field type sfixed32.
+  /// Field type sfixed32.
   GPBField_Kind_TypeSfixed32 = 15,
 
-  // Field type sfixed64.
+  /// Field type sfixed64.
   GPBField_Kind_TypeSfixed64 = 16,
 
-  // Field type sint32.
+  /// Field type sint32.
   GPBField_Kind_TypeSint32 = 17,
 
-  // Field type sint64.
+  /// Field type sint64.
   GPBField_Kind_TypeSint64 = 18,
 };
 
 GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBField_Kind_IsValidValue(int32_t value);
 
 #pragma mark - Enum GPBField_Cardinality
 
-// Whether a field is optional, required, or repeated.
+/// Whether a field is optional, required, or repeated.
 typedef GPB_ENUM(GPBField_Cardinality) {
+  /// Value used if any message's field encounters a value that is not defined
+  /// by this enum. The message will also have C functions to get/set the rawValue
+  /// of the field.
   GPBField_Cardinality_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
-  // For fields with unknown cardinality.
+  /// For fields with unknown cardinality.
   GPBField_Cardinality_CardinalityUnknown = 0,
 
-  // For optional fields.
+  /// For optional fields.
   GPBField_Cardinality_CardinalityOptional = 1,
 
-  // For required fields. Proto2 syntax only.
+  /// For required fields. Proto2 syntax only.
   GPBField_Cardinality_CardinalityRequired = 2,
 
-  // For repeated fields.
+  /// For repeated fields.
   GPBField_Cardinality_CardinalityRepeated = 3,
 };
 
 GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void);
 
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
 BOOL GPBField_Cardinality_IsValidValue(int32_t value);
 
 #pragma mark - GPBTypeRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBTypeRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBType
@@ -146,34 +163,43 @@
   GPBType_FieldNumber_Syntax = 6,
 };
 
-// A protocol buffer message type.
+/// A protocol buffer message type.
 @interface GPBType : GPBMessage
 
-// The fully qualified message name.
+/// The fully qualified message name.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
 
-// The list of fields.
+/// The list of fields.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBField*> *fieldsArray;
+/// The number of items in @c fieldsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger fieldsArray_Count;
 
-// The list of types appearing in `oneof` definitions in this type.
+/// The list of types appearing in `oneof` definitions in this type.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *oneofsArray;
+/// The number of items in @c oneofsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger oneofsArray_Count;
 
-// The protocol buffer options.
+/// The protocol buffer options.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
-// The source context.
-@property(nonatomic, readwrite) BOOL hasSourceContext;
+/// The source context.
 @property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
 
-// The source syntax.
+/// The source syntax.
 @property(nonatomic, readwrite) GPBSyntax syntax;
 
 @end
 
+/// Fetches the raw value of a @c GPBType's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
 int32_t GPBType_Syntax_RawValue(GPBType *message);
+/// Sets the raw value of an @c GPBType's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
 void SetGPBType_Syntax_RawValue(GPBType *message, int32_t value);
 
 #pragma mark - GPBField
@@ -191,48 +217,59 @@
   GPBField_FieldNumber_DefaultValue = 11,
 };
 
-// A single field of a message type.
+/// A single field of a message type.
 @interface GPBField : GPBMessage
 
-// The field type.
+/// The field type.
 @property(nonatomic, readwrite) GPBField_Kind kind;
 
-// The field cardinality.
+/// The field cardinality.
 @property(nonatomic, readwrite) GPBField_Cardinality cardinality;
 
-// The field number.
+/// The field number.
 @property(nonatomic, readwrite) int32_t number;
 
-// The field name.
+/// The field name.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
 
-// The field type URL, without the scheme, for message or enumeration
-// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
+/// The field type URL, without the scheme, for message or enumeration
+/// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL;
 
-// The index of the field type in `Type.oneofs`, for message or enumeration
-// types. The first type has index 1; zero means the type is not in the list.
+/// The index of the field type in `Type.oneofs`, for message or enumeration
+/// types. The first type has index 1; zero means the type is not in the list.
 @property(nonatomic, readwrite) int32_t oneofIndex;
 
-// Whether to use alternative packed wire representation.
+/// Whether to use alternative packed wire representation.
 @property(nonatomic, readwrite) BOOL packed;
 
-// The protocol buffer options.
+/// The protocol buffer options.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
-// The field JSON name.
+/// The field JSON name.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *jsonName;
 
-// The string value of the default value of this field. Proto2 syntax only.
+/// The string value of the default value of this field. Proto2 syntax only.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *defaultValue;
 
 @end
 
+/// Fetches the raw value of a @c GPBField's @c kind property, even
+/// if the value was not defined by the enum at the time the code was generated.
 int32_t GPBField_Kind_RawValue(GPBField *message);
+/// Sets the raw value of an @c GPBField's @c kind property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
 void SetGPBField_Kind_RawValue(GPBField *message, int32_t value);
 
+/// Fetches the raw value of a @c GPBField's @c cardinality property, even
+/// if the value was not defined by the enum at the time the code was generated.
 int32_t GPBField_Cardinality_RawValue(GPBField *message);
+/// Sets the raw value of an @c GPBField's @c cardinality property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
 void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value);
 
 #pragma mark - GPBEnum
@@ -245,30 +282,38 @@
   GPBEnum_FieldNumber_Syntax = 5,
 };
 
-// Enum type definition.
+/// Enum type definition.
 @interface GPBEnum : GPBMessage
 
-// Enum type name.
+/// Enum type name.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
 
-// Enum value definitions.
+/// Enum value definitions.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBEnumValue*> *enumvalueArray;
+/// The number of items in @c enumvalueArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger enumvalueArray_Count;
 
-// Protocol buffer options.
+/// Protocol buffer options.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
-// The source context.
-@property(nonatomic, readwrite) BOOL hasSourceContext;
+/// The source context.
 @property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
 
-// The source syntax.
+/// The source syntax.
 @property(nonatomic, readwrite) GPBSyntax syntax;
 
 @end
 
+/// Fetches the raw value of a @c GPBEnum's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
 int32_t GPBEnum_Syntax_RawValue(GPBEnum *message);
+/// Sets the raw value of an @c GPBEnum's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
 void SetGPBEnum_Syntax_RawValue(GPBEnum *message, int32_t value);
 
 #pragma mark - GPBEnumValue
@@ -279,17 +324,18 @@
   GPBEnumValue_FieldNumber_OptionsArray = 3,
 };
 
-// Enum value definition.
+/// Enum value definition.
 @interface GPBEnumValue : GPBMessage
 
-// Enum value name.
+/// Enum value name.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
 
-// Enum value number.
+/// Enum value number.
 @property(nonatomic, readwrite) int32_t number;
 
-// Protocol buffer options.
+/// Protocol buffer options.
 @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
 @property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
 @end
@@ -301,16 +347,17 @@
   GPBOption_FieldNumber_Value = 2,
 };
 
-// A protocol buffer option, which can be attached to a message, field,
-// enumeration, etc.
+/// A protocol buffer option, which can be attached to a message, field,
+/// enumeration, etc.
 @interface GPBOption : GPBMessage
 
-// The option's name. For example, `"java_package"`.
+/// The option's name. For example, `"java_package"`.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *name;
 
-// The option's value. For example, `"com.google.protobuf"`.
-@property(nonatomic, readwrite) BOOL hasValue;
+/// The option's value. For example, `"com.google.protobuf"`.
 @property(nonatomic, readwrite, strong, null_resettable) GPBAny *value;
+/// Test to see if @c value has been set.
+@property(nonatomic, readwrite) BOOL hasValue;
 
 @end
 
diff --git a/objectivec/google/protobuf/Wrappers.pbobjc.h b/objectivec/google/protobuf/Wrappers.pbobjc.h
index 580945c..38b9962 100644
--- a/objectivec/google/protobuf/Wrappers.pbobjc.h
+++ b/objectivec/google/protobuf/Wrappers.pbobjc.h
@@ -15,13 +15,15 @@
 
 #pragma mark - GPBWrappersRoot
 
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
 @interface GPBWrappersRoot : GPBRootObject
-
-// The base class provides:
-//   + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
 @end
 
 #pragma mark - GPBDoubleValue
@@ -30,12 +32,12 @@
   GPBDoubleValue_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `double`.
-//
-// The JSON representation for `DoubleValue` is JSON number.
+/// Wrapper message for `double`.
+///
+/// The JSON representation for `DoubleValue` is JSON number.
 @interface GPBDoubleValue : GPBMessage
 
-// The double value.
+/// The double value.
 @property(nonatomic, readwrite) double value;
 
 @end
@@ -46,12 +48,12 @@
   GPBFloatValue_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `float`.
-//
-// The JSON representation for `FloatValue` is JSON number.
+/// Wrapper message for `float`.
+///
+/// The JSON representation for `FloatValue` is JSON number.
 @interface GPBFloatValue : GPBMessage
 
-// The float value.
+/// The float value.
 @property(nonatomic, readwrite) float value;
 
 @end
@@ -62,12 +64,12 @@
   GPBInt64Value_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `int64`.
-//
-// The JSON representation for `Int64Value` is JSON string.
+/// Wrapper message for `int64`.
+///
+/// The JSON representation for `Int64Value` is JSON string.
 @interface GPBInt64Value : GPBMessage
 
-// The int64 value.
+/// The int64 value.
 @property(nonatomic, readwrite) int64_t value;
 
 @end
@@ -78,12 +80,12 @@
   GPBUInt64Value_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `uint64`.
-//
-// The JSON representation for `UInt64Value` is JSON string.
+/// Wrapper message for `uint64`.
+///
+/// The JSON representation for `UInt64Value` is JSON string.
 @interface GPBUInt64Value : GPBMessage
 
-// The uint64 value.
+/// The uint64 value.
 @property(nonatomic, readwrite) uint64_t value;
 
 @end
@@ -94,12 +96,12 @@
   GPBInt32Value_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `int32`.
-//
-// The JSON representation for `Int32Value` is JSON number.
+/// Wrapper message for `int32`.
+///
+/// The JSON representation for `Int32Value` is JSON number.
 @interface GPBInt32Value : GPBMessage
 
-// The int32 value.
+/// The int32 value.
 @property(nonatomic, readwrite) int32_t value;
 
 @end
@@ -110,12 +112,12 @@
   GPBUInt32Value_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `uint32`.
-//
-// The JSON representation for `UInt32Value` is JSON number.
+/// Wrapper message for `uint32`.
+///
+/// The JSON representation for `UInt32Value` is JSON number.
 @interface GPBUInt32Value : GPBMessage
 
-// The uint32 value.
+/// The uint32 value.
 @property(nonatomic, readwrite) uint32_t value;
 
 @end
@@ -126,12 +128,12 @@
   GPBBoolValue_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `bool`.
-//
-// The JSON representation for `BoolValue` is JSON `true` and `false`.
+/// Wrapper message for `bool`.
+///
+/// The JSON representation for `BoolValue` is JSON `true` and `false`.
 @interface GPBBoolValue : GPBMessage
 
-// The bool value.
+/// The bool value.
 @property(nonatomic, readwrite) BOOL value;
 
 @end
@@ -142,12 +144,12 @@
   GPBStringValue_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `string`.
-//
-// The JSON representation for `StringValue` is JSON string.
+/// Wrapper message for `string`.
+///
+/// The JSON representation for `StringValue` is JSON string.
 @interface GPBStringValue : GPBMessage
 
-// The string value.
+/// The string value.
 @property(nonatomic, readwrite, copy, null_resettable) NSString *value;
 
 @end
@@ -158,12 +160,12 @@
   GPBBytesValue_FieldNumber_Value = 1,
 };
 
-// Wrapper message for `bytes`.
-//
-// The JSON representation for `BytesValue` is JSON string.
+/// Wrapper message for `bytes`.
+///
+/// The JSON representation for `BytesValue` is JSON string.
 @interface GPBBytesValue : GPBMessage
 
-// The bytes value.
+/// The bytes value.
 @property(nonatomic, readwrite, copy, null_resettable) NSData *value;
 
 @end
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index 5d24419..fcb1734 100755
--- a/python/google/protobuf/__init__.py
+++ b/python/google/protobuf/__init__.py
@@ -30,7 +30,7 @@
 
 # Copyright 2007 Google Inc. All Rights Reserved.
 
-__version__ = '3.0.0b2'
+__version__ = '3.0.0b2.post2'
 
 if __name__ != '__main__':
   try:
diff --git a/python/setup.py b/python/setup.py
index 24ac53d..6ea3bad 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -210,6 +210,7 @@
         "Programming Language :: Python :: 3.3",
         "Programming Language :: Python :: 3.4",
         ],
+      namespace_packages=['google'],
       packages=find_packages(
           exclude=[
               'import_test_package',
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
index d6f01c6..857d24a 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
@@ -80,10 +80,12 @@
   if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
     // Include the unknown value.
     printer->Print(
+      "/// Value used if any message's field encounters a value that is not defined\n"
+      "/// by this enum. The message will also have C functions to get/set the rawValue\n"
+      "/// of the field.\n"
       "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n",
       "name", name_);
   }
-
   for (int i = 0; i < all_values_.size(); i++) {
     SourceLocation location;
     if (all_values_[i]->GetSourceLocation(&location)) {
@@ -107,6 +109,8 @@
       "\n"
       "GPBEnumDescriptor *$name$_EnumDescriptor(void);\n"
       "\n"
+      "/// Checks to see if the given value is defined by the enum or was not known at\n"
+      "/// the time this source was generated.\n"
       "BOOL $name$_IsValidValue(int32_t value);\n"
       "\n",
       "name", name_);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
index ecc77f6..cfbb8c5 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
@@ -87,7 +87,12 @@
 
   printer->Print(
       variables_,
+      "/// Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n"
+      "/// if the value was not defined by the enum at the time the code was generated.\n"
       "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message);\n"
+      "/// Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n"
+      "/// it to be set to a value that was not defined by the enum at the time the code\n"
+      "/// was generated.\n"
       "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value);\n"
       "\n");
 }
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
index 0934182..8697e22 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
@@ -270,15 +270,15 @@
 void SingleFieldGenerator::GeneratePropertyDeclaration(
     io::Printer* printer) const {
   printer->Print(variables_, "$comments$");
+  printer->Print(
+      variables_,
+      "@property(nonatomic, readwrite) $property_type$ $name$;\n"
+      "\n");
   if (WantsHasProperty()) {
     printer->Print(
         variables_,
         "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n");
   }
-  printer->Print(
-      variables_,
-      "@property(nonatomic, readwrite) $property_type$ $name$;\n"
-      "\n");
 }
 
 void SingleFieldGenerator::GeneratePropertyImplementation(
@@ -326,14 +326,15 @@
   // conventions (init*, new*, etc.)
 
   printer->Print(variables_, "$comments$");
-  if (WantsHasProperty()) {
-    printer->Print(
-        variables_,
-        "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n");
-  }
   printer->Print(
       variables_,
       "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$;\n");
+  if (WantsHasProperty()) {
+    printer->Print(
+        variables_,
+        "/// Test to see if @c $name$ has been set.\n"
+        "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n");
+  }
   if (IsInitName(variables_.find("name")->second)) {
     // If property name starts with init we need to annotate it to get past ARC.
     // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
@@ -385,6 +386,7 @@
       "$comments$"
       "$array_comment$"
       "@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$;\n"
+      "/// The number of items in @c $name$ without causing the array to be created.\n"
       "@property(nonatomic, readonly) NSUInteger $name$_Count;\n");
   if (IsInitName(variables_.find("name")->second)) {
     // If property name starts with init we need to annotate it to get past ARC.
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
index cdf9ebb..1619988 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
@@ -151,13 +151,15 @@
   printer->Print(
       "#pragma mark - $root_class_name$\n"
       "\n"
+      "/// Exposes the extension registry for this file.\n"
+      "///\n"
+      "/// The base class provides:\n"
+      "/// @code\n"
+      "///   + (GPBExtensionRegistry *)extensionRegistry;\n"
+      "/// @endcode\n"
+      "/// which is a @c GPBExtensionRegistry that includes all the extensions defined by\n"
+      "/// this file and all files that it depends on.\n"
       "@interface $root_class_name$ : GPBRootObject\n"
-      "\n"
-      "// The base class provides:\n"
-      "//   + (GPBExtensionRegistry *)extensionRegistry;\n"
-      "// which is an GPBExtensionRegistry that includes all the extensions defined by\n"
-      "// this file and all files that it depends on.\n"
-      "\n"
       "@end\n"
       "\n",
       "root_class_name", root_class_name_);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 77a378c..613a511 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -124,9 +124,14 @@
   }
   values.push_back(current);
 
+  string result;
+  bool first_segment_forces_upper = false;
   for (vector<string>::iterator i = values.begin(); i != values.end(); ++i) {
     string value = *i;
     bool all_upper = (kUpperSegments.count(value) > 0);
+    if (all_upper && (result.length() == 0)) {
+      first_segment_forces_upper = true;
+    }
     for (int j = 0; j < value.length(); j++) {
       if (j == 0 || all_upper) {
         value[j] = ascii_toupper(value[j]);
@@ -134,13 +139,11 @@
         // Nothing, already in lower.
       }
     }
-    *i = value;
+    result += value;
   }
-  string result;
-  for (vector<string>::iterator i = values.begin(); i != values.end(); ++i) {
-    result += *i;
-  }
-  if ((result.length() != 0) && !first_capitalized) {
+  if ((result.length() != 0) &&
+      !first_capitalized &&
+      !first_segment_forces_upper) {
     result[0] = ascii_tolower(result[0]);
   }
   return result;
@@ -771,16 +774,14 @@
   while (!lines.empty() && lines.back().empty()) {
     lines.pop_back();
   }
-  string prefix("//");
+  string prefix("///");
   string suffix("\n");
   string final_comments;
   for (int i = 0; i < lines.size(); i++) {
-    // We use $ for delimiters, so replace comments with dollars with
-    // html escaped version.
-    // None of the other compilers handle this (as of this writing) but we
-    // ran into it once, so just to be safe.
+    // HeaderDoc uses '\' and '@' for markers; escape them.
+    const string line = StringReplace(lines[i], "\\", "\\\\", true);
     final_comments +=
-        prefix + StringReplace(lines[i], "$", "&#36;", true) + suffix;
+        prefix + StringReplace(line, "@", "\\@", true) + suffix;
   }
   return final_comments;
 }
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
index 5b2dd19..a301493 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -146,6 +146,7 @@
 
 string BuildFlagsString(const vector<string>& strings);
 
+// Builds a HeaderDoc style comment out of the comments in the .proto file.
 string BuildCommentsString(const SourceLocation& location);
 
 // Checks the prefix for a given file and outputs any warnings needed, if
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
index 3cb8748..24e6df0 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
@@ -104,6 +104,7 @@
 void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) {
   printer->Print(
       variables_,
+      "/// Clears whatever value was set for the oneof '$name$'.\n"
       "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n");
 }