Explorar o código

line-ending-to-crlf

csharptest %!s(int64=14) %!d(string=hai) anos
pai
achega
d965c666ec
Modificáronse 25 ficheiros con 6794 adicións e 6794 borrados
  1. 71 71
      src/ProtocolBuffers/RpcUtil.cs
  2. 52 52
      src/ProtocolBuffers/SilverlightCompatibility.cs
  3. 171 171
      src/ProtocolBuffers/SortedList.cs
  4. 683 683
      src/ProtocolBuffers/TextFormat.cs
  5. 143 143
      src/ProtocolBuffers/TextGenerator.cs
  6. 412 412
      src/ProtocolBuffers/TextTokenizer.cs
  7. 73 73
      src/ProtocolBuffers/ThrowHelper.cs
  8. 170 170
      src/ProtocolBuffers/UninitializedMessageException.cs
  9. 371 371
      src/ProtocolBuffers/UnknownField.cs
  10. 768 768
      src/ProtocolBuffers/UnknownFieldSet.cs
  11. 171 171
      src/ProtocolBuffers/WireFormat.cs
  12. 268 268
      src/ProtocolBuffersLite.Test/AbstractBuilderLiteTest.cs
  13. 126 126
      src/ProtocolBuffersLite.Test/AbstractMessageLiteTest.cs
  14. 267 267
      src/ProtocolBuffersLite.Test/ExtendableBuilderLiteTest.cs
  15. 304 304
      src/ProtocolBuffersLite.Test/ExtendableMessageLiteTest.cs
  16. 162 162
      src/ProtocolBuffersLite.Test/InteropLiteTest.cs
  17. 111 111
      src/ProtocolBuffersLite.Test/LiteTest.cs
  18. 218 218
      src/ProtocolBuffersLite.Test/MissingFieldAndExtensionTest.cs
  19. 83 83
      src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj
  20. 88 88
      src/ProtocolBuffersLite.Test/ProtocolBuffersLiteMixed.Test.csproj
  21. 113 113
      src/ProtocolBuffersLite.Test/TestLiteByApi.cs
  22. 1721 1721
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs
  23. 116 116
      testdata/text_format_unittest_data.txt
  24. 116 116
      testdata/text_format_unittest_extensions_data.txt
  25. 16 16
      todo.txt

+ 71 - 71
src/ProtocolBuffers/RpcUtil.cs

@@ -1,71 +1,71 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Grab-bag of utility functions useful when dealing with RPCs.
-  /// </summary>
-  public static class RpcUtil {
-
-    /// <summary>
-    /// Converts an Action[IMessage] to an Action[T].
-    /// </summary>
-    public static Action<T> SpecializeCallback<T>(Action<IMessage> action) 
-        where T : IMessage<T> {
-      return message => action(message);
-    }
-
-    /// <summary>
-    /// Converts an Action[T] to an Action[IMessage].
-    /// The generalized action will accept any message object which has
-    /// the same descriptor, and will convert it to the correct class
-    /// before calling the original action. However, if the generalized
-    /// callback is given a message with a different descriptor, an
-    /// exception will be thrown.
-    /// </summary>
-    public static Action<IMessage> GeneralizeCallback<TMessage, TBuilder>(Action<TMessage> action, TMessage defaultInstance)
-        where TMessage : class, IMessage<TMessage, TBuilder> 
-        where TBuilder : IBuilder<TMessage, TBuilder> {
-      return message => {
-        TMessage castMessage = message as TMessage;
-        if (castMessage == null) {  
-          castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build();
-        }
-        action(castMessage);
-      };
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Grab-bag of utility functions useful when dealing with RPCs.
+  /// </summary>
+  public static class RpcUtil {
+
+    /// <summary>
+    /// Converts an Action[IMessage] to an Action[T].
+    /// </summary>
+    public static Action<T> SpecializeCallback<T>(Action<IMessage> action) 
+        where T : IMessage<T> {
+      return message => action(message);
+    }
+
+    /// <summary>
+    /// Converts an Action[T] to an Action[IMessage].
+    /// The generalized action will accept any message object which has
+    /// the same descriptor, and will convert it to the correct class
+    /// before calling the original action. However, if the generalized
+    /// callback is given a message with a different descriptor, an
+    /// exception will be thrown.
+    /// </summary>
+    public static Action<IMessage> GeneralizeCallback<TMessage, TBuilder>(Action<TMessage> action, TMessage defaultInstance)
+        where TMessage : class, IMessage<TMessage, TBuilder> 
+        where TBuilder : IBuilder<TMessage, TBuilder> {
+      return message => {
+        TMessage castMessage = message as TMessage;
+        if (castMessage == null) {  
+          castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build();
+        }
+        action(castMessage);
+      };
+    }
+  }
+}

+ 52 - 52
src/ProtocolBuffers/SilverlightCompatibility.cs

@@ -1,52 +1,52 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System.Text.RegularExpressions;
-
-namespace Google.ProtocolBuffers
-{
-    /// <summary>
-    /// Class containing helpful workarounds for Silverlight compatibility
-    /// </summary>
-    internal static class SilverlightCompatibility
-    {
-
-#if SILVERLIGHT2
-        internal const RegexOptions CompiledRegexWhereAvailable = RegexOptions.None;
-#else
-        internal const RegexOptions CompiledRegexWhereAvailable = RegexOptions.Compiled;
-#endif
-
-    }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System.Text.RegularExpressions;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Class containing helpful workarounds for Silverlight compatibility
+    /// </summary>
+    internal static class SilverlightCompatibility
+    {
+
+#if SILVERLIGHT2
+        internal const RegexOptions CompiledRegexWhereAvailable = RegexOptions.None;
+#else
+        internal const RegexOptions CompiledRegexWhereAvailable = RegexOptions.Compiled;
+#endif
+
+    }
+}

+ 171 - 171
src/ProtocolBuffers/SortedList.cs

@@ -1,172 +1,172 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-#if SILVERLIGHT2
-using System.Collections;
-using System.Collections.Generic;
-
-namespace Google.ProtocolBuffers
-{
-    /// <summary>
-    /// Dictionary implementation which always yields keys in sorted order.
-    /// This is not particularly efficient: it wraps a normal dictionary
-    /// for most operations, but sorts by key when either iterating or
-    /// fetching the Keys/Values properties.
-    /// This is only used for Silverlight, which doesn't have the normal
-    /// sorted collections.
-    /// </summary>
-    internal sealed class SortedList<TKey, TValue> : IDictionary<TKey, TValue>
-    {
-        private readonly IDictionary<TKey, TValue> wrapped = new Dictionary<TKey, TValue>();
-
-        public SortedList()
-        {
-        }
-
-        public SortedList(IDictionary<TKey, TValue> dictionary)
-        {
-            foreach (KeyValuePair<TKey, TValue> entry in dictionary)
-            {
-                Add(entry.Key, entry.Value);
-            }
-        }
-
-        public void Add(TKey key, TValue value)
-        {
-            wrapped.Add(key, value);
-        }
-
-        public bool ContainsKey(TKey key)
-        {
-            return wrapped.ContainsKey(key);
-        }
-
-        public ICollection<TKey> Keys
-        {
-            get
-            {
-                List<TKey> keys = new List<TKey>(wrapped.Count);
-                foreach (var pair in this)
-                {
-                    keys.Add(pair.Key);
-                }
-                return keys;
-            }
-        }
-
-        public bool Remove(TKey key)
-        {
-            return wrapped.Remove(key);
-        }
-
-        public bool TryGetValue(TKey key, out TValue value)
-        {
-            return wrapped.TryGetValue(key, out value);
-        }
-
-        public ICollection<TValue> Values
-        {
-            get
-            {
-                List<TValue> values = new List<TValue>(wrapped.Count);
-                foreach (var pair in this)
-                {
-                    values.Add(pair.Value);
-                }
-                return values;
-            }
-        }
-
-        public TValue this[TKey key]
-        {
-            get
-            {
-                return wrapped[key];
-            }
-            set
-            {
-                wrapped[key] = value;
-            }
-        }
-
-        public void Add(KeyValuePair<TKey, TValue> item)
-        {
-            wrapped.Add(item);
-        }
-
-        public void Clear()
-        {
-            wrapped.Clear();
-        }
-
-        public bool Contains(KeyValuePair<TKey, TValue> item)
-        {
-            return wrapped.Contains(item);
-        }
-
-        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
-        {
-            wrapped.CopyTo(array, arrayIndex);
-        }
-
-        public int Count
-        {
-            get { return wrapped.Count; }
-        }
-
-        public bool IsReadOnly
-        {
-            get { return wrapped.IsReadOnly; }
-        }
-
-        public bool Remove(KeyValuePair<TKey, TValue> item)
-        {
-            return wrapped.Remove(item);
-        }
-
-        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
-        {
-            IComparer<TKey> comparer = Comparer<TKey>.Default;
-            var list = new List<KeyValuePair<TKey, TValue>>(wrapped);
-            list.Sort((x, y) => comparer.Compare(x.Key, y.Key));
-            return list.GetEnumerator();
-        }
-
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return GetEnumerator();
-        }
-    }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+#if SILVERLIGHT2
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Dictionary implementation which always yields keys in sorted order.
+    /// This is not particularly efficient: it wraps a normal dictionary
+    /// for most operations, but sorts by key when either iterating or
+    /// fetching the Keys/Values properties.
+    /// This is only used for Silverlight, which doesn't have the normal
+    /// sorted collections.
+    /// </summary>
+    internal sealed class SortedList<TKey, TValue> : IDictionary<TKey, TValue>
+    {
+        private readonly IDictionary<TKey, TValue> wrapped = new Dictionary<TKey, TValue>();
+
+        public SortedList()
+        {
+        }
+
+        public SortedList(IDictionary<TKey, TValue> dictionary)
+        {
+            foreach (KeyValuePair<TKey, TValue> entry in dictionary)
+            {
+                Add(entry.Key, entry.Value);
+            }
+        }
+
+        public void Add(TKey key, TValue value)
+        {
+            wrapped.Add(key, value);
+        }
+
+        public bool ContainsKey(TKey key)
+        {
+            return wrapped.ContainsKey(key);
+        }
+
+        public ICollection<TKey> Keys
+        {
+            get
+            {
+                List<TKey> keys = new List<TKey>(wrapped.Count);
+                foreach (var pair in this)
+                {
+                    keys.Add(pair.Key);
+                }
+                return keys;
+            }
+        }
+
+        public bool Remove(TKey key)
+        {
+            return wrapped.Remove(key);
+        }
+
+        public bool TryGetValue(TKey key, out TValue value)
+        {
+            return wrapped.TryGetValue(key, out value);
+        }
+
+        public ICollection<TValue> Values
+        {
+            get
+            {
+                List<TValue> values = new List<TValue>(wrapped.Count);
+                foreach (var pair in this)
+                {
+                    values.Add(pair.Value);
+                }
+                return values;
+            }
+        }
+
+        public TValue this[TKey key]
+        {
+            get
+            {
+                return wrapped[key];
+            }
+            set
+            {
+                wrapped[key] = value;
+            }
+        }
+
+        public void Add(KeyValuePair<TKey, TValue> item)
+        {
+            wrapped.Add(item);
+        }
+
+        public void Clear()
+        {
+            wrapped.Clear();
+        }
+
+        public bool Contains(KeyValuePair<TKey, TValue> item)
+        {
+            return wrapped.Contains(item);
+        }
+
+        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+        {
+            wrapped.CopyTo(array, arrayIndex);
+        }
+
+        public int Count
+        {
+            get { return wrapped.Count; }
+        }
+
+        public bool IsReadOnly
+        {
+            get { return wrapped.IsReadOnly; }
+        }
+
+        public bool Remove(KeyValuePair<TKey, TValue> item)
+        {
+            return wrapped.Remove(item);
+        }
+
+        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+        {
+            IComparer<TKey> comparer = Comparer<TKey>.Default;
+            var list = new List<KeyValuePair<TKey, TValue>>(wrapped);
+            list.Sort((x, y) => comparer.Compare(x.Key, y.Key));
+            return list.GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+    }
+}
 #endif

+ 683 - 683
src/ProtocolBuffers/TextFormat.cs

@@ -1,685 +1,685 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Text;
-using Google.ProtocolBuffers.Descriptors;
-using System.Collections;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Provides ASCII text formatting support for messages.
-  /// TODO(jonskeet): Support for alternative line endings.
-  /// (Easy to print, via TextGenerator. Not sure about parsing.)
-  /// </summary>
-  public static class TextFormat {
-
-    /// <summary>
-    /// Outputs a textual representation of the Protocol Message supplied into
-    /// the parameter output.
-    /// </summary>
-    public static void Print(IMessage message, TextWriter output) {
-      TextGenerator generator = new TextGenerator(output, "\n");
-      Print(message, generator);
-    }
-
-    /// <summary>
-    /// Outputs a textual representation of <paramref name="fields" /> to <paramref name="output"/>.
-    /// </summary>
-    public static void Print(UnknownFieldSet fields, TextWriter output) {
-      TextGenerator generator = new TextGenerator(output, "\n");
-      PrintUnknownFields(fields, generator);
-    }
-
-    public static string PrintToString(IMessage message) {
-      StringWriter text = new StringWriter();
-      Print(message, text);
-      return text.ToString();
-    }
-
-    public static string PrintToString(UnknownFieldSet fields) {
-      StringWriter text = new StringWriter();
-      Print(fields, text);
-      return text.ToString();
-    }
-
-    private static void Print(IMessage message, TextGenerator generator) {
-      foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) {
-        PrintField(entry.Key, entry.Value, generator);
-      }
-      PrintUnknownFields(message.UnknownFields, generator);
-    }
-
-    internal static void PrintField(FieldDescriptor field, object value, TextGenerator generator) {
-      if (field.IsRepeated) {
-        // Repeated field.  Print each element.
-        foreach (object element in (IEnumerable) value) {
-          PrintSingleField(field, element, generator);
-        }
-      } else {
-        PrintSingleField(field, value, generator);
-      }
-    }
-
-    private static void PrintSingleField(FieldDescriptor field, Object value, TextGenerator generator) {
-      if (field.IsExtension) {
-        generator.Print("[");
-        // We special-case MessageSet elements for compatibility with proto1.
-        if (field.ContainingType.Options.MessageSetWireFormat
-            && field.FieldType == FieldType.Message
-            && field.IsOptional
-            // object equality (TODO(jonskeet): Work out what this comment means!)
-            && field.ExtensionScope == field.MessageType) {
-          generator.Print(field.MessageType.FullName);
-        } else {
-          generator.Print(field.FullName);
-        }
-        generator.Print("]");
-      } else {
-        if (field.FieldType == FieldType.Group) {
-          // Groups must be serialized with their original capitalization.
-          generator.Print(field.MessageType.Name);
-        } else {
-          generator.Print(field.Name);
-        }
-      }
-
-      if (field.MappedType == MappedType.Message) {
-        generator.Print(" {\n");
-        generator.Indent();
-      } else {
-        generator.Print(": ");
-      }
-
-      PrintFieldValue(field, value, generator);
-
-      if (field.MappedType == MappedType.Message) {
-        generator.Outdent();
-        generator.Print("}");
-      }
-      generator.Print("\n");
-    }
-
-    private static void PrintFieldValue(FieldDescriptor field, object value, TextGenerator generator) {
-      switch (field.FieldType) {
-        case FieldType.Int32:
-        case FieldType.Int64:
-        case FieldType.SInt32:
-        case FieldType.SInt64:
-        case FieldType.SFixed32:
-        case FieldType.SFixed64:
-        case FieldType.Float:
-        case FieldType.Double:
-        case FieldType.UInt32:
-        case FieldType.UInt64:
-        case FieldType.Fixed32:
-        case FieldType.Fixed64:
-          // The simple Object.ToString converts using the current culture.
-          // We want to always use the invariant culture so it's predictable.
-          generator.Print(((IConvertible) value).ToString(CultureInfo.InvariantCulture));
-          break;
-        case FieldType.Bool:
-          // Explicitly use the Java true/false
-          generator.Print((bool) value ? "true" : "false");
-          break;
-
-        case FieldType.String:
-          generator.Print("\"");
-          generator.Print(EscapeText((string) value));
-          generator.Print("\"");
-          break;
-
-        case FieldType.Bytes: {
-          generator.Print("\"");
-          generator.Print(EscapeBytes((ByteString) value));
-          generator.Print("\"");
-          break;
-        }
-
-        case FieldType.Enum: {
-          if (value is IEnumLite && !(value is EnumValueDescriptor)) {
-            throw new NotSupportedException("Lite enumerations are not supported.");
-          }
-          generator.Print(((EnumValueDescriptor)value).Name);
-          break;
-        }
-
-        case FieldType.Message:
-        case FieldType.Group:
-          if (value is IMessageLite && !(value is IMessage)) {
-            throw new NotSupportedException("Lite messages are not supported.");
-          }
-          Print((IMessage)value, generator);
-          break;
-      }
-    }
-
-    private static void PrintUnknownFields(UnknownFieldSet unknownFields, TextGenerator generator) {
-      foreach (KeyValuePair<int, UnknownField> entry in unknownFields.FieldDictionary) {
-        String prefix = entry.Key.ToString() + ": ";
-        UnknownField field = entry.Value;
-
-        foreach (ulong value in field.VarintList) {
-          generator.Print(prefix);
-          generator.Print(value.ToString());
-          generator.Print("\n");
-        }
-        foreach (uint value in field.Fixed32List) {
-          generator.Print(prefix);
-          generator.Print(string.Format("0x{0:x8}", value));
-          generator.Print("\n");
-        }
-        foreach (ulong value in field.Fixed64List) {
-          generator.Print(prefix);
-          generator.Print(string.Format("0x{0:x16}", value));
-          generator.Print("\n");
-        }
-        foreach (ByteString value in field.LengthDelimitedList) {
-          generator.Print(entry.Key.ToString());
-          generator.Print(": \"");
-          generator.Print(EscapeBytes(value));
-          generator.Print("\"\n");
-        }
-        foreach (UnknownFieldSet value in field.GroupList) {
-          generator.Print(entry.Key.ToString());
-          generator.Print(" {\n");
-          generator.Indent();
-          PrintUnknownFields(value, generator);
-          generator.Outdent();
-          generator.Print("}\n");
-        }
-      }
-    }
-
-    [CLSCompliant(false)]
-    public static ulong ParseUInt64(string text) {
-      return (ulong) ParseInteger(text, false, true);
-    }
-
-    public static long ParseInt64(string text) {
-      return ParseInteger(text, true, true);
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using Google.ProtocolBuffers.Descriptors;
+using System.Collections;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Provides ASCII text formatting support for messages.
+  /// TODO(jonskeet): Support for alternative line endings.
+  /// (Easy to print, via TextGenerator. Not sure about parsing.)
+  /// </summary>
+  public static class TextFormat {
+
+    /// <summary>
+    /// Outputs a textual representation of the Protocol Message supplied into
+    /// the parameter output.
+    /// </summary>
+    public static void Print(IMessage message, TextWriter output) {
+      TextGenerator generator = new TextGenerator(output, "\n");
+      Print(message, generator);
+    }
+
+    /// <summary>
+    /// Outputs a textual representation of <paramref name="fields" /> to <paramref name="output"/>.
+    /// </summary>
+    public static void Print(UnknownFieldSet fields, TextWriter output) {
+      TextGenerator generator = new TextGenerator(output, "\n");
+      PrintUnknownFields(fields, generator);
+    }
+
+    public static string PrintToString(IMessage message) {
+      StringWriter text = new StringWriter();
+      Print(message, text);
+      return text.ToString();
+    }
+
+    public static string PrintToString(UnknownFieldSet fields) {
+      StringWriter text = new StringWriter();
+      Print(fields, text);
+      return text.ToString();
+    }
+
+    private static void Print(IMessage message, TextGenerator generator) {
+      foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) {
+        PrintField(entry.Key, entry.Value, generator);
+      }
+      PrintUnknownFields(message.UnknownFields, generator);
+    }
+
+    internal static void PrintField(FieldDescriptor field, object value, TextGenerator generator) {
+      if (field.IsRepeated) {
+        // Repeated field.  Print each element.
+        foreach (object element in (IEnumerable) value) {
+          PrintSingleField(field, element, generator);
+        }
+      } else {
+        PrintSingleField(field, value, generator);
+      }
+    }
+
+    private static void PrintSingleField(FieldDescriptor field, Object value, TextGenerator generator) {
+      if (field.IsExtension) {
+        generator.Print("[");
+        // We special-case MessageSet elements for compatibility with proto1.
+        if (field.ContainingType.Options.MessageSetWireFormat
+            && field.FieldType == FieldType.Message
+            && field.IsOptional
+            // object equality (TODO(jonskeet): Work out what this comment means!)
+            && field.ExtensionScope == field.MessageType) {
+          generator.Print(field.MessageType.FullName);
+        } else {
+          generator.Print(field.FullName);
+        }
+        generator.Print("]");
+      } else {
+        if (field.FieldType == FieldType.Group) {
+          // Groups must be serialized with their original capitalization.
+          generator.Print(field.MessageType.Name);
+        } else {
+          generator.Print(field.Name);
+        }
+      }
+
+      if (field.MappedType == MappedType.Message) {
+        generator.Print(" {\n");
+        generator.Indent();
+      } else {
+        generator.Print(": ");
+      }
+
+      PrintFieldValue(field, value, generator);
+
+      if (field.MappedType == MappedType.Message) {
+        generator.Outdent();
+        generator.Print("}");
+      }
+      generator.Print("\n");
+    }
+
+    private static void PrintFieldValue(FieldDescriptor field, object value, TextGenerator generator) {
+      switch (field.FieldType) {
+        case FieldType.Int32:
+        case FieldType.Int64:
+        case FieldType.SInt32:
+        case FieldType.SInt64:
+        case FieldType.SFixed32:
+        case FieldType.SFixed64:
+        case FieldType.Float:
+        case FieldType.Double:
+        case FieldType.UInt32:
+        case FieldType.UInt64:
+        case FieldType.Fixed32:
+        case FieldType.Fixed64:
+          // The simple Object.ToString converts using the current culture.
+          // We want to always use the invariant culture so it's predictable.
+          generator.Print(((IConvertible) value).ToString(CultureInfo.InvariantCulture));
+          break;
+        case FieldType.Bool:
+          // Explicitly use the Java true/false
+          generator.Print((bool) value ? "true" : "false");
+          break;
+
+        case FieldType.String:
+          generator.Print("\"");
+          generator.Print(EscapeText((string) value));
+          generator.Print("\"");
+          break;
+
+        case FieldType.Bytes: {
+          generator.Print("\"");
+          generator.Print(EscapeBytes((ByteString) value));
+          generator.Print("\"");
+          break;
+        }
+
+        case FieldType.Enum: {
+          if (value is IEnumLite && !(value is EnumValueDescriptor)) {
+            throw new NotSupportedException("Lite enumerations are not supported.");
+          }
+          generator.Print(((EnumValueDescriptor)value).Name);
+          break;
+        }
+
+        case FieldType.Message:
+        case FieldType.Group:
+          if (value is IMessageLite && !(value is IMessage)) {
+            throw new NotSupportedException("Lite messages are not supported.");
+          }
+          Print((IMessage)value, generator);
+          break;
+      }
+    }
+
+    private static void PrintUnknownFields(UnknownFieldSet unknownFields, TextGenerator generator) {
+      foreach (KeyValuePair<int, UnknownField> entry in unknownFields.FieldDictionary) {
+        String prefix = entry.Key.ToString() + ": ";
+        UnknownField field = entry.Value;
+
+        foreach (ulong value in field.VarintList) {
+          generator.Print(prefix);
+          generator.Print(value.ToString());
+          generator.Print("\n");
+        }
+        foreach (uint value in field.Fixed32List) {
+          generator.Print(prefix);
+          generator.Print(string.Format("0x{0:x8}", value));
+          generator.Print("\n");
+        }
+        foreach (ulong value in field.Fixed64List) {
+          generator.Print(prefix);
+          generator.Print(string.Format("0x{0:x16}", value));
+          generator.Print("\n");
+        }
+        foreach (ByteString value in field.LengthDelimitedList) {
+          generator.Print(entry.Key.ToString());
+          generator.Print(": \"");
+          generator.Print(EscapeBytes(value));
+          generator.Print("\"\n");
+        }
+        foreach (UnknownFieldSet value in field.GroupList) {
+          generator.Print(entry.Key.ToString());
+          generator.Print(" {\n");
+          generator.Indent();
+          PrintUnknownFields(value, generator);
+          generator.Outdent();
+          generator.Print("}\n");
+        }
+      }
+    }
+
+    [CLSCompliant(false)]
+    public static ulong ParseUInt64(string text) {
+      return (ulong) ParseInteger(text, false, true);
+    }
+
+    public static long ParseInt64(string text) {
+      return ParseInteger(text, true, true);
+    }
+
+    [CLSCompliant(false)]
+    public static uint ParseUInt32(string text) {
+      return (uint) ParseInteger(text, false, false);
+    }
+
+    public static int ParseInt32(string text) {
+      return (int) ParseInteger(text, true, false);
+    }
+
+    public static float ParseFloat(string text) {
+      switch (text) {
+        case "-inf":
+        case "-infinity":
+        case "-inff":
+        case "-infinityf":
+          return float.NegativeInfinity;
+        case "inf":
+        case "infinity":
+        case "inff":
+        case "infinityf":
+          return float.PositiveInfinity;
+        case "nan":
+        case "nanf":
+          return float.NaN;
+        default:
+          return float.Parse(text, CultureInfo.InvariantCulture);
+      }
+    }
+
+    public static double ParseDouble(string text) {
+      switch (text) {
+        case "-inf":
+        case "-infinity":
+          return double.NegativeInfinity;
+        case "inf":
+        case "infinity":
+          return double.PositiveInfinity;
+        case "nan":
+          return double.NaN;
+        default:
+          return double.Parse(text, CultureInfo.InvariantCulture);
+      }
+    }
+    
+    /// <summary>
+    /// Parses an integer in hex (leading 0x), decimal (no prefix) or octal (leading 0).
+    /// Only a negative sign is permitted, and it must come before the radix indicator.
+    /// </summary>
+    private static long ParseInteger(string text, bool isSigned, bool isLong) {
+      string original = text;
+      bool negative = false;
+      if (text.StartsWith("-")) {
+        if (!isSigned) {
+          throw new FormatException("Number must be positive: " + original);
+        }
+        negative = true;
+        text = text.Substring(1);
+      }
+
+      int radix = 10;
+      if (text.StartsWith("0x")) {
+        radix = 16;
+        text = text.Substring(2);
+      } else if (text.StartsWith("0")) {
+        radix = 8;
+      }
+
+      ulong result;
+      try {
+        // Workaround for https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278448
+        // We should be able to use Convert.ToUInt64 for all cases.
+        result = radix == 10 ? ulong.Parse(text) : Convert.ToUInt64(text, radix);
+      } catch (OverflowException) {
+        // Convert OverflowException to FormatException so there's a single exception type this method can throw.
+        string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32, isSigned ? "" : "un");
+        throw new FormatException("Number out of range for " + numberDescription + ": " + original);
+      }
+
+      if (negative) {
+        ulong max = isLong ? 0x8000000000000000UL : 0x80000000L;
+        if (result > max) {
+          string numberDescription = string.Format("{0}-bit signed integer", isLong ? 64 : 32);
+          throw new FormatException("Number out of range for " + numberDescription + ": " + original);
+        }
+        return -((long) result);
+      } else {
+        ulong max = isSigned 
+            ? (isLong ? (ulong) long.MaxValue : int.MaxValue)
+            : (isLong ? ulong.MaxValue : uint.MaxValue);
+        if (result > max) {
+          string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32, isSigned ? "" : "un");
+          throw new FormatException("Number out of range for " + numberDescription + ": " + original);
+        }
+        return (long) result;
+      }
+    }
+
+    /// <summary>
+    /// Tests a character to see if it's an octal digit.
+    /// </summary>
+    private static bool IsOctal(char c) {
+      return '0' <= c && c <= '7';
+    }
+
+    /// <summary>
+    /// Tests a character to see if it's a hex digit.
+    /// </summary>
+    private static bool IsHex(char c) {
+      return ('0' <= c && c <= '9') ||
+             ('a' <= c && c <= 'f') ||
+             ('A' <= c && c <= 'F');
+    }
+
+    /// <summary>
+    /// Interprets a character as a digit (in any base up to 36) and returns the
+    /// numeric value.
+    /// </summary>
+    private static int ParseDigit(char c) {
+      if ('0' <= c && c <= '9') {
+        return c - '0';
+      } else if ('a' <= c && c <= 'z') {
+        return c - 'a' + 10;
+      } else {
+        return c - 'A' + 10;
+      }
+    }
+
+    /// <summary>
+    /// Unescapes a text string as escaped using <see cref="EscapeText(string)" />.
+    /// Two-digit hex escapes (starting with "\x" are also recognised.
+    /// </summary>
+    public static string UnescapeText(string input) {
+      return UnescapeBytes(input).ToStringUtf8();
+    }
+
+    /// <summary>
+    /// Like <see cref="EscapeBytes" /> but escapes a text string.
+    /// The string is first encoded as UTF-8, then each byte escaped individually.
+    /// The returned value is guaranteed to be entirely ASCII.
+    /// </summary>
+    public static string EscapeText(string input) {
+      return EscapeBytes(ByteString.CopyFromUtf8(input));
+    }
+
+    /// <summary>
+    /// Escapes bytes in the format used in protocol buffer text format, which
+    /// is the same as the format used for C string literals.  All bytes
+    /// that are not printable 7-bit ASCII characters are escaped, as well as
+    /// backslash, single-quote, and double-quote characters.  Characters for
+    /// which no defined short-hand escape sequence is defined will be escaped
+    /// using 3-digit octal sequences.
+    /// The returned value is guaranteed to be entirely ASCII.
+    /// </summary>
+    public static String EscapeBytes(ByteString input) {
+      StringBuilder builder = new StringBuilder(input.Length);
+      foreach (byte b in input) {
+        switch (b) {
+          // C# does not use \a or \v
+          case 0x07: builder.Append("\\a" ); break;
+          case (byte)'\b': builder.Append("\\b" ); break;
+          case (byte)'\f': builder.Append("\\f" ); break;
+          case (byte)'\n': builder.Append("\\n" ); break;
+          case (byte)'\r': builder.Append("\\r" ); break;
+          case (byte)'\t': builder.Append("\\t" ); break;
+          case 0x0b: builder.Append("\\v" ); break;
+          case (byte)'\\': builder.Append("\\\\"); break;
+          case (byte)'\'': builder.Append("\\\'"); break;
+          case (byte)'"' : builder.Append("\\\""); break;
+          default:
+            if (b >= 0x20 && b < 128) {
+              builder.Append((char) b);
+            } else {
+              builder.Append('\\');
+              builder.Append((char) ('0' + ((b >> 6) & 3)));
+              builder.Append((char) ('0' + ((b >> 3) & 7)));
+              builder.Append((char) ('0' + (b & 7)));
+            }
+            break;
+        }
+      }
+      return builder.ToString();
+    }
+
+    /// <summary>
+    /// Performs string unescaping from C style (octal, hex, form feeds, tab etc) into a byte string.
+    /// </summary>
+    public static ByteString UnescapeBytes(string input) {
+      byte[] result = new byte[input.Length];
+      int pos = 0;
+      for (int i = 0; i < input.Length; i++) {
+        char c = input[i];
+        if (c > 127 || c < 32) {
+          throw new FormatException("Escaped string must only contain ASCII");
+        }
+        if (c != '\\') {
+          result[pos++] = (byte) c;
+          continue;
+        }
+        if (i + 1 >= input.Length) {
+          throw new FormatException("Invalid escape sequence: '\\' at end of string.");
+        }
+
+        i++;
+        c = input[i];
+        if (c >= '0' && c <= '7') {
+          // Octal escape. 
+          int code = ParseDigit(c);
+          if (i + 1 < input.Length && IsOctal(input[i+1])) {
+            i++;
+            code = code * 8 + ParseDigit(input[i]);
+          }
+          if (i + 1 < input.Length && IsOctal(input[i+1])) {
+            i++;
+            code = code * 8 + ParseDigit(input[i]);
+          }
+          result[pos++] = (byte) code;
+        } else {
+          switch (c) {
+            case 'a': result[pos++] = 0x07; break;
+            case 'b': result[pos++] = (byte) '\b'; break;
+            case 'f': result[pos++] = (byte) '\f'; break;
+            case 'n': result[pos++] = (byte) '\n'; break;
+            case 'r': result[pos++] = (byte) '\r'; break;
+            case 't': result[pos++] = (byte) '\t'; break;
+            case 'v': result[pos++] = 0x0b; break;
+            case '\\': result[pos++] = (byte) '\\'; break;
+            case '\'': result[pos++] = (byte) '\''; break;
+            case '"': result[pos++] = (byte) '\"'; break;
+
+            case 'x':
+              // hex escape
+              int code;
+              if (i + 1 < input.Length && IsHex(input[i+1])) {
+                i++;
+                code = ParseDigit(input[i]);
+              } else {
+                throw new FormatException("Invalid escape sequence: '\\x' with no digits");
+              }
+              if (i + 1 < input.Length && IsHex(input[i+1])) {
+                ++i;
+                code = code * 16 + ParseDigit(input[i]);
+              }
+              result[pos++] = (byte)code;
+              break;
+
+            default:
+              throw new FormatException("Invalid escape sequence: '\\" + c + "'");
+          }
+        }
+      }
+
+      return ByteString.CopyFrom(result, 0, pos);
+    }
+
+    public static void Merge(string text, IBuilder builder) {
+      Merge(text, ExtensionRegistry.Empty, builder);
     }
 
-    [CLSCompliant(false)]
-    public static uint ParseUInt32(string text) {
-      return (uint) ParseInteger(text, false, false);
-    }
-
-    public static int ParseInt32(string text) {
-      return (int) ParseInteger(text, true, false);
-    }
-
-    public static float ParseFloat(string text) {
-      switch (text) {
-        case "-inf":
-        case "-infinity":
-        case "-inff":
-        case "-infinityf":
-          return float.NegativeInfinity;
-        case "inf":
-        case "infinity":
-        case "inff":
-        case "infinityf":
-          return float.PositiveInfinity;
-        case "nan":
-        case "nanf":
-          return float.NaN;
-        default:
-          return float.Parse(text, CultureInfo.InvariantCulture);
-      }
-    }
-
-    public static double ParseDouble(string text) {
-      switch (text) {
-        case "-inf":
-        case "-infinity":
-          return double.NegativeInfinity;
-        case "inf":
-        case "infinity":
-          return double.PositiveInfinity;
-        case "nan":
-          return double.NaN;
-        default:
-          return double.Parse(text, CultureInfo.InvariantCulture);
-      }
-    }
-    
-    /// <summary>
-    /// Parses an integer in hex (leading 0x), decimal (no prefix) or octal (leading 0).
-    /// Only a negative sign is permitted, and it must come before the radix indicator.
-    /// </summary>
-    private static long ParseInteger(string text, bool isSigned, bool isLong) {
-      string original = text;
-      bool negative = false;
-      if (text.StartsWith("-")) {
-        if (!isSigned) {
-          throw new FormatException("Number must be positive: " + original);
-        }
-        negative = true;
-        text = text.Substring(1);
-      }
-
-      int radix = 10;
-      if (text.StartsWith("0x")) {
-        radix = 16;
-        text = text.Substring(2);
-      } else if (text.StartsWith("0")) {
-        radix = 8;
-      }
-
-      ulong result;
-      try {
-        // Workaround for https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278448
-        // We should be able to use Convert.ToUInt64 for all cases.
-        result = radix == 10 ? ulong.Parse(text) : Convert.ToUInt64(text, radix);
-      } catch (OverflowException) {
-        // Convert OverflowException to FormatException so there's a single exception type this method can throw.
-        string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32, isSigned ? "" : "un");
-        throw new FormatException("Number out of range for " + numberDescription + ": " + original);
-      }
-
-      if (negative) {
-        ulong max = isLong ? 0x8000000000000000UL : 0x80000000L;
-        if (result > max) {
-          string numberDescription = string.Format("{0}-bit signed integer", isLong ? 64 : 32);
-          throw new FormatException("Number out of range for " + numberDescription + ": " + original);
-        }
-        return -((long) result);
-      } else {
-        ulong max = isSigned 
-            ? (isLong ? (ulong) long.MaxValue : int.MaxValue)
-            : (isLong ? ulong.MaxValue : uint.MaxValue);
-        if (result > max) {
-          string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32, isSigned ? "" : "un");
-          throw new FormatException("Number out of range for " + numberDescription + ": " + original);
-        }
-        return (long) result;
-      }
-    }
-
-    /// <summary>
-    /// Tests a character to see if it's an octal digit.
-    /// </summary>
-    private static bool IsOctal(char c) {
-      return '0' <= c && c <= '7';
-    }
-
-    /// <summary>
-    /// Tests a character to see if it's a hex digit.
-    /// </summary>
-    private static bool IsHex(char c) {
-      return ('0' <= c && c <= '9') ||
-             ('a' <= c && c <= 'f') ||
-             ('A' <= c && c <= 'F');
-    }
-
-    /// <summary>
-    /// Interprets a character as a digit (in any base up to 36) and returns the
-    /// numeric value.
-    /// </summary>
-    private static int ParseDigit(char c) {
-      if ('0' <= c && c <= '9') {
-        return c - '0';
-      } else if ('a' <= c && c <= 'z') {
-        return c - 'a' + 10;
-      } else {
-        return c - 'A' + 10;
-      }
-    }
-
-    /// <summary>
-    /// Unescapes a text string as escaped using <see cref="EscapeText(string)" />.
-    /// Two-digit hex escapes (starting with "\x" are also recognised.
-    /// </summary>
-    public static string UnescapeText(string input) {
-      return UnescapeBytes(input).ToStringUtf8();
-    }
-
-    /// <summary>
-    /// Like <see cref="EscapeBytes" /> but escapes a text string.
-    /// The string is first encoded as UTF-8, then each byte escaped individually.
-    /// The returned value is guaranteed to be entirely ASCII.
-    /// </summary>
-    public static string EscapeText(string input) {
-      return EscapeBytes(ByteString.CopyFromUtf8(input));
-    }
-
-    /// <summary>
-    /// Escapes bytes in the format used in protocol buffer text format, which
-    /// is the same as the format used for C string literals.  All bytes
-    /// that are not printable 7-bit ASCII characters are escaped, as well as
-    /// backslash, single-quote, and double-quote characters.  Characters for
-    /// which no defined short-hand escape sequence is defined will be escaped
-    /// using 3-digit octal sequences.
-    /// The returned value is guaranteed to be entirely ASCII.
-    /// </summary>
-    public static String EscapeBytes(ByteString input) {
-      StringBuilder builder = new StringBuilder(input.Length);
-      foreach (byte b in input) {
-        switch (b) {
-          // C# does not use \a or \v
-          case 0x07: builder.Append("\\a" ); break;
-          case (byte)'\b': builder.Append("\\b" ); break;
-          case (byte)'\f': builder.Append("\\f" ); break;
-          case (byte)'\n': builder.Append("\\n" ); break;
-          case (byte)'\r': builder.Append("\\r" ); break;
-          case (byte)'\t': builder.Append("\\t" ); break;
-          case 0x0b: builder.Append("\\v" ); break;
-          case (byte)'\\': builder.Append("\\\\"); break;
-          case (byte)'\'': builder.Append("\\\'"); break;
-          case (byte)'"' : builder.Append("\\\""); break;
-          default:
-            if (b >= 0x20 && b < 128) {
-              builder.Append((char) b);
-            } else {
-              builder.Append('\\');
-              builder.Append((char) ('0' + ((b >> 6) & 3)));
-              builder.Append((char) ('0' + ((b >> 3) & 7)));
-              builder.Append((char) ('0' + (b & 7)));
-            }
-            break;
-        }
-      }
-      return builder.ToString();
-    }
-
-    /// <summary>
-    /// Performs string unescaping from C style (octal, hex, form feeds, tab etc) into a byte string.
-    /// </summary>
-    public static ByteString UnescapeBytes(string input) {
-      byte[] result = new byte[input.Length];
-      int pos = 0;
-      for (int i = 0; i < input.Length; i++) {
-        char c = input[i];
-        if (c > 127 || c < 32) {
-          throw new FormatException("Escaped string must only contain ASCII");
-        }
-        if (c != '\\') {
-          result[pos++] = (byte) c;
-          continue;
-        }
-        if (i + 1 >= input.Length) {
-          throw new FormatException("Invalid escape sequence: '\\' at end of string.");
-        }
-
-        i++;
-        c = input[i];
-        if (c >= '0' && c <= '7') {
-          // Octal escape. 
-          int code = ParseDigit(c);
-          if (i + 1 < input.Length && IsOctal(input[i+1])) {
-            i++;
-            code = code * 8 + ParseDigit(input[i]);
-          }
-          if (i + 1 < input.Length && IsOctal(input[i+1])) {
-            i++;
-            code = code * 8 + ParseDigit(input[i]);
-          }
-          result[pos++] = (byte) code;
-        } else {
-          switch (c) {
-            case 'a': result[pos++] = 0x07; break;
-            case 'b': result[pos++] = (byte) '\b'; break;
-            case 'f': result[pos++] = (byte) '\f'; break;
-            case 'n': result[pos++] = (byte) '\n'; break;
-            case 'r': result[pos++] = (byte) '\r'; break;
-            case 't': result[pos++] = (byte) '\t'; break;
-            case 'v': result[pos++] = 0x0b; break;
-            case '\\': result[pos++] = (byte) '\\'; break;
-            case '\'': result[pos++] = (byte) '\''; break;
-            case '"': result[pos++] = (byte) '\"'; break;
-
-            case 'x':
-              // hex escape
-              int code;
-              if (i + 1 < input.Length && IsHex(input[i+1])) {
-                i++;
-                code = ParseDigit(input[i]);
-              } else {
-                throw new FormatException("Invalid escape sequence: '\\x' with no digits");
-              }
-              if (i + 1 < input.Length && IsHex(input[i+1])) {
-                ++i;
-                code = code * 16 + ParseDigit(input[i]);
-              }
-              result[pos++] = (byte)code;
-              break;
-
-            default:
-              throw new FormatException("Invalid escape sequence: '\\" + c + "'");
-          }
-        }
-      }
-
-      return ByteString.CopyFrom(result, 0, pos);
-    }
-
-    public static void Merge(string text, IBuilder builder) {
-      Merge(text, ExtensionRegistry.Empty, builder);
-    }
-
-    public static void Merge(TextReader reader, IBuilder builder) {
-      Merge(reader, ExtensionRegistry.Empty, builder);
-    }
-
-    public static void Merge(TextReader reader, ExtensionRegistry registry, IBuilder builder) {
-      Merge(reader.ReadToEnd(), registry, builder);
-    }
-
-    public static void Merge(string text, ExtensionRegistry registry, IBuilder builder) {
-      TextTokenizer tokenizer = new TextTokenizer(text);
-
-      while (!tokenizer.AtEnd) {
-        MergeField(tokenizer, registry, builder);
-      }
-    }
-
-    /// <summary>
-    /// Parses a single field from the specified tokenizer and merges it into
-    /// the builder.
-    /// </summary>
-    private static void MergeField(TextTokenizer tokenizer, ExtensionRegistry extensionRegistry,
-        IBuilder builder) {
-
-      FieldDescriptor field;
-      MessageDescriptor type = builder.DescriptorForType;
-      ExtensionInfo extension = null;
-
-      if (tokenizer.TryConsume("[")) {
-        // An extension.
-        StringBuilder name = new StringBuilder(tokenizer.ConsumeIdentifier());
-        while (tokenizer.TryConsume(".")) {
-          name.Append(".");
-          name.Append(tokenizer.ConsumeIdentifier());
-        }
-
-        extension = extensionRegistry[name.ToString()];
-
-        if (extension == null) {
-          throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" not found in the ExtensionRegistry.");
-        } else if (extension.Descriptor.ContainingType != type) {
-          throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" does not extend message type \"" +
-            type.FullName + "\".");
-        }
-
-        tokenizer.Consume("]");
-
-        field = extension.Descriptor;
-      } else {
-        String name = tokenizer.ConsumeIdentifier();
-        field = type.FindDescriptor<FieldDescriptor>(name);
-
-        // Group names are expected to be capitalized as they appear in the
-        // .proto file, which actually matches their type names, not their field
-        // names.
-        if (field == null) {
-          // Explicitly specify the invariant culture so that this code does not break when
-          // executing in Turkey.
-          String lowerName = name.ToLower(CultureInfo.InvariantCulture);
-          field = type.FindDescriptor<FieldDescriptor>(lowerName);
-          // If the case-insensitive match worked but the field is NOT a group,
-          // TODO(jonskeet): What? Java comment ends here!
-          if (field != null && field.FieldType != FieldType.Group) {
-            field = null;
-          }
-        }
-        // Again, special-case group names as described above.
-        if (field != null && field.FieldType == FieldType.Group && field.MessageType.Name != name) {
-          field = null;
-        }
-
-        if (field == null) {
-          throw tokenizer.CreateFormatExceptionPreviousToken(
-              "Message type \"" + type.FullName + "\" has no field named \"" + name + "\".");
-        }
-      }
-
-      object value = null;
-
-      if (field.MappedType == MappedType.Message) {
-        tokenizer.TryConsume(":");  // optional
-
-        String endToken;
-        if (tokenizer.TryConsume("<")) {
-          endToken = ">";
-        } else {
-          tokenizer.Consume("{");
-          endToken = "}";
-        }
-
-        IBuilder subBuilder;
-        if (extension == null) {
-          subBuilder = builder.CreateBuilderForField(field);
-        } else {
-          subBuilder = extension.DefaultInstance.WeakCreateBuilderForType() as IBuilder;
-          if (subBuilder == null)
-            throw new NotSupportedException("Lite messages are not supported.");
-        }
-
-        while (!tokenizer.TryConsume(endToken)) {
-          if (tokenizer.AtEnd) {
-            throw tokenizer.CreateFormatException("Expected \"" + endToken + "\".");
-          }
-          MergeField(tokenizer, extensionRegistry, subBuilder);
-        }
-
-        value = subBuilder.WeakBuild();
-
-      } else {
-        tokenizer.Consume(":");
-
-        switch (field.FieldType) {
-          case FieldType.Int32:
-          case FieldType.SInt32:
-          case FieldType.SFixed32:
-            value = tokenizer.ConsumeInt32();
-            break;
-
-          case FieldType.Int64:
-          case FieldType.SInt64:
-          case FieldType.SFixed64:
-            value = tokenizer.ConsumeInt64();
-            break;
-
-          case FieldType.UInt32:
-          case FieldType.Fixed32:
-            value = tokenizer.ConsumeUInt32();
-            break;
-
-          case FieldType.UInt64:
-          case FieldType.Fixed64:
-            value = tokenizer.ConsumeUInt64();
-            break;
-
-          case FieldType.Float:
-            value = tokenizer.ConsumeFloat();
-            break;
-
-          case FieldType.Double:
-            value = tokenizer.ConsumeDouble();
-            break;
-
-          case FieldType.Bool:
-            value = tokenizer.ConsumeBoolean();
-            break;
-
-          case FieldType.String:
-            value = tokenizer.ConsumeString();
-            break;
-
-          case FieldType.Bytes:
-            value = tokenizer.ConsumeByteString();
-            break;
-
-          case FieldType.Enum: {
-            EnumDescriptor enumType = field.EnumType;
-
-            if (tokenizer.LookingAtInteger()) {
-              int number = tokenizer.ConsumeInt32();
-              value = enumType.FindValueByNumber(number);
-              if (value == null) {
-                throw tokenizer.CreateFormatExceptionPreviousToken(
-                  "Enum type \"" + enumType.FullName +
-                  "\" has no value with number " + number + ".");
-              }
-            } else {
-              String id = tokenizer.ConsumeIdentifier();
-              value = enumType.FindValueByName(id);
-              if (value == null) {
-                throw tokenizer.CreateFormatExceptionPreviousToken(
-                  "Enum type \"" + enumType.FullName +
-                  "\" has no value named \"" + id + "\".");
-              }
-            }
-
-            break;
-          }
-
-          case FieldType.Message:
-          case FieldType.Group:
-            throw new InvalidOperationException("Can't get here.");
-        }
-      }
-
-      if (field.IsRepeated) {
-        builder.WeakAddRepeatedField(field, value);
-      } else {
-        builder.SetField(field, value);
-      }
-    }
-  }
-}
+    public static void Merge(TextReader reader, IBuilder builder) {
+      Merge(reader, ExtensionRegistry.Empty, builder);
+    }
+
+    public static void Merge(TextReader reader, ExtensionRegistry registry, IBuilder builder) {
+      Merge(reader.ReadToEnd(), registry, builder);
+    }
+
+    public static void Merge(string text, ExtensionRegistry registry, IBuilder builder) {
+      TextTokenizer tokenizer = new TextTokenizer(text);
+
+      while (!tokenizer.AtEnd) {
+        MergeField(tokenizer, registry, builder);
+      }
+    }
+
+    /// <summary>
+    /// Parses a single field from the specified tokenizer and merges it into
+    /// the builder.
+    /// </summary>
+    private static void MergeField(TextTokenizer tokenizer, ExtensionRegistry extensionRegistry,
+        IBuilder builder) {
+
+      FieldDescriptor field;
+      MessageDescriptor type = builder.DescriptorForType;
+      ExtensionInfo extension = null;
+
+      if (tokenizer.TryConsume("[")) {
+        // An extension.
+        StringBuilder name = new StringBuilder(tokenizer.ConsumeIdentifier());
+        while (tokenizer.TryConsume(".")) {
+          name.Append(".");
+          name.Append(tokenizer.ConsumeIdentifier());
+        }
+
+        extension = extensionRegistry[name.ToString()];
+
+        if (extension == null) {
+          throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" not found in the ExtensionRegistry.");
+        } else if (extension.Descriptor.ContainingType != type) {
+          throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" does not extend message type \"" +
+            type.FullName + "\".");
+        }
+
+        tokenizer.Consume("]");
+
+        field = extension.Descriptor;
+      } else {
+        String name = tokenizer.ConsumeIdentifier();
+        field = type.FindDescriptor<FieldDescriptor>(name);
+
+        // Group names are expected to be capitalized as they appear in the
+        // .proto file, which actually matches their type names, not their field
+        // names.
+        if (field == null) {
+          // Explicitly specify the invariant culture so that this code does not break when
+          // executing in Turkey.
+          String lowerName = name.ToLower(CultureInfo.InvariantCulture);
+          field = type.FindDescriptor<FieldDescriptor>(lowerName);
+          // If the case-insensitive match worked but the field is NOT a group,
+          // TODO(jonskeet): What? Java comment ends here!
+          if (field != null && field.FieldType != FieldType.Group) {
+            field = null;
+          }
+        }
+        // Again, special-case group names as described above.
+        if (field != null && field.FieldType == FieldType.Group && field.MessageType.Name != name) {
+          field = null;
+        }
+
+        if (field == null) {
+          throw tokenizer.CreateFormatExceptionPreviousToken(
+              "Message type \"" + type.FullName + "\" has no field named \"" + name + "\".");
+        }
+      }
+
+      object value = null;
+
+      if (field.MappedType == MappedType.Message) {
+        tokenizer.TryConsume(":");  // optional
+
+        String endToken;
+        if (tokenizer.TryConsume("<")) {
+          endToken = ">";
+        } else {
+          tokenizer.Consume("{");
+          endToken = "}";
+        }
+
+        IBuilder subBuilder;
+        if (extension == null) {
+          subBuilder = builder.CreateBuilderForField(field);
+        } else {
+          subBuilder = extension.DefaultInstance.WeakCreateBuilderForType() as IBuilder;
+          if (subBuilder == null)
+            throw new NotSupportedException("Lite messages are not supported.");
+        }
+
+        while (!tokenizer.TryConsume(endToken)) {
+          if (tokenizer.AtEnd) {
+            throw tokenizer.CreateFormatException("Expected \"" + endToken + "\".");
+          }
+          MergeField(tokenizer, extensionRegistry, subBuilder);
+        }
+
+        value = subBuilder.WeakBuild();
+
+      } else {
+        tokenizer.Consume(":");
+
+        switch (field.FieldType) {
+          case FieldType.Int32:
+          case FieldType.SInt32:
+          case FieldType.SFixed32:
+            value = tokenizer.ConsumeInt32();
+            break;
+
+          case FieldType.Int64:
+          case FieldType.SInt64:
+          case FieldType.SFixed64:
+            value = tokenizer.ConsumeInt64();
+            break;
+
+          case FieldType.UInt32:
+          case FieldType.Fixed32:
+            value = tokenizer.ConsumeUInt32();
+            break;
+
+          case FieldType.UInt64:
+          case FieldType.Fixed64:
+            value = tokenizer.ConsumeUInt64();
+            break;
+
+          case FieldType.Float:
+            value = tokenizer.ConsumeFloat();
+            break;
+
+          case FieldType.Double:
+            value = tokenizer.ConsumeDouble();
+            break;
+
+          case FieldType.Bool:
+            value = tokenizer.ConsumeBoolean();
+            break;
+
+          case FieldType.String:
+            value = tokenizer.ConsumeString();
+            break;
+
+          case FieldType.Bytes:
+            value = tokenizer.ConsumeByteString();
+            break;
+
+          case FieldType.Enum: {
+            EnumDescriptor enumType = field.EnumType;
+
+            if (tokenizer.LookingAtInteger()) {
+              int number = tokenizer.ConsumeInt32();
+              value = enumType.FindValueByNumber(number);
+              if (value == null) {
+                throw tokenizer.CreateFormatExceptionPreviousToken(
+                  "Enum type \"" + enumType.FullName +
+                  "\" has no value with number " + number + ".");
+              }
+            } else {
+              String id = tokenizer.ConsumeIdentifier();
+              value = enumType.FindValueByName(id);
+              if (value == null) {
+                throw tokenizer.CreateFormatExceptionPreviousToken(
+                  "Enum type \"" + enumType.FullName +
+                  "\" has no value named \"" + id + "\".");
+              }
+            }
+
+            break;
+          }
+
+          case FieldType.Message:
+          case FieldType.Group:
+            throw new InvalidOperationException("Can't get here.");
+        }
+      }
+
+      if (field.IsRepeated) {
+        builder.WeakAddRepeatedField(field, value);
+      } else {
+        builder.SetField(field, value);
+      }
+    }
+  }
+}

+ 143 - 143
src/ProtocolBuffers/TextGenerator.cs

@@ -1,143 +1,143 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.IO;
-using System.Text;
-
-namespace Google.ProtocolBuffers {
-
-  /// <summary>
-  /// Helper class to control indentation. Used for TextFormat and by ProtoGen.
-  /// </summary>
-  public sealed class TextGenerator {
-
-    /// <summary>
-    /// The string to use at the end of each line. We assume that "Print" is only called using \n
-    /// to indicate a line break; that's what we use to detect when we need to indent etc, and
-    /// *just* the \n is replaced with the contents of lineBreak.
-    /// </summary>
-    private readonly string lineBreak;
-
-    /// <summary>
-    /// Writer to write formatted text to.
-    /// </summary>
-    private readonly TextWriter writer;
-
-    /// <summary>
-    /// Keeps track of whether the next piece of text should be indented
-    /// </summary>
-    bool atStartOfLine = true;
-
-    /// <summary>
-    /// Keeps track of the current level of indentation
-    /// </summary>
-    readonly StringBuilder indent = new StringBuilder();
-
-    /// <summary>
-    /// Creates a generator writing to the given writer. The writer
-    /// is not closed by this class.
-    /// </summary>
-    public TextGenerator(TextWriter writer, string lineBreak) {
-      this.writer = writer;
-      this.lineBreak = lineBreak;
-    }
-
-    /// <summary>
-    /// Indents text by two spaces. After calling Indent(), two spaces
-    /// will be inserted at the beginning of each line of text. Indent() may
-    /// be called multiple times to produce deeper indents.
-    /// </summary>
-    public void Indent() {
-      indent.Append("  ");
-    }
-
-    /// <summary>
-    /// Reduces the current indent level by two spaces.
-    /// </summary>
-    public void Outdent() {
-      if (indent.Length == 0) {
-        throw new InvalidOperationException("Too many calls to Outdent()");
-      }
-      indent.Length -= 2;
-    }
-
-    public void WriteLine(string text) {
-      Print(text);
-      Print("\n");
-    }
-
-    public void WriteLine(string format, params object[] args) {
-      WriteLine(string.Format(format, args));
-    }
-
-    public void WriteLine() {
-      WriteLine("");
-    }
-
-    /// <summary>
-    /// Prints the given text to the output stream, indenting at line boundaries.
-    /// </summary>
-    /// <param name="text"></param>
-    public void Print(string text) {
-      int pos = 0;
-
-      for (int i = 0; i < text.Length; i++) {
-        if (text[i] == '\n') {
-          // Strip off the \n from what we write
-          Write(text.Substring(pos, i - pos));
-          Write(lineBreak);
-          pos = i + 1;
-          atStartOfLine = true;
-        }
-      }
-      Write(text.Substring(pos));
-    }
-
-    public void Write(string format, params object[] args) {
-      Write(string.Format(format, args));
-    }
-    
-    private void Write(string data) {
-      if (data.Length == 0) {
-        return;
-      }
-      if (atStartOfLine) {
-        atStartOfLine = false;
-        writer.Write(indent);
-      }
-      writer.Write(data);
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.IO;
+using System.Text;
+
+namespace Google.ProtocolBuffers {
+
+  /// <summary>
+  /// Helper class to control indentation. Used for TextFormat and by ProtoGen.
+  /// </summary>
+  public sealed class TextGenerator {
+
+    /// <summary>
+    /// The string to use at the end of each line. We assume that "Print" is only called using \n
+    /// to indicate a line break; that's what we use to detect when we need to indent etc, and
+    /// *just* the \n is replaced with the contents of lineBreak.
+    /// </summary>
+    private readonly string lineBreak;
+
+    /// <summary>
+    /// Writer to write formatted text to.
+    /// </summary>
+    private readonly TextWriter writer;
+
+    /// <summary>
+    /// Keeps track of whether the next piece of text should be indented
+    /// </summary>
+    bool atStartOfLine = true;
+
+    /// <summary>
+    /// Keeps track of the current level of indentation
+    /// </summary>
+    readonly StringBuilder indent = new StringBuilder();
+
+    /// <summary>
+    /// Creates a generator writing to the given writer. The writer
+    /// is not closed by this class.
+    /// </summary>
+    public TextGenerator(TextWriter writer, string lineBreak) {
+      this.writer = writer;
+      this.lineBreak = lineBreak;
+    }
+
+    /// <summary>
+    /// Indents text by two spaces. After calling Indent(), two spaces
+    /// will be inserted at the beginning of each line of text. Indent() may
+    /// be called multiple times to produce deeper indents.
+    /// </summary>
+    public void Indent() {
+      indent.Append("  ");
+    }
+
+    /// <summary>
+    /// Reduces the current indent level by two spaces.
+    /// </summary>
+    public void Outdent() {
+      if (indent.Length == 0) {
+        throw new InvalidOperationException("Too many calls to Outdent()");
+      }
+      indent.Length -= 2;
+    }
+
+    public void WriteLine(string text) {
+      Print(text);
+      Print("\n");
+    }
+
+    public void WriteLine(string format, params object[] args) {
+      WriteLine(string.Format(format, args));
+    }
+
+    public void WriteLine() {
+      WriteLine("");
+    }
+
+    /// <summary>
+    /// Prints the given text to the output stream, indenting at line boundaries.
+    /// </summary>
+    /// <param name="text"></param>
+    public void Print(string text) {
+      int pos = 0;
+
+      for (int i = 0; i < text.Length; i++) {
+        if (text[i] == '\n') {
+          // Strip off the \n from what we write
+          Write(text.Substring(pos, i - pos));
+          Write(lineBreak);
+          pos = i + 1;
+          atStartOfLine = true;
+        }
+      }
+      Write(text.Substring(pos));
+    }
+
+    public void Write(string format, params object[] args) {
+      Write(string.Format(format, args));
+    }
+    
+    private void Write(string data) {
+      if (data.Length == 0) {
+        return;
+      }
+      if (atStartOfLine) {
+        atStartOfLine = false;
+        writer.Write(indent);
+      }
+      writer.Write(data);
+    }
+  }
+}

+ 412 - 412
src/ProtocolBuffers/TextTokenizer.cs

@@ -1,412 +1,412 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Globalization;
-using System.Text.RegularExpressions;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Represents a stream of tokens parsed from a string.
-  /// </summary>
-  internal sealed class TextTokenizer {
-    private readonly string text;
-    private string currentToken;
-
-    /// <summary>
-    /// The character index within the text to perform the next regex match at.
-    /// </summary>
-    private int matchPos = 0;
-
-    /// <summary>
-    /// The character index within the text at which the current token begins.
-    /// </summary>
-    private int pos = 0;
-
-    /// <summary>
-    /// The line number of the current token.
-    /// </summary>
-    private int line = 0;
-    /// <summary>
-    /// The column number of the current token.
-    /// </summary>
-    private int column = 0;
-
-    /// <summary>
-    /// The line number of the previous token.
-    /// </summary>
-    private int previousLine = 0;
-    /// <summary>
-    /// The column number of the previous token.
-    /// </summary>
-    private int previousColumn = 0;
-
-    // Note: atomic groups used to mimic possessive quantifiers in Java in both of these regexes
-    internal static readonly Regex WhitespaceAndCommentPattern = new Regex("\\G(?>(\\s|(#.*$))+)",
-        SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline);
-    private static readonly Regex TokenPattern = new Regex(
-      "\\G[a-zA-Z_](?>[0-9a-zA-Z_+-]*)|" +              // an identifier
-      "\\G[0-9+-](?>[0-9a-zA-Z_.+-]*)|" +                  // a number
-      "\\G\"(?>([^\"\\\n\\\\]|\\\\.)*)(\"|\\\\?$)|" +    // a double-quoted string
-      "\\G\'(?>([^\"\\\n\\\\]|\\\\.)*)(\'|\\\\?$)",      // a single-quoted string
-      SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline);
-
-    private static readonly Regex DoubleInfinity = new Regex("^-?inf(inity)?$",
-      SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase);
-    private static readonly Regex FloatInfinity = new Regex("^-?inf(inity)?f?$",
-      SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase);
-    private static readonly Regex FloatNan = new Regex("^nanf?$",
-      SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase);
-
-    /** Construct a tokenizer that parses tokens from the given text. */
-    public TextTokenizer(string text) {
-      this.text = text;
-      SkipWhitespace();
-      NextToken();
-    }
-
-    /// <summary>
-    /// Are we at the end of the input?
-    /// </summary>
-    public bool AtEnd {
-      get { return currentToken.Length == 0; }
-    }
-
-    /// <summary>
-    /// Advances to the next token.
-    /// </summary>
-    public void NextToken() {
-      previousLine = line;
-      previousColumn = column;
-
-      // Advance the line counter to the current position.
-      while (pos < matchPos) {
-        if (text[pos] == '\n') {
-          ++line;
-          column = 0;
-        } else {
-          ++column;
-        }
-        ++pos;
-      }
-
-      // Match the next token.
-      if (matchPos == text.Length) {
-        // EOF
-        currentToken = "";
-      } else {
-        Match match = TokenPattern.Match(text, matchPos);
-        if (match.Success) {
-          currentToken = match.Value;
-          matchPos += match.Length;
-        } else {
-          // Take one character.
-          currentToken = text[matchPos].ToString();
-          matchPos++;
-        }
-
-        SkipWhitespace();
-      }
-    }
-
-    /// <summary>
-    /// Skip over any whitespace so that matchPos starts at the next token.
-    /// </summary>
-    private void SkipWhitespace() {
-      Match match = WhitespaceAndCommentPattern.Match(text, matchPos);
-      if (match.Success) {
-        matchPos += match.Length;
-      }
-    }
-
-    /// <summary>
-    /// If the next token exactly matches the given token, consume it and return
-    /// true. Otherwise, return false without doing anything.
-    /// </summary>
-    public bool TryConsume(string token) {
-      if (currentToken == token) {
-        NextToken();
-        return true;
-      }
-      return false;
-    }
-
-    /*
-     * If the next token exactly matches {@code token}, consume it.  Otherwise,
-     * throw a {@link ParseException}.
-     */
-    /// <summary>
-    /// If the next token exactly matches the specified one, consume it.
-    /// Otherwise, throw a FormatException.
-    /// </summary>
-    /// <param name="token"></param>
-    public void Consume(string token) {
-      if (!TryConsume(token)) {
-        throw CreateFormatException("Expected \"" + token + "\".");
-      }
-    }
-
-    /// <summary>
-    /// Returns true if the next token is an integer, but does not consume it.
-    /// </summary>
-    public bool LookingAtInteger() {
-      if (currentToken.Length == 0) {
-        return false;
-      }
-
-      char c = currentToken[0];
-      return ('0' <= c && c <= '9') || c == '-' || c == '+';
-    }
-
-    /// <summary>
-    /// If the next token is an identifier, consume it and return its value.
-    /// Otherwise, throw a FormatException.
-    /// </summary>
-    public string ConsumeIdentifier() {
-      foreach (char c in currentToken) {
-        if (('a' <= c && c <= 'z') ||
-            ('A' <= c && c <= 'Z') ||
-            ('0' <= c && c <= '9') ||
-            (c == '_') || (c == '.')) {
-          // OK
-        } else {
-          throw CreateFormatException("Expected identifier.");
-        }
-      }
-
-      string result = currentToken;
-      NextToken();
-      return result;
-    }
-
-    /// <summary>
-    /// If the next token is a 32-bit signed integer, consume it and return its 
-    /// value. Otherwise, throw a FormatException.
-    /// </summary>
-    public int ConsumeInt32()  {
-      try {
-        int result = TextFormat.ParseInt32(currentToken);
-        NextToken();
-        return result;
-      } catch (FormatException e) {
-        throw CreateIntegerParseException(e);
-      }
-    }
-
-    /// <summary>
-    /// If the next token is a 32-bit unsigned integer, consume it and return its
-    /// value. Otherwise, throw a FormatException.
-    /// </summary>
-    public uint ConsumeUInt32() {
-      try {
-        uint result = TextFormat.ParseUInt32(currentToken);
-        NextToken();
-        return result;
-      } catch (FormatException e) {
-        throw CreateIntegerParseException(e);
-      }
-    }
-
-    /// <summary>
-    /// If the next token is a 64-bit signed integer, consume it and return its
-    /// value. Otherwise, throw a FormatException.
-    /// </summary>
-    public long ConsumeInt64() {
-      try {
-        long result = TextFormat.ParseInt64(currentToken);
-        NextToken();
-        return result;
-      } catch (FormatException e) {
-        throw CreateIntegerParseException(e);
-      }
-    }
-
-    /// <summary>
-    /// If the next token is a 64-bit unsigned integer, consume it and return its
-    /// value. Otherwise, throw a FormatException.
-    /// </summary>
-    public ulong ConsumeUInt64() {
-      try {
-        ulong result = TextFormat.ParseUInt64(currentToken);
-        NextToken();
-        return result;
-      } catch (FormatException e) {
-        throw CreateIntegerParseException(e);
-      }
-    }
-
-    /// <summary>
-    /// If the next token is a double, consume it and return its value.
-    /// Otherwise, throw a FormatException.
-    /// </summary>
-    public double ConsumeDouble() {
-      // We need to parse infinity and nan separately because
-      // double.Parse() does not accept "inf", "infinity", or "nan".
-      if (DoubleInfinity.IsMatch(currentToken)) {
-        bool negative = currentToken.StartsWith("-");
-        NextToken();
-        return negative ? double.NegativeInfinity : double.PositiveInfinity;
-      }
-      if (currentToken.Equals("nan", StringComparison.InvariantCultureIgnoreCase)) {
-        NextToken();
-        return Double.NaN;
-      }
-
-      try {
-        double result = double.Parse(currentToken, CultureInfo.InvariantCulture);
-        NextToken();
-        return result;
-      } catch (FormatException e) {
-        throw CreateFloatParseException(e);
-      } catch (OverflowException e) {
-        throw CreateFloatParseException(e);
-      }
-    }
-
-    /// <summary>
-    /// If the next token is a float, consume it and return its value.
-    /// Otherwise, throw a FormatException.
-    /// </summary>
-    public float ConsumeFloat() {
-      // We need to parse infinity and nan separately because
-      // Float.parseFloat() does not accept "inf", "infinity", or "nan".
-      if (FloatInfinity.IsMatch(currentToken)) {
-        bool negative = currentToken.StartsWith("-");
-        NextToken();
-        return negative ? float.NegativeInfinity : float.PositiveInfinity;
-      }
-      if (FloatNan.IsMatch(currentToken)) {
-        NextToken();
-        return float.NaN;
-      }
-
-      if (currentToken.EndsWith("f")) {
-        currentToken = currentToken.TrimEnd('f');
-      }
-
-      try {
-        float result = float.Parse(currentToken, CultureInfo.InvariantCulture);
-        NextToken();
-        return result;
-      } catch (FormatException e) {
-        throw CreateFloatParseException(e);
-      } catch (OverflowException e) {
-        throw CreateFloatParseException(e);
-      }
-    }
-
-    /// <summary>
-    /// If the next token is a Boolean, consume it and return its value.
-    /// Otherwise, throw a FormatException.    
-    /// </summary>
-    public bool ConsumeBoolean() {
-      if (currentToken == "true") {
-        NextToken();
-        return true;
-      } 
-      if (currentToken == "false") {
-        NextToken();
-        return false;
-      }
-      throw CreateFormatException("Expected \"true\" or \"false\".");
-    }
-
-    /// <summary>
-    /// If the next token is a string, consume it and return its (unescaped) value.
-    /// Otherwise, throw a FormatException.
-    /// </summary>
-    public string ConsumeString() {
-      return ConsumeByteString().ToStringUtf8();
-    }
-
-    /// <summary>
-    /// If the next token is a string, consume it, unescape it as a
-    /// ByteString and return it. Otherwise, throw a FormatException.
-    /// </summary>
-    public ByteString ConsumeByteString() {
-      char quote = currentToken.Length > 0 ? currentToken[0] : '\0';
-      if (quote != '\"' && quote != '\'') {
-        throw CreateFormatException("Expected string.");
-      }
-
-      if (currentToken.Length < 2 ||
-          currentToken[currentToken.Length-1] != quote) {
-        throw CreateFormatException("String missing ending quote.");
-      }
-
-      try {
-        string escaped = currentToken.Substring(1, currentToken.Length - 2);
-        ByteString result = TextFormat.UnescapeBytes(escaped);
-        NextToken();
-        return result;
-      } catch (FormatException e) {
-        throw CreateFormatException(e.Message);
-      }
-    }
-
-    /// <summary>
-    /// Returns a format exception with the current line and column numbers
-    /// in the description, suitable for throwing.
-    /// </summary>
-    public FormatException CreateFormatException(string description) {
-      // Note:  People generally prefer one-based line and column numbers.
-      return new FormatException((line + 1) + ":" + (column + 1) + ": " + description);
-    }
-
-    /// <summary>
-    /// Returns a format exception with the line and column numbers of the
-    /// previous token in the description, suitable for throwing.
-    /// </summary>
-    public FormatException CreateFormatExceptionPreviousToken(string description) {
-      // Note:  People generally prefer one-based line and column numbers.
-      return new FormatException((previousLine + 1) + ":" + (previousColumn + 1) + ": " + description);
-    }
-
-    /// <summary>
-    /// Constructs an appropriate FormatException for the given existing exception
-    /// when trying to parse an integer.
-    /// </summary>
-    private FormatException CreateIntegerParseException(FormatException e) {
-      return CreateFormatException("Couldn't parse integer: " + e.Message);
-    }
-
-    /// <summary>
-    /// Constructs an appropriate FormatException for the given existing exception
-    /// when trying to parse a float or double.
-    /// </summary>
-    private FormatException CreateFloatParseException(Exception e) {
-      return CreateFormatException("Couldn't parse number: " + e.Message);
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Represents a stream of tokens parsed from a string.
+  /// </summary>
+  internal sealed class TextTokenizer {
+    private readonly string text;
+    private string currentToken;
+
+    /// <summary>
+    /// The character index within the text to perform the next regex match at.
+    /// </summary>
+    private int matchPos = 0;
+
+    /// <summary>
+    /// The character index within the text at which the current token begins.
+    /// </summary>
+    private int pos = 0;
+
+    /// <summary>
+    /// The line number of the current token.
+    /// </summary>
+    private int line = 0;
+    /// <summary>
+    /// The column number of the current token.
+    /// </summary>
+    private int column = 0;
+
+    /// <summary>
+    /// The line number of the previous token.
+    /// </summary>
+    private int previousLine = 0;
+    /// <summary>
+    /// The column number of the previous token.
+    /// </summary>
+    private int previousColumn = 0;
+
+    // Note: atomic groups used to mimic possessive quantifiers in Java in both of these regexes
+    internal static readonly Regex WhitespaceAndCommentPattern = new Regex("\\G(?>(\\s|(#.*$))+)",
+        SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline);
+    private static readonly Regex TokenPattern = new Regex(
+      "\\G[a-zA-Z_](?>[0-9a-zA-Z_+-]*)|" +              // an identifier
+      "\\G[0-9+-](?>[0-9a-zA-Z_.+-]*)|" +                  // a number
+      "\\G\"(?>([^\"\\\n\\\\]|\\\\.)*)(\"|\\\\?$)|" +    // a double-quoted string
+      "\\G\'(?>([^\"\\\n\\\\]|\\\\.)*)(\'|\\\\?$)",      // a single-quoted string
+      SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline);
+
+    private static readonly Regex DoubleInfinity = new Regex("^-?inf(inity)?$",
+      SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase);
+    private static readonly Regex FloatInfinity = new Regex("^-?inf(inity)?f?$",
+      SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase);
+    private static readonly Regex FloatNan = new Regex("^nanf?$",
+      SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase);
+
+    /** Construct a tokenizer that parses tokens from the given text. */
+    public TextTokenizer(string text) {
+      this.text = text;
+      SkipWhitespace();
+      NextToken();
+    }
+
+    /// <summary>
+    /// Are we at the end of the input?
+    /// </summary>
+    public bool AtEnd {
+      get { return currentToken.Length == 0; }
+    }
+
+    /// <summary>
+    /// Advances to the next token.
+    /// </summary>
+    public void NextToken() {
+      previousLine = line;
+      previousColumn = column;
+
+      // Advance the line counter to the current position.
+      while (pos < matchPos) {
+        if (text[pos] == '\n') {
+          ++line;
+          column = 0;
+        } else {
+          ++column;
+        }
+        ++pos;
+      }
+
+      // Match the next token.
+      if (matchPos == text.Length) {
+        // EOF
+        currentToken = "";
+      } else {
+        Match match = TokenPattern.Match(text, matchPos);
+        if (match.Success) {
+          currentToken = match.Value;
+          matchPos += match.Length;
+        } else {
+          // Take one character.
+          currentToken = text[matchPos].ToString();
+          matchPos++;
+        }
+
+        SkipWhitespace();
+      }
+    }
+
+    /// <summary>
+    /// Skip over any whitespace so that matchPos starts at the next token.
+    /// </summary>
+    private void SkipWhitespace() {
+      Match match = WhitespaceAndCommentPattern.Match(text, matchPos);
+      if (match.Success) {
+        matchPos += match.Length;
+      }
+    }
+
+    /// <summary>
+    /// If the next token exactly matches the given token, consume it and return
+    /// true. Otherwise, return false without doing anything.
+    /// </summary>
+    public bool TryConsume(string token) {
+      if (currentToken == token) {
+        NextToken();
+        return true;
+      }
+      return false;
+    }
+
+    /*
+     * If the next token exactly matches {@code token}, consume it.  Otherwise,
+     * throw a {@link ParseException}.
+     */
+    /// <summary>
+    /// If the next token exactly matches the specified one, consume it.
+    /// Otherwise, throw a FormatException.
+    /// </summary>
+    /// <param name="token"></param>
+    public void Consume(string token) {
+      if (!TryConsume(token)) {
+        throw CreateFormatException("Expected \"" + token + "\".");
+      }
+    }
+
+    /// <summary>
+    /// Returns true if the next token is an integer, but does not consume it.
+    /// </summary>
+    public bool LookingAtInteger() {
+      if (currentToken.Length == 0) {
+        return false;
+      }
+
+      char c = currentToken[0];
+      return ('0' <= c && c <= '9') || c == '-' || c == '+';
+    }
+
+    /// <summary>
+    /// If the next token is an identifier, consume it and return its value.
+    /// Otherwise, throw a FormatException.
+    /// </summary>
+    public string ConsumeIdentifier() {
+      foreach (char c in currentToken) {
+        if (('a' <= c && c <= 'z') ||
+            ('A' <= c && c <= 'Z') ||
+            ('0' <= c && c <= '9') ||
+            (c == '_') || (c == '.')) {
+          // OK
+        } else {
+          throw CreateFormatException("Expected identifier.");
+        }
+      }
+
+      string result = currentToken;
+      NextToken();
+      return result;
+    }
+
+    /// <summary>
+    /// If the next token is a 32-bit signed integer, consume it and return its 
+    /// value. Otherwise, throw a FormatException.
+    /// </summary>
+    public int ConsumeInt32()  {
+      try {
+        int result = TextFormat.ParseInt32(currentToken);
+        NextToken();
+        return result;
+      } catch (FormatException e) {
+        throw CreateIntegerParseException(e);
+      }
+    }
+
+    /// <summary>
+    /// If the next token is a 32-bit unsigned integer, consume it and return its
+    /// value. Otherwise, throw a FormatException.
+    /// </summary>
+    public uint ConsumeUInt32() {
+      try {
+        uint result = TextFormat.ParseUInt32(currentToken);
+        NextToken();
+        return result;
+      } catch (FormatException e) {
+        throw CreateIntegerParseException(e);
+      }
+    }
+
+    /// <summary>
+    /// If the next token is a 64-bit signed integer, consume it and return its
+    /// value. Otherwise, throw a FormatException.
+    /// </summary>
+    public long ConsumeInt64() {
+      try {
+        long result = TextFormat.ParseInt64(currentToken);
+        NextToken();
+        return result;
+      } catch (FormatException e) {
+        throw CreateIntegerParseException(e);
+      }
+    }
+
+    /// <summary>
+    /// If the next token is a 64-bit unsigned integer, consume it and return its
+    /// value. Otherwise, throw a FormatException.
+    /// </summary>
+    public ulong ConsumeUInt64() {
+      try {
+        ulong result = TextFormat.ParseUInt64(currentToken);
+        NextToken();
+        return result;
+      } catch (FormatException e) {
+        throw CreateIntegerParseException(e);
+      }
+    }
+
+    /// <summary>
+    /// If the next token is a double, consume it and return its value.
+    /// Otherwise, throw a FormatException.
+    /// </summary>
+    public double ConsumeDouble() {
+      // We need to parse infinity and nan separately because
+      // double.Parse() does not accept "inf", "infinity", or "nan".
+      if (DoubleInfinity.IsMatch(currentToken)) {
+        bool negative = currentToken.StartsWith("-");
+        NextToken();
+        return negative ? double.NegativeInfinity : double.PositiveInfinity;
+      }
+      if (currentToken.Equals("nan", StringComparison.InvariantCultureIgnoreCase)) {
+        NextToken();
+        return Double.NaN;
+      }
+
+      try {
+        double result = double.Parse(currentToken, CultureInfo.InvariantCulture);
+        NextToken();
+        return result;
+      } catch (FormatException e) {
+        throw CreateFloatParseException(e);
+      } catch (OverflowException e) {
+        throw CreateFloatParseException(e);
+      }
+    }
+
+    /// <summary>
+    /// If the next token is a float, consume it and return its value.
+    /// Otherwise, throw a FormatException.
+    /// </summary>
+    public float ConsumeFloat() {
+      // We need to parse infinity and nan separately because
+      // Float.parseFloat() does not accept "inf", "infinity", or "nan".
+      if (FloatInfinity.IsMatch(currentToken)) {
+        bool negative = currentToken.StartsWith("-");
+        NextToken();
+        return negative ? float.NegativeInfinity : float.PositiveInfinity;
+      }
+      if (FloatNan.IsMatch(currentToken)) {
+        NextToken();
+        return float.NaN;
+      }
+
+      if (currentToken.EndsWith("f")) {
+        currentToken = currentToken.TrimEnd('f');
+      }
+
+      try {
+        float result = float.Parse(currentToken, CultureInfo.InvariantCulture);
+        NextToken();
+        return result;
+      } catch (FormatException e) {
+        throw CreateFloatParseException(e);
+      } catch (OverflowException e) {
+        throw CreateFloatParseException(e);
+      }
+    }
+
+    /// <summary>
+    /// If the next token is a Boolean, consume it and return its value.
+    /// Otherwise, throw a FormatException.    
+    /// </summary>
+    public bool ConsumeBoolean() {
+      if (currentToken == "true") {
+        NextToken();
+        return true;
+      } 
+      if (currentToken == "false") {
+        NextToken();
+        return false;
+      }
+      throw CreateFormatException("Expected \"true\" or \"false\".");
+    }
+
+    /// <summary>
+    /// If the next token is a string, consume it and return its (unescaped) value.
+    /// Otherwise, throw a FormatException.
+    /// </summary>
+    public string ConsumeString() {
+      return ConsumeByteString().ToStringUtf8();
+    }
+
+    /// <summary>
+    /// If the next token is a string, consume it, unescape it as a
+    /// ByteString and return it. Otherwise, throw a FormatException.
+    /// </summary>
+    public ByteString ConsumeByteString() {
+      char quote = currentToken.Length > 0 ? currentToken[0] : '\0';
+      if (quote != '\"' && quote != '\'') {
+        throw CreateFormatException("Expected string.");
+      }
+
+      if (currentToken.Length < 2 ||
+          currentToken[currentToken.Length-1] != quote) {
+        throw CreateFormatException("String missing ending quote.");
+      }
+
+      try {
+        string escaped = currentToken.Substring(1, currentToken.Length - 2);
+        ByteString result = TextFormat.UnescapeBytes(escaped);
+        NextToken();
+        return result;
+      } catch (FormatException e) {
+        throw CreateFormatException(e.Message);
+      }
+    }
+
+    /// <summary>
+    /// Returns a format exception with the current line and column numbers
+    /// in the description, suitable for throwing.
+    /// </summary>
+    public FormatException CreateFormatException(string description) {
+      // Note:  People generally prefer one-based line and column numbers.
+      return new FormatException((line + 1) + ":" + (column + 1) + ": " + description);
+    }
+
+    /// <summary>
+    /// Returns a format exception with the line and column numbers of the
+    /// previous token in the description, suitable for throwing.
+    /// </summary>
+    public FormatException CreateFormatExceptionPreviousToken(string description) {
+      // Note:  People generally prefer one-based line and column numbers.
+      return new FormatException((previousLine + 1) + ":" + (previousColumn + 1) + ": " + description);
+    }
+
+    /// <summary>
+    /// Constructs an appropriate FormatException for the given existing exception
+    /// when trying to parse an integer.
+    /// </summary>
+    private FormatException CreateIntegerParseException(FormatException e) {
+      return CreateFormatException("Couldn't parse integer: " + e.Message);
+    }
+
+    /// <summary>
+    /// Constructs an appropriate FormatException for the given existing exception
+    /// when trying to parse a float or double.
+    /// </summary>
+    private FormatException CreateFloatParseException(Exception e) {
+      return CreateFormatException("Couldn't parse number: " + e.Message);
+    }
+  }
+}

+ 73 - 73
src/ProtocolBuffers/ThrowHelper.cs

@@ -1,73 +1,73 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Helper methods for throwing exceptions
-  /// </summary>
-  public static class ThrowHelper {
-
-    /// <summary>
-    /// Throws an ArgumentNullException if the given value is null.
-    /// </summary>
-    public static void ThrowIfNull(object value, string name) {
-      if (value == null) {
-        throw new ArgumentNullException(name);
-      }
-    }
-
-    /// <summary>
-    /// Throws an ArgumentNullException if the given value is null.
-    /// </summary>
-    public static void ThrowIfNull(object value) {
-      if (value == null) {
-        throw new ArgumentNullException();
-      }
-    }
-
-    /// <summary>
-    /// Throws an ArgumentNullException if the given value or any element within it is null.
-    /// </summary>
-    public static void ThrowIfAnyNull<T>(IEnumerable<T> sequence) {
-      foreach (T t in sequence) {
-        if (t == null) {
-          throw new ArgumentNullException();
-        }
-      }
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Helper methods for throwing exceptions
+  /// </summary>
+  public static class ThrowHelper {
+
+    /// <summary>
+    /// Throws an ArgumentNullException if the given value is null.
+    /// </summary>
+    public static void ThrowIfNull(object value, string name) {
+      if (value == null) {
+        throw new ArgumentNullException(name);
+      }
+    }
+
+    /// <summary>
+    /// Throws an ArgumentNullException if the given value is null.
+    /// </summary>
+    public static void ThrowIfNull(object value) {
+      if (value == null) {
+        throw new ArgumentNullException();
+      }
+    }
+
+    /// <summary>
+    /// Throws an ArgumentNullException if the given value or any element within it is null.
+    /// </summary>
+    public static void ThrowIfAnyNull<T>(IEnumerable<T> sequence) {
+      foreach (T t in sequence) {
+        if (t == null) {
+          throw new ArgumentNullException();
+        }
+      }
+    }
+  }
+}

+ 170 - 170
src/ProtocolBuffers/UninitializedMessageException.cs

@@ -1,170 +1,170 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-#if !LITE
-using Google.ProtocolBuffers.Collections;
-using Google.ProtocolBuffers.Descriptors;
-#endif
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// TODO(jonskeet): Write summary text.
-  /// </summary>
-  public sealed class UninitializedMessageException : Exception {
-
-    private readonly IList<string> missingFields;
-
-    private UninitializedMessageException(IList<string> missingFields)
-        : base(BuildDescription(missingFields)) {
-      this.missingFields = new List<string>(missingFields);
-    }
-    /// <summary>
-    /// Returns a read-only list of human-readable names of
-    /// required fields missing from this message. Each name
-    /// is a full path to a field, e.g. "foo.bar[5].baz"
-    /// </summary>
-    public IList<string> MissingFields {
-      get { return missingFields; }
-    }
-
-    /// <summary>
-    /// Converts this exception into an InvalidProtocolBufferException.
-    /// When a parsed message is missing required fields, this should be thrown
-    /// instead of UninitializedMessageException.
-    /// </summary>
-    public InvalidProtocolBufferException AsInvalidProtocolBufferException() {
-      return new InvalidProtocolBufferException(Message);
-    }
-
-    /// <summary>
-    /// Constructs the description string for a given list of missing fields.
-    /// </summary>
-    private static string BuildDescription(IEnumerable<string> missingFields) {
-      StringBuilder description = new StringBuilder("Message missing required fields: ");
-      bool first = true;
-      foreach(string field in missingFields) {
-        if (first) {
-          first = false;
-        } else {
-          description.Append(", ");
-        }
-        description.Append(field);
-      }
-      return description.ToString();
-    }
-
-    /// <summary>
-    /// For Lite exceptions that do not known how to enumerate missing fields
-    /// </summary>
-    public UninitializedMessageException(IMessageLite message)
-      : base(String.Format("Message {0} is missing required fields", message.GetType())) {
-      missingFields = new List<string>();
-    }
-
-#if !LITE
-    public UninitializedMessageException(IMessage message)
-        : this(FindMissingFields(message)) {
-    }
-
-    /// <summary>
-    /// Returns a list of the full "paths" of missing required
-    /// fields in the specified message.
-    /// </summary>
-    private static IList<String> FindMissingFields(IMessage message) {
-      List<String> results = new List<String>();
-      FindMissingFields(message, "", results);
-      return results;
-    }
-
-    /// <summary>
-    /// Recursive helper implementing FindMissingFields.
-    /// </summary>
-    private static void FindMissingFields(IMessage message, String prefix, List<String> results) {
-      foreach (FieldDescriptor field in message.DescriptorForType.Fields) {
-        if (field.IsRequired && !message.HasField(field)) {
-          results.Add(prefix + field.Name);
-        }
-      }
-
-      foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) {
-        FieldDescriptor field = entry.Key;
-        object value = entry.Value;
-
-        if (field.MappedType == MappedType.Message) {
-          if (field.IsRepeated) {
-            int i = 0;
-            foreach (object element in (IEnumerable) value) {
-              if (element is IMessage) {
-                FindMissingFields((IMessage)element, SubMessagePrefix(prefix, field, i++), results);
-              } else {
-                results.Add(prefix + field.Name);
-              }
-            }
-          } else {
-            if (message.HasField(field)) {
-              if (value is IMessage) {
-                FindMissingFields((IMessage)value, SubMessagePrefix(prefix, field, -1), results);
-              } else {
-                results.Add(prefix + field.Name);
-              }
-            }
-          }
-        }
-      }
-    }
-
-    private static String SubMessagePrefix(String prefix, FieldDescriptor field, int index) {
-      StringBuilder result = new StringBuilder(prefix);
-      if (field.IsExtension) {
-        result.Append('(')
-              .Append(field.FullName)
-              .Append(')');
-      } else {
-        result.Append(field.Name);
-      }
-      if (index != -1) {
-        result.Append('[')
-              .Append(index)
-              .Append(']');
-      }
-      result.Append('.');
-      return result.ToString();
-    }
-#endif
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+#if !LITE
+using Google.ProtocolBuffers.Collections;
+using Google.ProtocolBuffers.Descriptors;
+#endif
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// TODO(jonskeet): Write summary text.
+  /// </summary>
+  public sealed class UninitializedMessageException : Exception {
+
+    private readonly IList<string> missingFields;
+
+    private UninitializedMessageException(IList<string> missingFields)
+        : base(BuildDescription(missingFields)) {
+      this.missingFields = new List<string>(missingFields);
+    }
+    /// <summary>
+    /// Returns a read-only list of human-readable names of
+    /// required fields missing from this message. Each name
+    /// is a full path to a field, e.g. "foo.bar[5].baz"
+    /// </summary>
+    public IList<string> MissingFields {
+      get { return missingFields; }
+    }
+
+    /// <summary>
+    /// Converts this exception into an InvalidProtocolBufferException.
+    /// When a parsed message is missing required fields, this should be thrown
+    /// instead of UninitializedMessageException.
+    /// </summary>
+    public InvalidProtocolBufferException AsInvalidProtocolBufferException() {
+      return new InvalidProtocolBufferException(Message);
+    }
+
+    /// <summary>
+    /// Constructs the description string for a given list of missing fields.
+    /// </summary>
+    private static string BuildDescription(IEnumerable<string> missingFields) {
+      StringBuilder description = new StringBuilder("Message missing required fields: ");
+      bool first = true;
+      foreach(string field in missingFields) {
+        if (first) {
+          first = false;
+        } else {
+          description.Append(", ");
+        }
+        description.Append(field);
+      }
+      return description.ToString();
+    }
+
+    /// <summary>
+    /// For Lite exceptions that do not known how to enumerate missing fields
+    /// </summary>
+    public UninitializedMessageException(IMessageLite message)
+      : base(String.Format("Message {0} is missing required fields", message.GetType())) {
+      missingFields = new List<string>();
+    }
+
+#if !LITE
+    public UninitializedMessageException(IMessage message)
+        : this(FindMissingFields(message)) {
+    }
+
+    /// <summary>
+    /// Returns a list of the full "paths" of missing required
+    /// fields in the specified message.
+    /// </summary>
+    private static IList<String> FindMissingFields(IMessage message) {
+      List<String> results = new List<String>();
+      FindMissingFields(message, "", results);
+      return results;
+    }
+
+    /// <summary>
+    /// Recursive helper implementing FindMissingFields.
+    /// </summary>
+    private static void FindMissingFields(IMessage message, String prefix, List<String> results) {
+      foreach (FieldDescriptor field in message.DescriptorForType.Fields) {
+        if (field.IsRequired && !message.HasField(field)) {
+          results.Add(prefix + field.Name);
+        }
+      }
+
+      foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) {
+        FieldDescriptor field = entry.Key;
+        object value = entry.Value;
+
+        if (field.MappedType == MappedType.Message) {
+          if (field.IsRepeated) {
+            int i = 0;
+            foreach (object element in (IEnumerable) value) {
+              if (element is IMessage) {
+                FindMissingFields((IMessage)element, SubMessagePrefix(prefix, field, i++), results);
+              } else {
+                results.Add(prefix + field.Name);
+              }
+            }
+          } else {
+            if (message.HasField(field)) {
+              if (value is IMessage) {
+                FindMissingFields((IMessage)value, SubMessagePrefix(prefix, field, -1), results);
+              } else {
+                results.Add(prefix + field.Name);
+              }
+            }
+          }
+        }
+      }
+    }
+
+    private static String SubMessagePrefix(String prefix, FieldDescriptor field, int index) {
+      StringBuilder result = new StringBuilder(prefix);
+      if (field.IsExtension) {
+        result.Append('(')
+              .Append(field.FullName)
+              .Append(')');
+      } else {
+        result.Append(field.Name);
+      }
+      if (index != -1) {
+        result.Append('[')
+              .Append(index)
+              .Append(']');
+      }
+      result.Append('.');
+      return result.ToString();
+    }
+#endif
+  }
+}

+ 371 - 371
src/ProtocolBuffers/UnknownField.cs

@@ -1,371 +1,371 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using Google.ProtocolBuffers.Collections;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Represents a single field in an UnknownFieldSet.
-  /// 
-  /// An UnknownField consists of five lists of values. The lists correspond
-   /// to the five "wire types" used in the protocol buffer binary format.
-   /// The wire type of each field can be determined from the encoded form alone,
-   /// without knowing the field's declared type. So, we are able to parse
-   /// unknown values at least this far and separate them. Normally, only one
-   /// of the five lists will contain any values, since it is impossible to
-   /// define a valid message type that declares two different types for the
-   /// same field number. However, the code is designed to allow for the case
-   /// where the same unknown field number is encountered using multiple different
-   /// wire types.
-   /// 
-   /// UnknownField is an immutable class. To construct one, you must use an
-   /// UnknownField.Builder.
-  /// </summary>
-  public sealed class UnknownField {
-
-    private static readonly UnknownField defaultInstance = CreateBuilder().Build();
-    private readonly ReadOnlyCollection<ulong> varintList;
-    private readonly ReadOnlyCollection<uint> fixed32List;
-    private readonly ReadOnlyCollection<ulong> fixed64List;
-    private readonly ReadOnlyCollection<ByteString> lengthDelimitedList;
-    private readonly ReadOnlyCollection<UnknownFieldSet> groupList;
-
-    private UnknownField(ReadOnlyCollection<ulong> varintList,
-        ReadOnlyCollection<uint> fixed32List, 
-        ReadOnlyCollection<ulong> fixed64List, 
-        ReadOnlyCollection<ByteString> lengthDelimitedList, 
-        ReadOnlyCollection<UnknownFieldSet> groupList) {
-      this.varintList = varintList;
-      this.fixed32List = fixed32List;
-      this.fixed64List = fixed64List;
-      this.lengthDelimitedList = lengthDelimitedList;
-      this.groupList = groupList;
-    }
-
-    public static UnknownField DefaultInstance { 
-      get { return defaultInstance; } 
-    }
-
-    /// <summary>
-    /// The list of varint values for this field.
-    /// </summary>
-    public IList<ulong> VarintList {
-      get { return varintList; }
-    }
-
-    /// <summary>
-    /// The list of fixed32 values for this field.
-    /// </summary>
-    public IList<uint> Fixed32List {
-      get { return fixed32List; }
-    }
-
-    /// <summary>
-    /// The list of fixed64 values for this field.
-    /// </summary>
-    public IList<ulong> Fixed64List {
-      get { return fixed64List; }
-    }
-
-    /// <summary>
-    /// The list of length-delimited values for this field.
-    /// </summary>
-    public IList<ByteString> LengthDelimitedList {
-      get { return lengthDelimitedList; }
-    }
-
-    /// <summary>
-    /// The list of embedded group values for this field. These
-    /// are represented using UnknownFieldSets rather than Messages
-    /// since the group's type is presumably unknown.
-    /// </summary>
-    public IList<UnknownFieldSet> GroupList {
-      get { return groupList; }
-    }
-
-    public override bool Equals(object other) {
-      if (ReferenceEquals(this, other)) {
-        return true;
-      }
-      UnknownField otherField = other as UnknownField;
-      return otherField != null
-        && Lists.Equals(varintList, otherField.varintList)
-        && Lists.Equals(fixed32List, otherField.fixed32List)
-        && Lists.Equals(fixed64List, otherField.fixed64List)
-        && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList)
-        && Lists.Equals(groupList, otherField.groupList);
-    }
-
-    public override int GetHashCode() {
-      int hash = 43;
-      hash = hash * 47 + Lists.GetHashCode(varintList);
-      hash = hash * 47 + Lists.GetHashCode(fixed32List);
-      hash = hash * 47 + Lists.GetHashCode(fixed64List);
-      hash = hash * 47 + Lists.GetHashCode(lengthDelimitedList);
-      hash = hash * 47 + Lists.GetHashCode(groupList);
-      return hash;
-    }
-
-    /// <summary>
-    /// Constructs a new Builder.
-    /// </summary>
-    public static Builder CreateBuilder() {
-      return new Builder();
-    }
-
-    /// <summary>
-    /// Constructs a new Builder and initializes it to a copy of <paramref name="copyFrom"/>.
-    /// </summary>
-    public static Builder CreateBuilder(UnknownField copyFrom) {
-      return new Builder().MergeFrom(copyFrom);
-    }
-   
-    /// <summary>
-    /// Serializes the field, including the field number, and writes it to
-    /// <paramref name="output"/>.
-    /// </summary>
-    public void WriteTo(int fieldNumber, CodedOutputStream output) {
-      foreach (ulong value in varintList) {
-        output.WriteUInt64(fieldNumber, value);
-      }
-      foreach (uint value in fixed32List) {
-        output.WriteFixed32(fieldNumber, value);
-      }
-      foreach (ulong value in fixed64List) {
-        output.WriteFixed64(fieldNumber, value);
-      }
-      foreach (ByteString value in lengthDelimitedList) {
-        output.WriteBytes(fieldNumber, value);
-      }
-      foreach (UnknownFieldSet value in groupList) {
-#pragma warning disable 0612
-        output.WriteUnknownGroup(fieldNumber, value);
-#pragma warning restore 0612
-      }
-    }
-
-    /// <summary>
-    /// Computes the number of bytes required to encode this field, including field
-    /// number.
-    /// </summary>
-    public int GetSerializedSize(int fieldNumber) {
-      int result = 0;
-      foreach (ulong value in varintList) {
-        result += CodedOutputStream.ComputeUInt64Size(fieldNumber, value);
-      }
-      foreach (uint value in fixed32List) {
-        result += CodedOutputStream.ComputeFixed32Size(fieldNumber, value);
-      }
-      foreach (ulong value in fixed64List) {
-        result += CodedOutputStream.ComputeFixed64Size(fieldNumber, value);
-      }
-      foreach (ByteString value in lengthDelimitedList) {
-        result += CodedOutputStream.ComputeBytesSize(fieldNumber, value);
-      }
-      foreach (UnknownFieldSet value in groupList) {
-#pragma warning disable 0612
-        result += CodedOutputStream.ComputeUnknownGroupSize(fieldNumber, value);
-#pragma warning restore 0612
-      }
-      return result;
-    }
-
-    /// <summary>
-    /// Serializes the length-delimited values of the field, including field
-    /// number, and writes them to <paramref name="output"/> using the MessageSet wire format.
-    /// </summary>
-    /// <param name="fieldNumber"></param>
-    /// <param name="output"></param>
-    public void WriteAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) {
-      foreach (ByteString value in lengthDelimitedList) {
-        output.WriteRawMessageSetExtension(fieldNumber, value);
-      }
-    }
-
-    /// <summary>
-    /// Get the number of bytes required to encode this field, incuding field number,
-    /// using the MessageSet wire format.
-    /// </summary>
-    public int GetSerializedSizeAsMessageSetExtension(int fieldNumber) {
-      int result = 0;
-      foreach (ByteString value in lengthDelimitedList) {
-        result += CodedOutputStream.ComputeRawMessageSetExtensionSize(fieldNumber, value);
-      }
-      return result;
-    }
-
-    /// <summary>
-    /// Used to build instances of UnknownField.
-    /// </summary>
-    public sealed class Builder {
-
-      private List<ulong> varintList;
-      private List<uint> fixed32List;
-      private List<ulong> fixed64List;
-      private List<ByteString> lengthDelimitedList;
-      private List<UnknownFieldSet> groupList;
-
-      /// <summary>
-      /// Builds the field. After building, the builder is reset to an empty
-      /// state. (This is actually easier than making it unusable.)
-      /// </summary>
-      public UnknownField Build() {
-        return new UnknownField(MakeReadOnly(ref varintList),
-            MakeReadOnly(ref fixed32List),
-            MakeReadOnly(ref fixed64List),
-            MakeReadOnly(ref lengthDelimitedList),
-            MakeReadOnly(ref groupList));
-      }
-
-      /// <summary>
-      /// Merge the values in <paramref name="other" /> into this field.  For each list
-      /// of values, <paramref name="other"/>'s values are append to the ones in this
-      /// field.
-      /// </summary>
-      public Builder MergeFrom(UnknownField other) {
-        varintList = AddAll(varintList, other.VarintList);
-        fixed32List = AddAll(fixed32List, other.Fixed32List);
-        fixed64List = AddAll(fixed64List, other.Fixed64List);
-        lengthDelimitedList = AddAll(lengthDelimitedList, other.LengthDelimitedList);
-        groupList = AddAll(groupList, other.GroupList);
-        return this;
-      }
-
-      /// <summary>
-      /// Returns a new list containing all of the given specified values from
-      /// both the <paramref name="current"/> and <paramref name="extras"/> lists.
-      /// If <paramref name="current" /> is null and <paramref name="extras"/> is empty,
-      /// null is returned. Otherwise, either a new list is created (if <paramref name="current" />
-      /// is null) or the elements of <paramref name="extras"/> are added to <paramref name="current" />.
-      /// </summary>
-      private static List<T> AddAll<T>(List<T> current, IList<T> extras)
-      {
-        if (extras.Count == 0) {
-          return current;
-        }
-           if (current == null) {
-          current = new List<T>(extras);
-        } else {
-          current.AddRange(extras);
-        }
-        return current;
-      }
-
-      /// <summary>
-      /// Clears the contents of this builder.
-      /// </summary>
-      public Builder Clear() {
-        varintList = null;
-        fixed32List = null;
-        fixed64List = null;
-        lengthDelimitedList = null;
-        groupList = null;
-        return this;
-      }
-
-      /// <summary>
-      /// Adds a varint value.
-      /// </summary>
-      [CLSCompliant(false)]
-      public Builder AddVarint(ulong value) {
-        varintList = Add(varintList, value);
-        return this;
-      }
-
-      /// <summary>
-      /// Adds a fixed32 value.
-      /// </summary>
-      [CLSCompliant(false)]
-      public Builder AddFixed32(uint value) {
-        fixed32List = Add(fixed32List, value);
-        return this;
-      }
-
-      /// <summary>
-      /// Adds a fixed64 value.
-      /// </summary>
-      [CLSCompliant(false)]
-      public Builder AddFixed64(ulong value) {
-        fixed64List = Add(fixed64List, value);
-        return this;
-      }
-
-      /// <summary>
-      /// Adds a length-delimited value.
-      /// </summary>
-      public Builder AddLengthDelimited(ByteString value) {
-        lengthDelimitedList = Add(lengthDelimitedList, value);
-        return this;
-      }
-
-      /// <summary>
-      /// Adds an embedded group.
-      /// </summary>
-      /// <param name="value"></param>
-      /// <returns></returns>
-      public Builder AddGroup(UnknownFieldSet value) {
-        groupList = Add(groupList, value);
-        return this;
-      }
-
-      /// <summary>
-      /// Adds <paramref name="value"/> to the <paramref name="list"/>, creating
-      /// a new list if <paramref name="list"/> is null. The list is returned - either
-      /// the original reference or the new list.
-      /// </summary>
-      private static List<T> Add<T>(List<T> list, T value) {
-        if (list == null) {
-          list = new List<T>();
-        }
-        list.Add(value);
-        return list;
-      }
-
-      /// <summary>
-      /// Returns a read-only version of the given IList, and clears
-      /// the field used for <paramref name="list"/>. If the value
-      /// is null, an empty list is produced using Lists.Empty.
-      /// </summary>
-      /// <returns></returns>
-      private static ReadOnlyCollection<T> MakeReadOnly<T>(ref List<T> list) {
-        ReadOnlyCollection<T> ret = list == null ? Lists<T>.Empty : new ReadOnlyCollection<T>(list);
-           list = null;
-        return ret;
-      }
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Google.ProtocolBuffers.Collections;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Represents a single field in an UnknownFieldSet.
+  /// 
+  /// An UnknownField consists of five lists of values. The lists correspond
+   /// to the five "wire types" used in the protocol buffer binary format.
+   /// The wire type of each field can be determined from the encoded form alone,
+   /// without knowing the field's declared type. So, we are able to parse
+   /// unknown values at least this far and separate them. Normally, only one
+   /// of the five lists will contain any values, since it is impossible to
+   /// define a valid message type that declares two different types for the
+   /// same field number. However, the code is designed to allow for the case
+   /// where the same unknown field number is encountered using multiple different
+   /// wire types.
+   /// 
+   /// UnknownField is an immutable class. To construct one, you must use an
+   /// UnknownField.Builder.
+  /// </summary>
+  public sealed class UnknownField {
+
+    private static readonly UnknownField defaultInstance = CreateBuilder().Build();
+    private readonly ReadOnlyCollection<ulong> varintList;
+    private readonly ReadOnlyCollection<uint> fixed32List;
+    private readonly ReadOnlyCollection<ulong> fixed64List;
+    private readonly ReadOnlyCollection<ByteString> lengthDelimitedList;
+    private readonly ReadOnlyCollection<UnknownFieldSet> groupList;
+
+    private UnknownField(ReadOnlyCollection<ulong> varintList,
+        ReadOnlyCollection<uint> fixed32List, 
+        ReadOnlyCollection<ulong> fixed64List, 
+        ReadOnlyCollection<ByteString> lengthDelimitedList, 
+        ReadOnlyCollection<UnknownFieldSet> groupList) {
+      this.varintList = varintList;
+      this.fixed32List = fixed32List;
+      this.fixed64List = fixed64List;
+      this.lengthDelimitedList = lengthDelimitedList;
+      this.groupList = groupList;
+    }
+
+    public static UnknownField DefaultInstance { 
+      get { return defaultInstance; } 
+    }
+
+    /// <summary>
+    /// The list of varint values for this field.
+    /// </summary>
+    public IList<ulong> VarintList {
+      get { return varintList; }
+    }
+
+    /// <summary>
+    /// The list of fixed32 values for this field.
+    /// </summary>
+    public IList<uint> Fixed32List {
+      get { return fixed32List; }
+    }
+
+    /// <summary>
+    /// The list of fixed64 values for this field.
+    /// </summary>
+    public IList<ulong> Fixed64List {
+      get { return fixed64List; }
+    }
+
+    /// <summary>
+    /// The list of length-delimited values for this field.
+    /// </summary>
+    public IList<ByteString> LengthDelimitedList {
+      get { return lengthDelimitedList; }
+    }
+
+    /// <summary>
+    /// The list of embedded group values for this field. These
+    /// are represented using UnknownFieldSets rather than Messages
+    /// since the group's type is presumably unknown.
+    /// </summary>
+    public IList<UnknownFieldSet> GroupList {
+      get { return groupList; }
+    }
+
+    public override bool Equals(object other) {
+      if (ReferenceEquals(this, other)) {
+        return true;
+      }
+      UnknownField otherField = other as UnknownField;
+      return otherField != null
+        && Lists.Equals(varintList, otherField.varintList)
+        && Lists.Equals(fixed32List, otherField.fixed32List)
+        && Lists.Equals(fixed64List, otherField.fixed64List)
+        && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList)
+        && Lists.Equals(groupList, otherField.groupList);
+    }
+
+    public override int GetHashCode() {
+      int hash = 43;
+      hash = hash * 47 + Lists.GetHashCode(varintList);
+      hash = hash * 47 + Lists.GetHashCode(fixed32List);
+      hash = hash * 47 + Lists.GetHashCode(fixed64List);
+      hash = hash * 47 + Lists.GetHashCode(lengthDelimitedList);
+      hash = hash * 47 + Lists.GetHashCode(groupList);
+      return hash;
+    }
+
+    /// <summary>
+    /// Constructs a new Builder.
+    /// </summary>
+    public static Builder CreateBuilder() {
+      return new Builder();
+    }
+
+    /// <summary>
+    /// Constructs a new Builder and initializes it to a copy of <paramref name="copyFrom"/>.
+    /// </summary>
+    public static Builder CreateBuilder(UnknownField copyFrom) {
+      return new Builder().MergeFrom(copyFrom);
+    }
+   
+    /// <summary>
+    /// Serializes the field, including the field number, and writes it to
+    /// <paramref name="output"/>.
+    /// </summary>
+    public void WriteTo(int fieldNumber, CodedOutputStream output) {
+      foreach (ulong value in varintList) {
+        output.WriteUInt64(fieldNumber, value);
+      }
+      foreach (uint value in fixed32List) {
+        output.WriteFixed32(fieldNumber, value);
+      }
+      foreach (ulong value in fixed64List) {
+        output.WriteFixed64(fieldNumber, value);
+      }
+      foreach (ByteString value in lengthDelimitedList) {
+        output.WriteBytes(fieldNumber, value);
+      }
+      foreach (UnknownFieldSet value in groupList) {
+#pragma warning disable 0612
+        output.WriteUnknownGroup(fieldNumber, value);
+#pragma warning restore 0612
+      }
+    }
+
+    /// <summary>
+    /// Computes the number of bytes required to encode this field, including field
+    /// number.
+    /// </summary>
+    public int GetSerializedSize(int fieldNumber) {
+      int result = 0;
+      foreach (ulong value in varintList) {
+        result += CodedOutputStream.ComputeUInt64Size(fieldNumber, value);
+      }
+      foreach (uint value in fixed32List) {
+        result += CodedOutputStream.ComputeFixed32Size(fieldNumber, value);
+      }
+      foreach (ulong value in fixed64List) {
+        result += CodedOutputStream.ComputeFixed64Size(fieldNumber, value);
+      }
+      foreach (ByteString value in lengthDelimitedList) {
+        result += CodedOutputStream.ComputeBytesSize(fieldNumber, value);
+      }
+      foreach (UnknownFieldSet value in groupList) {
+#pragma warning disable 0612
+        result += CodedOutputStream.ComputeUnknownGroupSize(fieldNumber, value);
+#pragma warning restore 0612
+      }
+      return result;
+    }
+
+    /// <summary>
+    /// Serializes the length-delimited values of the field, including field
+    /// number, and writes them to <paramref name="output"/> using the MessageSet wire format.
+    /// </summary>
+    /// <param name="fieldNumber"></param>
+    /// <param name="output"></param>
+    public void WriteAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) {
+      foreach (ByteString value in lengthDelimitedList) {
+        output.WriteRawMessageSetExtension(fieldNumber, value);
+      }
+    }
+
+    /// <summary>
+    /// Get the number of bytes required to encode this field, incuding field number,
+    /// using the MessageSet wire format.
+    /// </summary>
+    public int GetSerializedSizeAsMessageSetExtension(int fieldNumber) {
+      int result = 0;
+      foreach (ByteString value in lengthDelimitedList) {
+        result += CodedOutputStream.ComputeRawMessageSetExtensionSize(fieldNumber, value);
+      }
+      return result;
+    }
+
+    /// <summary>
+    /// Used to build instances of UnknownField.
+    /// </summary>
+    public sealed class Builder {
+
+      private List<ulong> varintList;
+      private List<uint> fixed32List;
+      private List<ulong> fixed64List;
+      private List<ByteString> lengthDelimitedList;
+      private List<UnknownFieldSet> groupList;
+
+      /// <summary>
+      /// Builds the field. After building, the builder is reset to an empty
+      /// state. (This is actually easier than making it unusable.)
+      /// </summary>
+      public UnknownField Build() {
+        return new UnknownField(MakeReadOnly(ref varintList),
+            MakeReadOnly(ref fixed32List),
+            MakeReadOnly(ref fixed64List),
+            MakeReadOnly(ref lengthDelimitedList),
+            MakeReadOnly(ref groupList));
+      }
+
+      /// <summary>
+      /// Merge the values in <paramref name="other" /> into this field.  For each list
+      /// of values, <paramref name="other"/>'s values are append to the ones in this
+      /// field.
+      /// </summary>
+      public Builder MergeFrom(UnknownField other) {
+        varintList = AddAll(varintList, other.VarintList);
+        fixed32List = AddAll(fixed32List, other.Fixed32List);
+        fixed64List = AddAll(fixed64List, other.Fixed64List);
+        lengthDelimitedList = AddAll(lengthDelimitedList, other.LengthDelimitedList);
+        groupList = AddAll(groupList, other.GroupList);
+        return this;
+      }
+
+      /// <summary>
+      /// Returns a new list containing all of the given specified values from
+      /// both the <paramref name="current"/> and <paramref name="extras"/> lists.
+      /// If <paramref name="current" /> is null and <paramref name="extras"/> is empty,
+      /// null is returned. Otherwise, either a new list is created (if <paramref name="current" />
+      /// is null) or the elements of <paramref name="extras"/> are added to <paramref name="current" />.
+      /// </summary>
+      private static List<T> AddAll<T>(List<T> current, IList<T> extras)
+      {
+        if (extras.Count == 0) {
+          return current;
+        }
+           if (current == null) {
+          current = new List<T>(extras);
+        } else {
+          current.AddRange(extras);
+        }
+        return current;
+      }
+
+      /// <summary>
+      /// Clears the contents of this builder.
+      /// </summary>
+      public Builder Clear() {
+        varintList = null;
+        fixed32List = null;
+        fixed64List = null;
+        lengthDelimitedList = null;
+        groupList = null;
+        return this;
+      }
+
+      /// <summary>
+      /// Adds a varint value.
+      /// </summary>
+      [CLSCompliant(false)]
+      public Builder AddVarint(ulong value) {
+        varintList = Add(varintList, value);
+        return this;
+      }
+
+      /// <summary>
+      /// Adds a fixed32 value.
+      /// </summary>
+      [CLSCompliant(false)]
+      public Builder AddFixed32(uint value) {
+        fixed32List = Add(fixed32List, value);
+        return this;
+      }
+
+      /// <summary>
+      /// Adds a fixed64 value.
+      /// </summary>
+      [CLSCompliant(false)]
+      public Builder AddFixed64(ulong value) {
+        fixed64List = Add(fixed64List, value);
+        return this;
+      }
+
+      /// <summary>
+      /// Adds a length-delimited value.
+      /// </summary>
+      public Builder AddLengthDelimited(ByteString value) {
+        lengthDelimitedList = Add(lengthDelimitedList, value);
+        return this;
+      }
+
+      /// <summary>
+      /// Adds an embedded group.
+      /// </summary>
+      /// <param name="value"></param>
+      /// <returns></returns>
+      public Builder AddGroup(UnknownFieldSet value) {
+        groupList = Add(groupList, value);
+        return this;
+      }
+
+      /// <summary>
+      /// Adds <paramref name="value"/> to the <paramref name="list"/>, creating
+      /// a new list if <paramref name="list"/> is null. The list is returned - either
+      /// the original reference or the new list.
+      /// </summary>
+      private static List<T> Add<T>(List<T> list, T value) {
+        if (list == null) {
+          list = new List<T>();
+        }
+        list.Add(value);
+        return list;
+      }
+
+      /// <summary>
+      /// Returns a read-only version of the given IList, and clears
+      /// the field used for <paramref name="list"/>. If the value
+      /// is null, an empty list is produced using Lists.Empty.
+      /// </summary>
+      /// <returns></returns>
+      private static ReadOnlyCollection<T> MakeReadOnly<T>(ref List<T> list) {
+        ReadOnlyCollection<T> ret = list == null ? Lists<T>.Empty : new ReadOnlyCollection<T>(list);
+           list = null;
+        return ret;
+      }
+    }
+  }
+}

+ 768 - 768
src/ProtocolBuffers/UnknownFieldSet.cs

@@ -1,768 +1,768 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Google.ProtocolBuffers.Collections;
-using Google.ProtocolBuffers.Descriptors;
-using Google.ProtocolBuffers.DescriptorProtos;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Used to keep track of fields which were seen when parsing a protocol message
-  /// but whose field numbers or types are unrecognized. This most frequently
-  /// occurs when new fields are added to a message type and then messages containing
-  /// those fields are read by old software that was built before the new types were
-  /// added.
-  /// 
-  /// Every message contains an UnknownFieldSet.
-  /// 
-  /// Most users will never need to use this class directly.
-  /// </summary>
-  public sealed class UnknownFieldSet : IMessageLite {
-
-    private static readonly UnknownFieldSet defaultInstance = new UnknownFieldSet(new Dictionary<int, UnknownField>());
-
-    private readonly IDictionary<int, UnknownField> fields;
-
-    private UnknownFieldSet(IDictionary<int, UnknownField> fields) {
-      this.fields = fields;
-    }
-
-    /// <summary>
-    /// Creates a new unknown field set builder.
-    /// </summary>
-    public static Builder CreateBuilder() {
-      return new Builder();
-    }
-
-    /// <summary>
-    /// Creates a new unknown field set builder 
-    /// and initialize it from <paramref name="original"/>.
-    /// </summary>
-    public static Builder CreateBuilder(UnknownFieldSet original) {
-      return new Builder().MergeFrom(original);
-    }
-
-    public static UnknownFieldSet DefaultInstance {
-      get { return defaultInstance; }
-    }
-
-    /// <summary>
-    /// Returns a read-only view of the mapping from field numbers to values.
-    /// </summary>
-    public IDictionary<int, UnknownField> FieldDictionary {
-      get { return Dictionaries.AsReadOnly(fields); }
-    }
-
-    /// <summary>
-    /// Checks whether or not the given field number is present in the set.
-    /// </summary>
-    public bool HasField(int field) {
-      return fields.ContainsKey(field);
-    }
-
-    /// <summary>
-    /// Fetches a field by number, returning an empty field if not present.
-    /// Never returns null.
-    /// </summary>
-    public UnknownField this[int number] {
-      get {
-        UnknownField ret;
-        if (!fields.TryGetValue(number, out ret)) {
-          ret = UnknownField.DefaultInstance;
-        }
-        return ret;
-      }
-    }
-
-    /// <summary>
-    /// Serializes the set and writes it to <paramref name="output"/>.
-    /// </summary>
-    public void WriteTo(CodedOutputStream output) {
-      foreach (KeyValuePair<int, UnknownField> entry in fields) {
-        entry.Value.WriteTo(entry.Key, output);
-      }
-    }
-
-    /// <summary>
-    /// Gets the number of bytes required to encode this set.
-    /// </summary>
-    public int SerializedSize { 
-      get {
-        int result = 0;
-        foreach (KeyValuePair<int, UnknownField> entry in fields) {
-          result += entry.Value.GetSerializedSize(entry.Key);
-        }
-        return result;
-      } 
-    }
-
-    /// <summary>
-    /// Converts the set to a string in protocol buffer text format. This
-    /// is just a trivial wrapper around TextFormat.PrintToString.
-    /// </summary>
-    public override String ToString() {
-      return TextFormat.PrintToString(this);
-    }
-
-    /// <summary>
-    /// Converts the set to a string in protocol buffer text format. This
-    /// is just a trivial wrapper around TextFormat.PrintToString.
-    /// </summary>
-    public void PrintTo(TextWriter writer) {
-      TextFormat.Print(this, writer);
-    }
-
-    /// <summary>
-    /// Serializes the message to a ByteString and returns it. This is
-    /// just a trivial wrapper around WriteTo(CodedOutputStream).
-    /// </summary>
-    /// <returns></returns>
-    public ByteString ToByteString() {
-      ByteString.CodedBuilder codedBuilder = new ByteString.CodedBuilder(SerializedSize);
-      WriteTo(codedBuilder.CodedOutput);
-      return codedBuilder.Build();
-    }
-
-    /// <summary>
-    /// Serializes the message to a byte array and returns it. This is
-    /// just a trivial wrapper around WriteTo(CodedOutputStream).
-    /// </summary>
-    /// <returns></returns>
-    public byte[] ToByteArray() {
-      byte[] data = new byte[SerializedSize];
-      CodedOutputStream output = CodedOutputStream.CreateInstance(data);
-      WriteTo(output);
-      output.CheckNoSpaceLeft();
-      return data;
-    }
-
-    /// <summary>
-    /// Serializes the message and writes it to <paramref name="output"/>. This is
-    /// just a trivial wrapper around WriteTo(CodedOutputStream).
-    /// </summary>
-    /// <param name="output"></param>
-    public void WriteTo(Stream output) {
-      CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
-      WriteTo(codedOutput);
-      codedOutput.Flush();
-    }
-
-    /// <summary>
-    /// Serializes the set and writes it to <paramref name="output"/> using
-    /// the MessageSet wire format.
-    /// </summary>
-    public void WriteAsMessageSetTo(CodedOutputStream output) {
-      foreach (KeyValuePair<int, UnknownField> entry in fields) {
-        entry.Value.WriteAsMessageSetExtensionTo(entry.Key, output);
-      }
-    }
-
-    /// <summary>
-    /// Gets the number of bytes required to encode this set using the MessageSet
-    /// wire format.
-    /// </summary>
-    public int SerializedSizeAsMessageSet {
-      get {
-        int result = 0;
-        foreach (KeyValuePair<int, UnknownField> entry in fields) {
-          result += entry.Value.GetSerializedSizeAsMessageSetExtension(entry.Key);
-        }
-        return result;
-      }
-    }
-
-    public override bool Equals(object other) {
-      if (ReferenceEquals(this, other)) {
-        return true;
-      }
-      UnknownFieldSet otherSet = other as UnknownFieldSet;
-      return otherSet != null && Dictionaries.Equals(fields, otherSet.fields);
-    }
-
-    public override int GetHashCode() {
-      return Dictionaries.GetHashCode(fields);
-    }
-
-    /// <summary>
-    /// Parses an UnknownFieldSet from the given input.
-    /// </summary>
-    public static UnknownFieldSet ParseFrom(CodedInputStream input) {
-      return CreateBuilder().MergeFrom(input).Build();
-    }
-
-    /// <summary>
-    /// Parses an UnknownFieldSet from the given data.
-    /// </summary>
-    public static UnknownFieldSet ParseFrom(ByteString data) {
-      return CreateBuilder().MergeFrom(data).Build();
-    }
-
-    /// <summary>
-    /// Parses an UnknownFieldSet from the given data.
-    /// </summary>
-    public static UnknownFieldSet ParseFrom(byte[] data) {
-      return CreateBuilder().MergeFrom(data).Build();
-    }
-
-    /// <summary>
-    /// Parses an UnknownFieldSet from the given input.
-    /// </summary>
-    public static UnknownFieldSet ParseFrom(Stream input) {
-      return CreateBuilder().MergeFrom(input).Build();
-    }
-
-    #region IMessageLite Members
-
-    public bool IsInitialized {
-      get { return fields != null; }
-    }
-
-    public void WriteDelimitedTo(Stream output) {
-      CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
-      codedOutput.WriteRawVarint32((uint) SerializedSize);
-      WriteTo(codedOutput);
-      codedOutput.Flush();
-    }
-
-    public IBuilderLite WeakCreateBuilderForType() {
-      return new Builder();
-    }
-
-    public IBuilderLite WeakToBuilder() {
-      return new Builder(fields);
-    }
-
-    public IMessageLite WeakDefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-
-    #endregion
-
-    /// <summary>
-    /// Builder for UnknownFieldSets.
-    /// </summary>
-    public sealed class Builder : IBuilderLite
-    {
-      /// <summary>
-      /// Mapping from number to field. Note that by using a SortedList we ensure
-      /// that the fields will be serialized in ascending order.
-      /// </summary>
-      private IDictionary<int, UnknownField> fields;
-      // Optimization:  We keep around a builder for the last field that was
-      // modified so that we can efficiently add to it multiple times in a
-      // row (important when parsing an unknown repeated field).
-      private int lastFieldNumber;
-      private UnknownField.Builder lastField;
-
-      internal Builder() {
-        fields = new SortedList<int, UnknownField>();
-      }
-
-      internal Builder(IDictionary<int, UnknownField> dictionary) {
-        fields = new SortedList<int, UnknownField>(dictionary); 
-      }
-
-      /// <summary>
-      /// Returns a field builder for the specified field number, including any values
-      /// which already exist.
-      /// </summary>
-      private UnknownField.Builder GetFieldBuilder(int number) {
-        if (lastField != null) {
-          if (number == lastFieldNumber) {
-            return lastField;
-          }
-          // Note: AddField() will reset lastField and lastFieldNumber.
-          AddField(lastFieldNumber, lastField.Build());
-        }
-        if (number == 0) {
-          return null;
-        }
-
-        lastField = UnknownField.CreateBuilder();
-        UnknownField existing;
-        if (fields.TryGetValue(number, out existing)) {
-          lastField.MergeFrom(existing);
-        }
-        lastFieldNumber = number;
-        return lastField;
-      }
-
-      /// <summary>
-      /// Build the UnknownFieldSet and return it. Once this method has been called,
-      /// this instance will no longer be usable. Calling any method after this
-      /// will throw a NullReferenceException.
-      /// </summary>
-      public UnknownFieldSet Build() {
-        GetFieldBuilder(0);  // Force lastField to be built.
-        UnknownFieldSet result = fields.Count == 0 ? DefaultInstance : new UnknownFieldSet(fields);
-        fields = null;
-        return result;
-      }
-
-      /// <summary>
-      /// Adds a field to the set. If a field with the same number already exists, it
-      /// is replaced.
-      /// </summary>
-      public Builder AddField(int number, UnknownField field) {
-        if (number == 0) {
-          throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
-        }
-        if (lastField != null && lastFieldNumber == number) {
-          // Discard this.
-          lastField = null;
-          lastFieldNumber = 0;
-        }
-        fields[number] = field;
-        return this;
-      }
-
-      /// <summary>
-      /// Resets the builder to an empty set.
-      /// </summary>
-      public Builder Clear() {
-        fields.Clear();
-        lastFieldNumber = 0;
-        lastField = null;
-        return this;
-      }
-      
-      /// <summary>
-      /// Parse an entire message from <paramref name="input"/> and merge
-      /// its fields into this set.
-      /// </summary>
-      public Builder MergeFrom(CodedInputStream input) {
-        while (true) {
-          uint tag = input.ReadTag();
-          if (tag == 0 || !MergeFieldFrom(tag, input)) {
-            break;
-          }
-        }
-        return this;
-      }
-
-        /// <summary>
-        /// Parse a single field from <paramref name="input"/> and merge it
-        /// into this set.
-        /// </summary>
-        /// <param name="tag">The field's tag number, which was already parsed.</param>
-        /// <param name="input">The coded input stream containing the field</param>
-        /// <returns>false if the tag is an "end group" tag, true otherwise</returns>
-      [CLSCompliant(false)]
-      public bool MergeFieldFrom(uint tag, CodedInputStream input) {
-        int number = WireFormat.GetTagFieldNumber(tag);
-        switch (WireFormat.GetTagWireType(tag)) {
-          case WireFormat.WireType.Varint:
-            GetFieldBuilder(number).AddVarint(input.ReadUInt64());
-            return true;
-          case WireFormat.WireType.Fixed64:
-            GetFieldBuilder(number).AddFixed64(input.ReadFixed64());
-            return true;
-          case WireFormat.WireType.LengthDelimited:
-            GetFieldBuilder(number).AddLengthDelimited(input.ReadBytes());
-            return true;
-          case WireFormat.WireType.StartGroup: {
-            Builder subBuilder = CreateBuilder();
-#pragma warning disable 0612
-            input.ReadUnknownGroup(number, subBuilder);
-#pragma warning restore 0612
-            GetFieldBuilder(number).AddGroup(subBuilder.Build());
-            return true;
-          }
-          case WireFormat.WireType.EndGroup:
-            return false;
-          case WireFormat.WireType.Fixed32:
-            GetFieldBuilder(number).AddFixed32(input.ReadFixed32());
-            return true;
-          default:
-            throw InvalidProtocolBufferException.InvalidWireType();
-        }
-      }
-
-      /// <summary>
-      /// Parses <paramref name="input"/> as an UnknownFieldSet and merge it
-      /// with the set being built. This is just a small wrapper around
-      /// MergeFrom(CodedInputStream).
-      /// </summary>
-      public Builder MergeFrom(Stream input) {
-        CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
-        MergeFrom(codedInput);
-        codedInput.CheckLastTagWas(0);
-        return this;
-      }
-
-      /// <summary>
-      /// Parses <paramref name="data"/> as an UnknownFieldSet and merge it
-      /// with the set being built. This is just a small wrapper around
-      /// MergeFrom(CodedInputStream).
-      /// </summary>
-      public Builder MergeFrom(ByteString data) {
-        CodedInputStream input = data.CreateCodedInput();
-        MergeFrom(input);
-        input.CheckLastTagWas(0);
-        return this;
-      }
-
-      /// <summary>
-      /// Parses <paramref name="data"/> as an UnknownFieldSet and merge it
-      /// with the set being built. This is just a small wrapper around
-      /// MergeFrom(CodedInputStream).
-      /// </summary>
-      public Builder MergeFrom(byte[] data) {
-        CodedInputStream input = CodedInputStream.CreateInstance(data);
-        MergeFrom(input);
-        input.CheckLastTagWas(0);
-        return this;
-      }
-
-      /// <summary>
-      /// Convenience method for merging a new field containing a single varint
-      /// value.  This is used in particular when an unknown enum value is
-      /// encountered.
-      /// </summary>
-      [CLSCompliant(false)]
-      public Builder MergeVarintField(int number, ulong value) {
-        if (number == 0) {
-          throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
-        }
-        GetFieldBuilder(number).AddVarint(value);
-        return this;
-      }
-
-      /// <summary>
-      /// Merges the fields from <paramref name="other"/> into this set.
-      /// If a field number exists in both sets, the values in <paramref name="other"/>
-      /// will be appended to the values in this set.
-      /// </summary>
-      public Builder MergeFrom(UnknownFieldSet other) {
-        if (other != DefaultInstance) {
-          foreach(KeyValuePair<int, UnknownField> entry in other.fields) {
-            MergeField(entry.Key, entry.Value);
-          }
-        }
-        return this;
-      }
-
-      /// <summary>
-      /// Checks if the given field number is present in the set.
-      /// </summary>
-      public bool HasField(int number) {
-        if (number == 0) {
-          throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
-        }
-        return number == lastFieldNumber || fields.ContainsKey(number);
-      }
-
-      /// <summary>
-      /// Adds a field to the unknown field set. If a field with the same
-      /// number already exists, the two are merged.
-      /// </summary>
-      public Builder MergeField(int number, UnknownField field) {
-        if (number == 0) {
-          throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
-        }
-        if (HasField(number)) {
-          GetFieldBuilder(number).MergeFrom(field);
-        } else {
-          // Optimization:  We could call getFieldBuilder(number).mergeFrom(field)
-          // in this case, but that would create a copy of the Field object.
-          // We'd rather reuse the one passed to us, so call AddField() instead.
-          AddField(number, field);
-        }
-        return this;
-      }
-
-      internal void MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder) {
-        while (true) {
-          uint tag = input.ReadTag();
-          if (tag == 0) {
-            break;
-          }
-
-          if (!MergeFieldFrom(input, extensionRegistry, builder, tag)) {
-            // end group tag
-            break;
-          }
-        }
-      }
-
-      /// <summary>
-      /// Like <see cref="MergeFrom(CodedInputStream, ExtensionRegistry, IBuilder)" />
-      /// but parses a single field.
-      /// </summary>
-      /// <param name="input">The input to read the field from</param>
-      /// <param name="extensionRegistry">Registry to use when an extension field is encountered</param>
-      /// <param name="builder">Builder to merge field into, if it's a known field</param>
-      /// <param name="tag">The tag, which should already have been read from the input</param>
-      /// <returns>true unless the tag is an end-group tag</returns>
-      internal bool MergeFieldFrom(CodedInputStream input,
-          ExtensionRegistry extensionRegistry, IBuilder builder, uint tag) {
-
-        MessageDescriptor type = builder.DescriptorForType;
-        if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart) {
-          MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder);
-          return true;
-        }
-
-        WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
-        int fieldNumber = WireFormat.GetTagFieldNumber(tag);
-
-        FieldDescriptor field;
-        IMessageLite defaultFieldInstance = null;
-
-        if (type.IsExtensionNumber(fieldNumber)) {
-          ExtensionInfo extension = extensionRegistry[type, fieldNumber];
-          if (extension == null) {
-            field = null;
-          } else {
-            field = extension.Descriptor;
-            defaultFieldInstance = extension.DefaultInstance;
-          }
-        } else {
-          field = type.FindFieldByNumber(fieldNumber);
-        }
-
-        // Unknown field or wrong wire type. Skip.
-        if (field == null || wireType != WireFormat.GetWireType(field)) {
-          return MergeFieldFrom(tag, input);
-        }
-
-        if (field.IsPacked) {
-          int length = (int)input.ReadRawVarint32();
-          int limit = input.PushLimit(length);
-          if (field.FieldType == FieldType.Enum) {
-            while (!input.ReachedLimit) {
-              int rawValue = input.ReadEnum();
-              object value = field.EnumType.FindValueByNumber(rawValue);
-              if (value == null) {
-                // If the number isn't recognized as a valid value for this
-                // enum, drop it (don't even add it to unknownFields).
-                return true;
-              }
-              builder.WeakAddRepeatedField(field, value);
-            }
-          } else {
-            while (!input.ReachedLimit) {
-              Object value = input.ReadPrimitiveField(field.FieldType);
-              builder.WeakAddRepeatedField(field, value);
-            }
-          }
-          input.PopLimit(limit);
-        } else {
-          object value;
-          switch (field.FieldType) {
-            case FieldType.Group:
-            case FieldType.Message: {
-                IBuilderLite subBuilder;
-                if (defaultFieldInstance != null) {
-                  subBuilder = defaultFieldInstance.WeakCreateBuilderForType();
-                } else {
-                  subBuilder = builder.CreateBuilderForField(field);
-                }
-                if (!field.IsRepeated) {
-                  subBuilder.WeakMergeFrom((IMessageLite)builder[field]);
-                }
-                if (field.FieldType == FieldType.Group) {
-                  input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
-                } else {
-                  input.ReadMessage(subBuilder, extensionRegistry);
-                }
-                value = subBuilder.WeakBuild();
-                break;
-              }
-            case FieldType.Enum: {
-                int rawValue = input.ReadEnum();
-                value = field.EnumType.FindValueByNumber(rawValue);
-                // If the number isn't recognized as a valid value for this enum,
-                // drop it.
-                if (value == null) {
-                  MergeVarintField(fieldNumber, (ulong)rawValue);
-                  return true;
-                }
-                break;
-              }
-            default:
-              value = input.ReadPrimitiveField(field.FieldType);
-              break;
-          }
-          if (field.IsRepeated) {
-            builder.WeakAddRepeatedField(field, value);
-          } else {
-            builder[field] = value;
-          }
-        }
-        return true;
-      }
-
-      /// <summary>
-      /// Called by MergeFieldFrom to parse a MessageSet extension.
-      /// </summary>
-      private void MergeMessageSetExtensionFromCodedStream(CodedInputStream input,
-          ExtensionRegistry extensionRegistry, IBuilder builder) {
-        MessageDescriptor type = builder.DescriptorForType;
-
-        // The wire format for MessageSet is:
-        //   message MessageSet {
-        //     repeated group Item = 1 {
-        //       required int32 typeId = 2;
-        //       required bytes message = 3;
-        //     }
-        //   }
-        // "typeId" is the extension's field number.  The extension can only be
-        // a message type, where "message" contains the encoded bytes of that
-        // message.
-        //
-        // In practice, we will probably never see a MessageSet item in which
-        // the message appears before the type ID, or where either field does not
-        // appear exactly once.  However, in theory such cases are valid, so we
-        // should be prepared to accept them.
-
-        int typeId = 0;
-        ByteString rawBytes = null;  // If we encounter "message" before "typeId"
-        IBuilderLite subBuilder = null;
-        FieldDescriptor field = null;
-
-        while (true) {
-          uint tag = input.ReadTag();
-          if (tag == 0) {
-            break;
-          }
-
-          if (tag == WireFormat.MessageSetTag.TypeID) {
-            typeId = input.ReadInt32();
-            // Zero is not a valid type ID.
-            if (typeId != 0) {
-              ExtensionInfo extension = extensionRegistry[type, typeId];
-              if (extension != null) {
-                field = extension.Descriptor;
-                subBuilder = extension.DefaultInstance.WeakCreateBuilderForType();
-                IMessageLite originalMessage = (IMessageLite)builder[field];
-                if (originalMessage != null) {
-                  subBuilder.WeakMergeFrom(originalMessage);
-                }
-                if (rawBytes != null) {
-                  // We already encountered the message.  Parse it now.
-                  // TODO(jonskeet): Check this is okay. It's subtly different from the Java, as it doesn't create an input stream from rawBytes.
-                  // In fact, why don't we just call MergeFrom(rawBytes)? And what about the extension registry?
-                  subBuilder.WeakMergeFrom(rawBytes.CreateCodedInput());
-                  rawBytes = null;
-                }
-              } else {
-                // Unknown extension number.  If we already saw data, put it
-                // in rawBytes.
-                if (rawBytes != null) {
-                  MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(rawBytes).Build());
-                  rawBytes = null;
-                }
-              }
-            }
-          } else if (tag == WireFormat.MessageSetTag.Message) {
-            if (typeId == 0) {
-              // We haven't seen a type ID yet, so we have to store the raw bytes for now.
-              rawBytes = input.ReadBytes();
-            } else if (subBuilder == null) {
-              // We don't know how to parse this.  Ignore it.
-              MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(input.ReadBytes()).Build());
-            } else {
-              // We already know the type, so we can parse directly from the input
-              // with no copying.  Hooray!
-              input.ReadMessage(subBuilder, extensionRegistry);
-            }
-          } else {
-            // Unknown tag.  Skip it.
-            if (!input.SkipField(tag)) {
-              break;  // end of group
-            }
-          }
-        }
-
-        input.CheckLastTagWas(WireFormat.MessageSetTag.ItemEnd);
-
-        if (subBuilder != null) {
-          builder[field] = subBuilder.WeakBuild();
-        }
-      }
-
-      #region IBuilderLite Members
-
-      bool IBuilderLite.IsInitialized {
-        get { return fields != null; }
-      }
-
-      IBuilderLite IBuilderLite.WeakClear() {
-        return Clear();
-      }
-
-      IBuilderLite IBuilderLite.WeakMergeFrom(IMessageLite message) {
-        return MergeFrom((UnknownFieldSet)message);
-      }
-
-      IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data) {
-        return MergeFrom(data);
-      }
-
-      IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistry registry) {
-        return MergeFrom(data);
-      }
-
-      IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input) {
-        return MergeFrom(input);
-      }
-
-      IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) {
-        return MergeFrom(input);
-      }
-
-      IMessageLite IBuilderLite.WeakBuild() {
-        return Build();
-      }
-
-      IMessageLite IBuilderLite.WeakBuildPartial() {
-        return Build();
-      }
-
-      IBuilderLite IBuilderLite.WeakClone() {
-        return Build().WeakToBuilder();
-      }
-
-      IMessageLite IBuilderLite.WeakDefaultInstanceForType {
-        get { return DefaultInstance; }
-      }
-
-      #endregion
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Google.ProtocolBuffers.Collections;
+using Google.ProtocolBuffers.Descriptors;
+using Google.ProtocolBuffers.DescriptorProtos;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Used to keep track of fields which were seen when parsing a protocol message
+  /// but whose field numbers or types are unrecognized. This most frequently
+  /// occurs when new fields are added to a message type and then messages containing
+  /// those fields are read by old software that was built before the new types were
+  /// added.
+  /// 
+  /// Every message contains an UnknownFieldSet.
+  /// 
+  /// Most users will never need to use this class directly.
+  /// </summary>
+  public sealed class UnknownFieldSet : IMessageLite {
+
+    private static readonly UnknownFieldSet defaultInstance = new UnknownFieldSet(new Dictionary<int, UnknownField>());
+
+    private readonly IDictionary<int, UnknownField> fields;
+
+    private UnknownFieldSet(IDictionary<int, UnknownField> fields) {
+      this.fields = fields;
+    }
+
+    /// <summary>
+    /// Creates a new unknown field set builder.
+    /// </summary>
+    public static Builder CreateBuilder() {
+      return new Builder();
+    }
+
+    /// <summary>
+    /// Creates a new unknown field set builder 
+    /// and initialize it from <paramref name="original"/>.
+    /// </summary>
+    public static Builder CreateBuilder(UnknownFieldSet original) {
+      return new Builder().MergeFrom(original);
+    }
+
+    public static UnknownFieldSet DefaultInstance {
+      get { return defaultInstance; }
+    }
+
+    /// <summary>
+    /// Returns a read-only view of the mapping from field numbers to values.
+    /// </summary>
+    public IDictionary<int, UnknownField> FieldDictionary {
+      get { return Dictionaries.AsReadOnly(fields); }
+    }
+
+    /// <summary>
+    /// Checks whether or not the given field number is present in the set.
+    /// </summary>
+    public bool HasField(int field) {
+      return fields.ContainsKey(field);
+    }
+
+    /// <summary>
+    /// Fetches a field by number, returning an empty field if not present.
+    /// Never returns null.
+    /// </summary>
+    public UnknownField this[int number] {
+      get {
+        UnknownField ret;
+        if (!fields.TryGetValue(number, out ret)) {
+          ret = UnknownField.DefaultInstance;
+        }
+        return ret;
+      }
+    }
+
+    /// <summary>
+    /// Serializes the set and writes it to <paramref name="output"/>.
+    /// </summary>
+    public void WriteTo(CodedOutputStream output) {
+      foreach (KeyValuePair<int, UnknownField> entry in fields) {
+        entry.Value.WriteTo(entry.Key, output);
+      }
+    }
+
+    /// <summary>
+    /// Gets the number of bytes required to encode this set.
+    /// </summary>
+    public int SerializedSize { 
+      get {
+        int result = 0;
+        foreach (KeyValuePair<int, UnknownField> entry in fields) {
+          result += entry.Value.GetSerializedSize(entry.Key);
+        }
+        return result;
+      } 
+    }
+
+    /// <summary>
+    /// Converts the set to a string in protocol buffer text format. This
+    /// is just a trivial wrapper around TextFormat.PrintToString.
+    /// </summary>
+    public override String ToString() {
+      return TextFormat.PrintToString(this);
+    }
+
+    /// <summary>
+    /// Converts the set to a string in protocol buffer text format. This
+    /// is just a trivial wrapper around TextFormat.PrintToString.
+    /// </summary>
+    public void PrintTo(TextWriter writer) {
+      TextFormat.Print(this, writer);
+    }
+
+    /// <summary>
+    /// Serializes the message to a ByteString and returns it. This is
+    /// just a trivial wrapper around WriteTo(CodedOutputStream).
+    /// </summary>
+    /// <returns></returns>
+    public ByteString ToByteString() {
+      ByteString.CodedBuilder codedBuilder = new ByteString.CodedBuilder(SerializedSize);
+      WriteTo(codedBuilder.CodedOutput);
+      return codedBuilder.Build();
+    }
+
+    /// <summary>
+    /// Serializes the message to a byte array and returns it. This is
+    /// just a trivial wrapper around WriteTo(CodedOutputStream).
+    /// </summary>
+    /// <returns></returns>
+    public byte[] ToByteArray() {
+      byte[] data = new byte[SerializedSize];
+      CodedOutputStream output = CodedOutputStream.CreateInstance(data);
+      WriteTo(output);
+      output.CheckNoSpaceLeft();
+      return data;
+    }
+
+    /// <summary>
+    /// Serializes the message and writes it to <paramref name="output"/>. This is
+    /// just a trivial wrapper around WriteTo(CodedOutputStream).
+    /// </summary>
+    /// <param name="output"></param>
+    public void WriteTo(Stream output) {
+      CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
+      WriteTo(codedOutput);
+      codedOutput.Flush();
+    }
+
+    /// <summary>
+    /// Serializes the set and writes it to <paramref name="output"/> using
+    /// the MessageSet wire format.
+    /// </summary>
+    public void WriteAsMessageSetTo(CodedOutputStream output) {
+      foreach (KeyValuePair<int, UnknownField> entry in fields) {
+        entry.Value.WriteAsMessageSetExtensionTo(entry.Key, output);
+      }
+    }
+
+    /// <summary>
+    /// Gets the number of bytes required to encode this set using the MessageSet
+    /// wire format.
+    /// </summary>
+    public int SerializedSizeAsMessageSet {
+      get {
+        int result = 0;
+        foreach (KeyValuePair<int, UnknownField> entry in fields) {
+          result += entry.Value.GetSerializedSizeAsMessageSetExtension(entry.Key);
+        }
+        return result;
+      }
+    }
+
+    public override bool Equals(object other) {
+      if (ReferenceEquals(this, other)) {
+        return true;
+      }
+      UnknownFieldSet otherSet = other as UnknownFieldSet;
+      return otherSet != null && Dictionaries.Equals(fields, otherSet.fields);
+    }
+
+    public override int GetHashCode() {
+      return Dictionaries.GetHashCode(fields);
+    }
+
+    /// <summary>
+    /// Parses an UnknownFieldSet from the given input.
+    /// </summary>
+    public static UnknownFieldSet ParseFrom(CodedInputStream input) {
+      return CreateBuilder().MergeFrom(input).Build();
+    }
+
+    /// <summary>
+    /// Parses an UnknownFieldSet from the given data.
+    /// </summary>
+    public static UnknownFieldSet ParseFrom(ByteString data) {
+      return CreateBuilder().MergeFrom(data).Build();
+    }
+
+    /// <summary>
+    /// Parses an UnknownFieldSet from the given data.
+    /// </summary>
+    public static UnknownFieldSet ParseFrom(byte[] data) {
+      return CreateBuilder().MergeFrom(data).Build();
+    }
+
+    /// <summary>
+    /// Parses an UnknownFieldSet from the given input.
+    /// </summary>
+    public static UnknownFieldSet ParseFrom(Stream input) {
+      return CreateBuilder().MergeFrom(input).Build();
+    }
+
+    #region IMessageLite Members
+
+    public bool IsInitialized {
+      get { return fields != null; }
+    }
+
+    public void WriteDelimitedTo(Stream output) {
+      CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
+      codedOutput.WriteRawVarint32((uint) SerializedSize);
+      WriteTo(codedOutput);
+      codedOutput.Flush();
+    }
+
+    public IBuilderLite WeakCreateBuilderForType() {
+      return new Builder();
+    }
+
+    public IBuilderLite WeakToBuilder() {
+      return new Builder(fields);
+    }
+
+    public IMessageLite WeakDefaultInstanceForType {
+      get { return defaultInstance; }
+    }
+
+    #endregion
+
+    /// <summary>
+    /// Builder for UnknownFieldSets.
+    /// </summary>
+    public sealed class Builder : IBuilderLite
+    {
+      /// <summary>
+      /// Mapping from number to field. Note that by using a SortedList we ensure
+      /// that the fields will be serialized in ascending order.
+      /// </summary>
+      private IDictionary<int, UnknownField> fields;
+      // Optimization:  We keep around a builder for the last field that was
+      // modified so that we can efficiently add to it multiple times in a
+      // row (important when parsing an unknown repeated field).
+      private int lastFieldNumber;
+      private UnknownField.Builder lastField;
+
+      internal Builder() {
+        fields = new SortedList<int, UnknownField>();
+      }
+
+      internal Builder(IDictionary<int, UnknownField> dictionary) {
+        fields = new SortedList<int, UnknownField>(dictionary); 
+      }
+
+      /// <summary>
+      /// Returns a field builder for the specified field number, including any values
+      /// which already exist.
+      /// </summary>
+      private UnknownField.Builder GetFieldBuilder(int number) {
+        if (lastField != null) {
+          if (number == lastFieldNumber) {
+            return lastField;
+          }
+          // Note: AddField() will reset lastField and lastFieldNumber.
+          AddField(lastFieldNumber, lastField.Build());
+        }
+        if (number == 0) {
+          return null;
+        }
+
+        lastField = UnknownField.CreateBuilder();
+        UnknownField existing;
+        if (fields.TryGetValue(number, out existing)) {
+          lastField.MergeFrom(existing);
+        }
+        lastFieldNumber = number;
+        return lastField;
+      }
+
+      /// <summary>
+      /// Build the UnknownFieldSet and return it. Once this method has been called,
+      /// this instance will no longer be usable. Calling any method after this
+      /// will throw a NullReferenceException.
+      /// </summary>
+      public UnknownFieldSet Build() {
+        GetFieldBuilder(0);  // Force lastField to be built.
+        UnknownFieldSet result = fields.Count == 0 ? DefaultInstance : new UnknownFieldSet(fields);
+        fields = null;
+        return result;
+      }
+
+      /// <summary>
+      /// Adds a field to the set. If a field with the same number already exists, it
+      /// is replaced.
+      /// </summary>
+      public Builder AddField(int number, UnknownField field) {
+        if (number == 0) {
+          throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
+        }
+        if (lastField != null && lastFieldNumber == number) {
+          // Discard this.
+          lastField = null;
+          lastFieldNumber = 0;
+        }
+        fields[number] = field;
+        return this;
+      }
+
+      /// <summary>
+      /// Resets the builder to an empty set.
+      /// </summary>
+      public Builder Clear() {
+        fields.Clear();
+        lastFieldNumber = 0;
+        lastField = null;
+        return this;
+      }
+      
+      /// <summary>
+      /// Parse an entire message from <paramref name="input"/> and merge
+      /// its fields into this set.
+      /// </summary>
+      public Builder MergeFrom(CodedInputStream input) {
+        while (true) {
+          uint tag = input.ReadTag();
+          if (tag == 0 || !MergeFieldFrom(tag, input)) {
+            break;
+          }
+        }
+        return this;
+      }
+
+        /// <summary>
+        /// Parse a single field from <paramref name="input"/> and merge it
+        /// into this set.
+        /// </summary>
+        /// <param name="tag">The field's tag number, which was already parsed.</param>
+        /// <param name="input">The coded input stream containing the field</param>
+        /// <returns>false if the tag is an "end group" tag, true otherwise</returns>
+      [CLSCompliant(false)]
+      public bool MergeFieldFrom(uint tag, CodedInputStream input) {
+        int number = WireFormat.GetTagFieldNumber(tag);
+        switch (WireFormat.GetTagWireType(tag)) {
+          case WireFormat.WireType.Varint:
+            GetFieldBuilder(number).AddVarint(input.ReadUInt64());
+            return true;
+          case WireFormat.WireType.Fixed64:
+            GetFieldBuilder(number).AddFixed64(input.ReadFixed64());
+            return true;
+          case WireFormat.WireType.LengthDelimited:
+            GetFieldBuilder(number).AddLengthDelimited(input.ReadBytes());
+            return true;
+          case WireFormat.WireType.StartGroup: {
+            Builder subBuilder = CreateBuilder();
+#pragma warning disable 0612
+            input.ReadUnknownGroup(number, subBuilder);
+#pragma warning restore 0612
+            GetFieldBuilder(number).AddGroup(subBuilder.Build());
+            return true;
+          }
+          case WireFormat.WireType.EndGroup:
+            return false;
+          case WireFormat.WireType.Fixed32:
+            GetFieldBuilder(number).AddFixed32(input.ReadFixed32());
+            return true;
+          default:
+            throw InvalidProtocolBufferException.InvalidWireType();
+        }
+      }
+
+      /// <summary>
+      /// Parses <paramref name="input"/> as an UnknownFieldSet and merge it
+      /// with the set being built. This is just a small wrapper around
+      /// MergeFrom(CodedInputStream).
+      /// </summary>
+      public Builder MergeFrom(Stream input) {
+        CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
+        MergeFrom(codedInput);
+        codedInput.CheckLastTagWas(0);
+        return this;
+      }
+
+      /// <summary>
+      /// Parses <paramref name="data"/> as an UnknownFieldSet and merge it
+      /// with the set being built. This is just a small wrapper around
+      /// MergeFrom(CodedInputStream).
+      /// </summary>
+      public Builder MergeFrom(ByteString data) {
+        CodedInputStream input = data.CreateCodedInput();
+        MergeFrom(input);
+        input.CheckLastTagWas(0);
+        return this;
+      }
+
+      /// <summary>
+      /// Parses <paramref name="data"/> as an UnknownFieldSet and merge it
+      /// with the set being built. This is just a small wrapper around
+      /// MergeFrom(CodedInputStream).
+      /// </summary>
+      public Builder MergeFrom(byte[] data) {
+        CodedInputStream input = CodedInputStream.CreateInstance(data);
+        MergeFrom(input);
+        input.CheckLastTagWas(0);
+        return this;
+      }
+
+      /// <summary>
+      /// Convenience method for merging a new field containing a single varint
+      /// value.  This is used in particular when an unknown enum value is
+      /// encountered.
+      /// </summary>
+      [CLSCompliant(false)]
+      public Builder MergeVarintField(int number, ulong value) {
+        if (number == 0) {
+          throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
+        }
+        GetFieldBuilder(number).AddVarint(value);
+        return this;
+      }
+
+      /// <summary>
+      /// Merges the fields from <paramref name="other"/> into this set.
+      /// If a field number exists in both sets, the values in <paramref name="other"/>
+      /// will be appended to the values in this set.
+      /// </summary>
+      public Builder MergeFrom(UnknownFieldSet other) {
+        if (other != DefaultInstance) {
+          foreach(KeyValuePair<int, UnknownField> entry in other.fields) {
+            MergeField(entry.Key, entry.Value);
+          }
+        }
+        return this;
+      }
+
+      /// <summary>
+      /// Checks if the given field number is present in the set.
+      /// </summary>
+      public bool HasField(int number) {
+        if (number == 0) {
+          throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
+        }
+        return number == lastFieldNumber || fields.ContainsKey(number);
+      }
+
+      /// <summary>
+      /// Adds a field to the unknown field set. If a field with the same
+      /// number already exists, the two are merged.
+      /// </summary>
+      public Builder MergeField(int number, UnknownField field) {
+        if (number == 0) {
+          throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
+        }
+        if (HasField(number)) {
+          GetFieldBuilder(number).MergeFrom(field);
+        } else {
+          // Optimization:  We could call getFieldBuilder(number).mergeFrom(field)
+          // in this case, but that would create a copy of the Field object.
+          // We'd rather reuse the one passed to us, so call AddField() instead.
+          AddField(number, field);
+        }
+        return this;
+      }
+
+      internal void MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder) {
+        while (true) {
+          uint tag = input.ReadTag();
+          if (tag == 0) {
+            break;
+          }
+
+          if (!MergeFieldFrom(input, extensionRegistry, builder, tag)) {
+            // end group tag
+            break;
+          }
+        }
+      }
+
+      /// <summary>
+      /// Like <see cref="MergeFrom(CodedInputStream, ExtensionRegistry, IBuilder)" />
+      /// but parses a single field.
+      /// </summary>
+      /// <param name="input">The input to read the field from</param>
+      /// <param name="extensionRegistry">Registry to use when an extension field is encountered</param>
+      /// <param name="builder">Builder to merge field into, if it's a known field</param>
+      /// <param name="tag">The tag, which should already have been read from the input</param>
+      /// <returns>true unless the tag is an end-group tag</returns>
+      internal bool MergeFieldFrom(CodedInputStream input,
+          ExtensionRegistry extensionRegistry, IBuilder builder, uint tag) {
+
+        MessageDescriptor type = builder.DescriptorForType;
+        if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart) {
+          MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder);
+          return true;
+        }
+
+        WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
+        int fieldNumber = WireFormat.GetTagFieldNumber(tag);
+
+        FieldDescriptor field;
+        IMessageLite defaultFieldInstance = null;
+
+        if (type.IsExtensionNumber(fieldNumber)) {
+          ExtensionInfo extension = extensionRegistry[type, fieldNumber];
+          if (extension == null) {
+            field = null;
+          } else {
+            field = extension.Descriptor;
+            defaultFieldInstance = extension.DefaultInstance;
+          }
+        } else {
+          field = type.FindFieldByNumber(fieldNumber);
+        }
+
+        // Unknown field or wrong wire type. Skip.
+        if (field == null || wireType != WireFormat.GetWireType(field)) {
+          return MergeFieldFrom(tag, input);
+        }
+
+        if (field.IsPacked) {
+          int length = (int)input.ReadRawVarint32();
+          int limit = input.PushLimit(length);
+          if (field.FieldType == FieldType.Enum) {
+            while (!input.ReachedLimit) {
+              int rawValue = input.ReadEnum();
+              object value = field.EnumType.FindValueByNumber(rawValue);
+              if (value == null) {
+                // If the number isn't recognized as a valid value for this
+                // enum, drop it (don't even add it to unknownFields).
+                return true;
+              }
+              builder.WeakAddRepeatedField(field, value);
+            }
+          } else {
+            while (!input.ReachedLimit) {
+              Object value = input.ReadPrimitiveField(field.FieldType);
+              builder.WeakAddRepeatedField(field, value);
+            }
+          }
+          input.PopLimit(limit);
+        } else {
+          object value;
+          switch (field.FieldType) {
+            case FieldType.Group:
+            case FieldType.Message: {
+                IBuilderLite subBuilder;
+                if (defaultFieldInstance != null) {
+                  subBuilder = defaultFieldInstance.WeakCreateBuilderForType();
+                } else {
+                  subBuilder = builder.CreateBuilderForField(field);
+                }
+                if (!field.IsRepeated) {
+                  subBuilder.WeakMergeFrom((IMessageLite)builder[field]);
+                }
+                if (field.FieldType == FieldType.Group) {
+                  input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
+                } else {
+                  input.ReadMessage(subBuilder, extensionRegistry);
+                }
+                value = subBuilder.WeakBuild();
+                break;
+              }
+            case FieldType.Enum: {
+                int rawValue = input.ReadEnum();
+                value = field.EnumType.FindValueByNumber(rawValue);
+                // If the number isn't recognized as a valid value for this enum,
+                // drop it.
+                if (value == null) {
+                  MergeVarintField(fieldNumber, (ulong)rawValue);
+                  return true;
+                }
+                break;
+              }
+            default:
+              value = input.ReadPrimitiveField(field.FieldType);
+              break;
+          }
+          if (field.IsRepeated) {
+            builder.WeakAddRepeatedField(field, value);
+          } else {
+            builder[field] = value;
+          }
+        }
+        return true;
+      }
+
+      /// <summary>
+      /// Called by MergeFieldFrom to parse a MessageSet extension.
+      /// </summary>
+      private void MergeMessageSetExtensionFromCodedStream(CodedInputStream input,
+          ExtensionRegistry extensionRegistry, IBuilder builder) {
+        MessageDescriptor type = builder.DescriptorForType;
+
+        // The wire format for MessageSet is:
+        //   message MessageSet {
+        //     repeated group Item = 1 {
+        //       required int32 typeId = 2;
+        //       required bytes message = 3;
+        //     }
+        //   }
+        // "typeId" is the extension's field number.  The extension can only be
+        // a message type, where "message" contains the encoded bytes of that
+        // message.
+        //
+        // In practice, we will probably never see a MessageSet item in which
+        // the message appears before the type ID, or where either field does not
+        // appear exactly once.  However, in theory such cases are valid, so we
+        // should be prepared to accept them.
+
+        int typeId = 0;
+        ByteString rawBytes = null;  // If we encounter "message" before "typeId"
+        IBuilderLite subBuilder = null;
+        FieldDescriptor field = null;
+
+        while (true) {
+          uint tag = input.ReadTag();
+          if (tag == 0) {
+            break;
+          }
+
+          if (tag == WireFormat.MessageSetTag.TypeID) {
+            typeId = input.ReadInt32();
+            // Zero is not a valid type ID.
+            if (typeId != 0) {
+              ExtensionInfo extension = extensionRegistry[type, typeId];
+              if (extension != null) {
+                field = extension.Descriptor;
+                subBuilder = extension.DefaultInstance.WeakCreateBuilderForType();
+                IMessageLite originalMessage = (IMessageLite)builder[field];
+                if (originalMessage != null) {
+                  subBuilder.WeakMergeFrom(originalMessage);
+                }
+                if (rawBytes != null) {
+                  // We already encountered the message.  Parse it now.
+                  // TODO(jonskeet): Check this is okay. It's subtly different from the Java, as it doesn't create an input stream from rawBytes.
+                  // In fact, why don't we just call MergeFrom(rawBytes)? And what about the extension registry?
+                  subBuilder.WeakMergeFrom(rawBytes.CreateCodedInput());
+                  rawBytes = null;
+                }
+              } else {
+                // Unknown extension number.  If we already saw data, put it
+                // in rawBytes.
+                if (rawBytes != null) {
+                  MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(rawBytes).Build());
+                  rawBytes = null;
+                }
+              }
+            }
+          } else if (tag == WireFormat.MessageSetTag.Message) {
+            if (typeId == 0) {
+              // We haven't seen a type ID yet, so we have to store the raw bytes for now.
+              rawBytes = input.ReadBytes();
+            } else if (subBuilder == null) {
+              // We don't know how to parse this.  Ignore it.
+              MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(input.ReadBytes()).Build());
+            } else {
+              // We already know the type, so we can parse directly from the input
+              // with no copying.  Hooray!
+              input.ReadMessage(subBuilder, extensionRegistry);
+            }
+          } else {
+            // Unknown tag.  Skip it.
+            if (!input.SkipField(tag)) {
+              break;  // end of group
+            }
+          }
+        }
+
+        input.CheckLastTagWas(WireFormat.MessageSetTag.ItemEnd);
+
+        if (subBuilder != null) {
+          builder[field] = subBuilder.WeakBuild();
+        }
+      }
+
+      #region IBuilderLite Members
+
+      bool IBuilderLite.IsInitialized {
+        get { return fields != null; }
+      }
+
+      IBuilderLite IBuilderLite.WeakClear() {
+        return Clear();
+      }
+
+      IBuilderLite IBuilderLite.WeakMergeFrom(IMessageLite message) {
+        return MergeFrom((UnknownFieldSet)message);
+      }
+
+      IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data) {
+        return MergeFrom(data);
+      }
+
+      IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistry registry) {
+        return MergeFrom(data);
+      }
+
+      IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input) {
+        return MergeFrom(input);
+      }
+
+      IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) {
+        return MergeFrom(input);
+      }
+
+      IMessageLite IBuilderLite.WeakBuild() {
+        return Build();
+      }
+
+      IMessageLite IBuilderLite.WeakBuildPartial() {
+        return Build();
+      }
+
+      IBuilderLite IBuilderLite.WeakClone() {
+        return Build().WeakToBuilder();
+      }
+
+      IMessageLite IBuilderLite.WeakDefaultInstanceForType {
+        get { return DefaultInstance; }
+      }
+
+      #endregion
+    }
+  }
+}

+ 171 - 171
src/ProtocolBuffers/WireFormat.cs

@@ -1,56 +1,56 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-#if !LITE
-using Google.ProtocolBuffers.Descriptors;
-#endif
-
-namespace Google.ProtocolBuffers {
-  
-  /// <summary>
-  /// This class is used internally by the Protocol Buffer Library and generated
-  /// message implementations. It is public only for the sake of those generated
-  /// messages. Others should not use this class directly.
-  /// <para>
-  /// This class contains constants and helper functions useful for dealing with
-  /// the Protocol Buffer wire format.
-  /// </para>
-  /// </summary>
-  public static class WireFormat {
-
-#region Fixed sizes.
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+#if !LITE
+using Google.ProtocolBuffers.Descriptors;
+#endif
+
+namespace Google.ProtocolBuffers {
+  
+  /// <summary>
+  /// This class is used internally by the Protocol Buffer Library and generated
+  /// message implementations. It is public only for the sake of those generated
+  /// messages. Others should not use this class directly.
+  /// <para>
+  /// This class contains constants and helper functions useful for dealing with
+  /// the Protocol Buffer wire format.
+  /// </para>
+  /// </summary>
+  public static class WireFormat {
+
+#region Fixed sizes.
     // TODO(jonskeet): Move these somewhere else. They're messy. Consider making FieldType a smarter kind of enum
     public const int Fixed32Size = 4;
     public const int Fixed64Size = 8;
@@ -58,121 +58,121 @@ namespace Google.ProtocolBuffers {
     public const int SFixed64Size = 8;
     public const int FloatSize = 4;
     public const int DoubleSize = 8;
-    public const int BoolSize = 1;
-#endregion
-
-    [CLSCompliant(false)]
-    public enum WireType : uint {
-      Varint = 0,
-      Fixed64 = 1,
-      LengthDelimited = 2,
-      StartGroup = 3,
-      EndGroup = 4,
-      Fixed32 = 5
-    }
-
-    internal static class MessageSetField {
-      internal const int Item = 1;
-      internal const int TypeID = 2;
-      internal const int Message = 3;
-    }
-
-    internal static class MessageSetTag {
-      internal static readonly uint ItemStart = MakeTag(MessageSetField.Item, WireType.StartGroup);
-      internal static readonly uint ItemEnd = MakeTag(MessageSetField.Item, WireType.EndGroup);
-      internal static readonly uint TypeID = MakeTag(MessageSetField.TypeID, WireType.Varint);
-      internal static readonly uint Message = MakeTag(MessageSetField.Message, WireType.LengthDelimited);
-    }
-  
-    private const int TagTypeBits = 3;
-    private const uint TagTypeMask = (1 << TagTypeBits) - 1;
-
-    /// <summary>
-    /// Given a tag value, determines the wire type (lower 3 bits).
-    /// </summary>
-    [CLSCompliant(false)]
-    public static WireType GetTagWireType(uint tag) {
-      return (WireType) (tag & TagTypeMask);
-    }
-
-    [CLSCompliant(false)]
-    public static bool IsEndGroupTag(uint tag) {
-      return (WireType)(tag & TagTypeMask) == WireType.EndGroup;
-    }
-
-    /// <summary>
-    /// Given a tag value, determines the field number (the upper 29 bits).
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int GetTagFieldNumber(uint tag) {
-      return (int) tag >> TagTypeBits;
-    }
-
-    /// <summary>
-    /// Makes a tag value given a field number and wire type.
-    /// TODO(jonskeet): Should we just have a Tag structure?
-    /// </summary>
-    [CLSCompliant(false)]
-    public static uint MakeTag(int fieldNumber, WireType wireType) {
-      return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
-    }
-
-#if !LITE
-    [CLSCompliant(false)]
-    public static uint MakeTag(FieldDescriptor field) {
-      return MakeTag(field.FieldNumber, GetWireType(field));
-    }
-
-    /// <summary>
-    /// Returns the wire type for the given field descriptor. This differs
-    /// from GetWireType(FieldType) for packed repeated fields.
-    /// </summary>
-    internal static WireType GetWireType(FieldDescriptor descriptor) {
-      return descriptor.IsPacked ? WireType.LengthDelimited : GetWireType(descriptor.FieldType);
-    }
-
-    /// <summary>
-    /// Converts a field type to its wire type. Done with a switch for the sake
-    /// of speed - this is significantly faster than a dictionary lookup.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static WireType GetWireType(FieldType fieldType) {
-      switch (fieldType) {
-        case FieldType.Double:
-          return WireType.Fixed64;
-        case FieldType.Float:
-          return WireType.Fixed32;
-        case FieldType.Int64:
-        case FieldType.UInt64:
-        case FieldType.Int32:
-          return WireType.Varint;
-        case FieldType.Fixed64:
-          return WireType.Fixed64;
-        case FieldType.Fixed32:
-          return WireType.Fixed32;
-        case FieldType.Bool:
-          return WireType.Varint;
-        case FieldType.String:
-          return WireType.LengthDelimited;
-        case FieldType.Group:
-          return WireType.StartGroup;
-        case FieldType.Message:
-        case FieldType.Bytes:
-          return WireType.LengthDelimited;
-        case FieldType.UInt32:
-          return WireType.Varint;
-        case FieldType.SFixed32:
-          return WireType.Fixed32;
-        case FieldType.SFixed64:
-          return WireType.Fixed64;
-        case FieldType.SInt32:
-        case FieldType.SInt64:
-        case FieldType.Enum:
-          return WireType.Varint;
-        default:
-          throw new ArgumentOutOfRangeException("No such field type");
-      }
-    }
-#endif
-  }
-}
+    public const int BoolSize = 1;
+#endregion
+
+    [CLSCompliant(false)]
+    public enum WireType : uint {
+      Varint = 0,
+      Fixed64 = 1,
+      LengthDelimited = 2,
+      StartGroup = 3,
+      EndGroup = 4,
+      Fixed32 = 5
+    }
+
+    internal static class MessageSetField {
+      internal const int Item = 1;
+      internal const int TypeID = 2;
+      internal const int Message = 3;
+    }
+
+    internal static class MessageSetTag {
+      internal static readonly uint ItemStart = MakeTag(MessageSetField.Item, WireType.StartGroup);
+      internal static readonly uint ItemEnd = MakeTag(MessageSetField.Item, WireType.EndGroup);
+      internal static readonly uint TypeID = MakeTag(MessageSetField.TypeID, WireType.Varint);
+      internal static readonly uint Message = MakeTag(MessageSetField.Message, WireType.LengthDelimited);
+    }
+  
+    private const int TagTypeBits = 3;
+    private const uint TagTypeMask = (1 << TagTypeBits) - 1;
+
+    /// <summary>
+    /// Given a tag value, determines the wire type (lower 3 bits).
+    /// </summary>
+    [CLSCompliant(false)]
+    public static WireType GetTagWireType(uint tag) {
+      return (WireType) (tag & TagTypeMask);
+    }
+
+    [CLSCompliant(false)]
+    public static bool IsEndGroupTag(uint tag) {
+      return (WireType)(tag & TagTypeMask) == WireType.EndGroup;
+    }
+
+    /// <summary>
+    /// Given a tag value, determines the field number (the upper 29 bits).
+    /// </summary>
+    [CLSCompliant(false)]
+    public static int GetTagFieldNumber(uint tag) {
+      return (int) tag >> TagTypeBits;
+    }
+
+    /// <summary>
+    /// Makes a tag value given a field number and wire type.
+    /// TODO(jonskeet): Should we just have a Tag structure?
+    /// </summary>
+    [CLSCompliant(false)]
+    public static uint MakeTag(int fieldNumber, WireType wireType) {
+      return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
+    }
+
+#if !LITE
+    [CLSCompliant(false)]
+    public static uint MakeTag(FieldDescriptor field) {
+      return MakeTag(field.FieldNumber, GetWireType(field));
+    }
+
+    /// <summary>
+    /// Returns the wire type for the given field descriptor. This differs
+    /// from GetWireType(FieldType) for packed repeated fields.
+    /// </summary>
+    internal static WireType GetWireType(FieldDescriptor descriptor) {
+      return descriptor.IsPacked ? WireType.LengthDelimited : GetWireType(descriptor.FieldType);
+    }
+
+    /// <summary>
+    /// Converts a field type to its wire type. Done with a switch for the sake
+    /// of speed - this is significantly faster than a dictionary lookup.
+    /// </summary>
+    [CLSCompliant(false)]
+    public static WireType GetWireType(FieldType fieldType) {
+      switch (fieldType) {
+        case FieldType.Double:
+          return WireType.Fixed64;
+        case FieldType.Float:
+          return WireType.Fixed32;
+        case FieldType.Int64:
+        case FieldType.UInt64:
+        case FieldType.Int32:
+          return WireType.Varint;
+        case FieldType.Fixed64:
+          return WireType.Fixed64;
+        case FieldType.Fixed32:
+          return WireType.Fixed32;
+        case FieldType.Bool:
+          return WireType.Varint;
+        case FieldType.String:
+          return WireType.LengthDelimited;
+        case FieldType.Group:
+          return WireType.StartGroup;
+        case FieldType.Message:
+        case FieldType.Bytes:
+          return WireType.LengthDelimited;
+        case FieldType.UInt32:
+          return WireType.Varint;
+        case FieldType.SFixed32:
+          return WireType.Fixed32;
+        case FieldType.SFixed64:
+          return WireType.Fixed64;
+        case FieldType.SInt32:
+        case FieldType.SInt64:
+        case FieldType.Enum:
+          return WireType.Varint;
+        default:
+          throw new ArgumentOutOfRangeException("No such field type");
+      }
+    }
+#endif
+  }
+}

+ 268 - 268
src/ProtocolBuffersLite.Test/AbstractBuilderLiteTest.cs

@@ -1,268 +1,268 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Google.ProtocolBuffers;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class AbstractBuilderLiteTest {
-
-    [Test]
-    public void TestMergeFromCodedInputStream() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
-        .SetOptionalUint32(uint.MaxValue).Build();
-
-      copy = TestAllTypesLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      using (MemoryStream ms = new MemoryStream(msg.ToByteArray())) {
-        CodedInputStream ci = CodedInputStream.CreateInstance(ms);
-        copy = copy.ToBuilder().MergeFrom(ci).Build();
-      }
-
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestIBuilderLiteWeakClear() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.DefaultInstance;
-
-      copy = msg.ToBuilder().SetOptionalString("Should be removed.").Build();
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakClear().WeakBuild();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestBuilderLiteMergeFromCodedInputStream() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
-        .SetOptionalString("Should be merged.").Build();
-
-      copy = TestAllTypesLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      copy = copy.ToBuilder().MergeFrom(CodedInputStream.CreateInstance(new MemoryStream(msg.ToByteArray()))).Build();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestBuilderLiteMergeDelimitedFrom() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
-        .SetOptionalString("Should be merged.").Build();
-
-      copy = TestAllTypesLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-      Stream s = new MemoryStream();
-      msg.WriteDelimitedTo(s);
-      s.Position = 0;
-      copy = copy.ToBuilder().MergeDelimitedFrom(s).Build();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestBuilderLiteMergeDelimitedFromExtensions() {
-      TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder()
-        .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build();
-
-      copy = TestAllExtensionsLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      Stream s = new MemoryStream();
-      msg.WriteDelimitedTo(s);
-      s.Position = 0;
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
-
-      copy = copy.ToBuilder().MergeDelimitedFrom(s, registry).Build();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-      Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite));
-    }
-
-    [Test]
-    public void TestBuilderLiteMergeFromStream() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
-        .SetOptionalString("Should be merged.").Build();
-
-      copy = TestAllTypesLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-      Stream s = new MemoryStream();
-      msg.WriteTo(s);
-      s.Position = 0;
-      copy = copy.ToBuilder().MergeFrom(s).Build();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestBuilderLiteMergeFromStreamExtensions() {
-      TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder()
-        .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build();
-
-      copy = TestAllExtensionsLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      Stream s = new MemoryStream();
-      msg.WriteTo(s);
-      s.Position = 0;
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
-
-      copy = copy.ToBuilder().MergeFrom(s, registry).Build();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-      Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite));
-    }
-
-    [Test]
-    public void TestIBuilderLiteWeakMergeFromIMessageLite() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
-        .SetOptionalString("Should be merged.").Build();
-
-      copy = TestAllTypesLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom((IMessageLite)msg).WeakBuild();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestIBuilderLiteWeakMergeFromByteString() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
-        .SetOptionalString("Should be merged.").Build();
-
-      copy = TestAllTypesLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString()).WeakBuild();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestIBuilderLiteWeakMergeFromByteStringExtensions() {
-      TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder()
-        .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build();
-
-      copy = TestAllExtensionsLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      copy = (TestAllExtensionsLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString(), ExtensionRegistry.Empty).WeakBuild();
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
-
-      copy = (TestAllExtensionsLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString(), registry).WeakBuild();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-      Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite));
-    }
-    
-    [Test]
-    public void TestIBuilderLiteWeakMergeFromCodedInputStream() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
-        .SetOptionalUint32(uint.MaxValue).Build();
-
-      copy = TestAllTypesLite.DefaultInstance;
-      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      using (MemoryStream ms = new MemoryStream(msg.ToByteArray())) {
-        CodedInputStream ci = CodedInputStream.CreateInstance(ms);
-        copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(ci).WeakBuild();
-      }
-
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestIBuilderLiteWeakBuildPartial() {
-      IBuilderLite builder = TestRequiredLite.CreateBuilder();
-      Assert.IsFalse(builder.IsInitialized);
-
-      IMessageLite msg = builder.WeakBuildPartial();
-      Assert.IsFalse(msg.IsInitialized);
-
-      Assert.AreEqual(msg.ToByteArray(), TestRequiredLite.DefaultInstance.ToByteArray());
-    }
-
-    [Test, ExpectedException(typeof(UninitializedMessageException ))]
-    public void TestIBuilderLiteWeakBuildUninitialized() {
-      IBuilderLite builder = TestRequiredLite.CreateBuilder();
-      Assert.IsFalse(builder.IsInitialized);
-      builder.WeakBuild();
-    }
-
-    [Test]
-    public void TestIBuilderLiteWeakBuild() {
-      IBuilderLite builder = TestRequiredLite.CreateBuilder()
-        .SetD(0)
-        .SetEn(ExtraEnum.EXLITE_BAZ);
-      Assert.IsTrue(builder.IsInitialized);
-      builder.WeakBuild();
-    }
-
-    [Test]
-    public void TestIBuilderLiteWeakClone() {
-      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
-        .SetD(1).SetEn(ExtraEnum.EXLITE_BAR).Build();
-      Assert.IsTrue(msg.IsInitialized);
-
-      IMessageLite copy = ((IBuilderLite)msg.ToBuilder()).WeakClone().WeakBuild();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestIBuilderLiteWeakDefaultInstance() {
-      Assert.IsTrue(ReferenceEquals(TestRequiredLite.DefaultInstance,
-        ((IBuilderLite)TestRequiredLite.CreateBuilder()).WeakDefaultInstanceForType));
-    }
-
-    [Test]
-    public void TestGeneratedBuilderLiteAddRange() {
-      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
-        .SetOptionalUint32(123)
-        .AddRepeatedInt32(1)
-        .AddRepeatedInt32(2)
-        .AddRepeatedInt32(3)
-        .Build();
-
-      copy = msg.DefaultInstanceForType.ToBuilder().MergeFrom(msg).Build();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Google.ProtocolBuffers;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers {
+  [TestFixture]
+  public class AbstractBuilderLiteTest {
+
+    [Test]
+    public void TestMergeFromCodedInputStream() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
+        .SetOptionalUint32(uint.MaxValue).Build();
+
+      copy = TestAllTypesLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      using (MemoryStream ms = new MemoryStream(msg.ToByteArray())) {
+        CodedInputStream ci = CodedInputStream.CreateInstance(ms);
+        copy = copy.ToBuilder().MergeFrom(ci).Build();
+      }
+
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestIBuilderLiteWeakClear() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.DefaultInstance;
+
+      copy = msg.ToBuilder().SetOptionalString("Should be removed.").Build();
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakClear().WeakBuild();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestBuilderLiteMergeFromCodedInputStream() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
+        .SetOptionalString("Should be merged.").Build();
+
+      copy = TestAllTypesLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      copy = copy.ToBuilder().MergeFrom(CodedInputStream.CreateInstance(new MemoryStream(msg.ToByteArray()))).Build();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestBuilderLiteMergeDelimitedFrom() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
+        .SetOptionalString("Should be merged.").Build();
+
+      copy = TestAllTypesLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+      Stream s = new MemoryStream();
+      msg.WriteDelimitedTo(s);
+      s.Position = 0;
+      copy = copy.ToBuilder().MergeDelimitedFrom(s).Build();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestBuilderLiteMergeDelimitedFromExtensions() {
+      TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder()
+        .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build();
+
+      copy = TestAllExtensionsLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      Stream s = new MemoryStream();
+      msg.WriteDelimitedTo(s);
+      s.Position = 0;
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
+
+      copy = copy.ToBuilder().MergeDelimitedFrom(s, registry).Build();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+      Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite));
+    }
+
+    [Test]
+    public void TestBuilderLiteMergeFromStream() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
+        .SetOptionalString("Should be merged.").Build();
+
+      copy = TestAllTypesLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+      Stream s = new MemoryStream();
+      msg.WriteTo(s);
+      s.Position = 0;
+      copy = copy.ToBuilder().MergeFrom(s).Build();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestBuilderLiteMergeFromStreamExtensions() {
+      TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder()
+        .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build();
+
+      copy = TestAllExtensionsLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      Stream s = new MemoryStream();
+      msg.WriteTo(s);
+      s.Position = 0;
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
+
+      copy = copy.ToBuilder().MergeFrom(s, registry).Build();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+      Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite));
+    }
+
+    [Test]
+    public void TestIBuilderLiteWeakMergeFromIMessageLite() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
+        .SetOptionalString("Should be merged.").Build();
+
+      copy = TestAllTypesLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom((IMessageLite)msg).WeakBuild();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestIBuilderLiteWeakMergeFromByteString() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
+        .SetOptionalString("Should be merged.").Build();
+
+      copy = TestAllTypesLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString()).WeakBuild();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestIBuilderLiteWeakMergeFromByteStringExtensions() {
+      TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder()
+        .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build();
+
+      copy = TestAllExtensionsLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      copy = (TestAllExtensionsLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString(), ExtensionRegistry.Empty).WeakBuild();
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
+
+      copy = (TestAllExtensionsLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString(), registry).WeakBuild();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+      Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite));
+    }
+    
+    [Test]
+    public void TestIBuilderLiteWeakMergeFromCodedInputStream() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
+        .SetOptionalUint32(uint.MaxValue).Build();
+
+      copy = TestAllTypesLite.DefaultInstance;
+      Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      using (MemoryStream ms = new MemoryStream(msg.ToByteArray())) {
+        CodedInputStream ci = CodedInputStream.CreateInstance(ms);
+        copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(ci).WeakBuild();
+      }
+
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestIBuilderLiteWeakBuildPartial() {
+      IBuilderLite builder = TestRequiredLite.CreateBuilder();
+      Assert.IsFalse(builder.IsInitialized);
+
+      IMessageLite msg = builder.WeakBuildPartial();
+      Assert.IsFalse(msg.IsInitialized);
+
+      Assert.AreEqual(msg.ToByteArray(), TestRequiredLite.DefaultInstance.ToByteArray());
+    }
+
+    [Test, ExpectedException(typeof(UninitializedMessageException ))]
+    public void TestIBuilderLiteWeakBuildUninitialized() {
+      IBuilderLite builder = TestRequiredLite.CreateBuilder();
+      Assert.IsFalse(builder.IsInitialized);
+      builder.WeakBuild();
+    }
+
+    [Test]
+    public void TestIBuilderLiteWeakBuild() {
+      IBuilderLite builder = TestRequiredLite.CreateBuilder()
+        .SetD(0)
+        .SetEn(ExtraEnum.EXLITE_BAZ);
+      Assert.IsTrue(builder.IsInitialized);
+      builder.WeakBuild();
+    }
+
+    [Test]
+    public void TestIBuilderLiteWeakClone() {
+      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
+        .SetD(1).SetEn(ExtraEnum.EXLITE_BAR).Build();
+      Assert.IsTrue(msg.IsInitialized);
+
+      IMessageLite copy = ((IBuilderLite)msg.ToBuilder()).WeakClone().WeakBuild();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestIBuilderLiteWeakDefaultInstance() {
+      Assert.IsTrue(ReferenceEquals(TestRequiredLite.DefaultInstance,
+        ((IBuilderLite)TestRequiredLite.CreateBuilder()).WeakDefaultInstanceForType));
+    }
+
+    [Test]
+    public void TestGeneratedBuilderLiteAddRange() {
+      TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder()
+        .SetOptionalUint32(123)
+        .AddRepeatedInt32(1)
+        .AddRepeatedInt32(2)
+        .AddRepeatedInt32(3)
+        .Build();
+
+      copy = msg.DefaultInstanceForType.ToBuilder().MergeFrom(msg).Build();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+  }
+}

+ 126 - 126
src/ProtocolBuffersLite.Test/AbstractMessageLiteTest.cs

@@ -1,126 +1,126 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Google.ProtocolBuffers;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class AbstractMessageLiteTest {
-
-    [Test]
-    public void TestMessageLiteToByteString() {
-      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
-        .SetD(42)
-        .SetEn(ExtraEnum.EXLITE_BAZ)
-        .Build();
-      
-      ByteString b = msg.ToByteString();
-      Assert.AreEqual(4, b.Length);
-      Assert.AreEqual(TestRequiredLite.DFieldNumber << 3, b[0]);
-      Assert.AreEqual(42, b[1]);
-      Assert.AreEqual(TestRequiredLite.EnFieldNumber << 3, b[2]);
-      Assert.AreEqual((int)ExtraEnum.EXLITE_BAZ, b[3]);
-    }
-
-    [Test]
-    public void TestMessageLiteToByteArray() {
-      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
-        .SetD(42)
-        .SetEn(ExtraEnum.EXLITE_BAZ)
-        .Build();
-
-      ByteString b = msg.ToByteString();
-      ByteString copy = ByteString.CopyFrom(msg.ToByteArray());
-      Assert.AreEqual(b, copy);
-    }
-
-    [Test]
-    public void TestMessageLiteWriteTo() {
-      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
-        .SetD(42)
-        .SetEn(ExtraEnum.EXLITE_BAZ)
-        .Build();
-
-      MemoryStream ms = new MemoryStream();
-      msg.WriteTo(ms);
-      Assert.AreEqual(msg.ToByteArray(), ms.ToArray());
-    }
-
-    [Test]
-    public void TestMessageLiteWriteDelimitedTo() {
-      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
-        .SetD(42)
-        .SetEn(ExtraEnum.EXLITE_BAZ)
-        .Build();
-
-      MemoryStream ms = new MemoryStream();
-      msg.WriteDelimitedTo(ms);
-      byte[] buffer = ms.ToArray();
-
-      Assert.AreEqual(5, buffer.Length);
-      Assert.AreEqual(4, buffer[0]);
-      byte[] msgBytes = new byte[4];
-      Array.Copy(buffer, 1, msgBytes, 0, 4);
-      Assert.AreEqual(msg.ToByteArray(), msgBytes);
-    }
-
-    [Test]
-    public void TestIMessageLiteWeakCreateBuilderForType() {
-      IMessageLite msg = TestRequiredLite.DefaultInstance;
-      Assert.AreEqual(typeof(TestRequiredLite.Builder), msg.WeakCreateBuilderForType().GetType());
-    }
-
-    [Test]
-    public void TestMessageLiteWeakToBuilder() {
-      IMessageLite msg = TestRequiredLite.CreateBuilder()
-        .SetD(42)
-        .SetEn(ExtraEnum.EXLITE_BAZ)
-        .Build();
-
-      IMessageLite copy = msg.WeakToBuilder().WeakBuild();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestMessageLiteWeakDefaultInstanceForType() {
-      IMessageLite msg = TestRequiredLite.DefaultInstance;
-      Assert.IsTrue(Object.ReferenceEquals(TestRequiredLite.DefaultInstance, msg.WeakDefaultInstanceForType));
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Google.ProtocolBuffers;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers {
+  [TestFixture]
+  public class AbstractMessageLiteTest {
+
+    [Test]
+    public void TestMessageLiteToByteString() {
+      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
+        .SetD(42)
+        .SetEn(ExtraEnum.EXLITE_BAZ)
+        .Build();
+      
+      ByteString b = msg.ToByteString();
+      Assert.AreEqual(4, b.Length);
+      Assert.AreEqual(TestRequiredLite.DFieldNumber << 3, b[0]);
+      Assert.AreEqual(42, b[1]);
+      Assert.AreEqual(TestRequiredLite.EnFieldNumber << 3, b[2]);
+      Assert.AreEqual((int)ExtraEnum.EXLITE_BAZ, b[3]);
+    }
+
+    [Test]
+    public void TestMessageLiteToByteArray() {
+      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
+        .SetD(42)
+        .SetEn(ExtraEnum.EXLITE_BAZ)
+        .Build();
+
+      ByteString b = msg.ToByteString();
+      ByteString copy = ByteString.CopyFrom(msg.ToByteArray());
+      Assert.AreEqual(b, copy);
+    }
+
+    [Test]
+    public void TestMessageLiteWriteTo() {
+      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
+        .SetD(42)
+        .SetEn(ExtraEnum.EXLITE_BAZ)
+        .Build();
+
+      MemoryStream ms = new MemoryStream();
+      msg.WriteTo(ms);
+      Assert.AreEqual(msg.ToByteArray(), ms.ToArray());
+    }
+
+    [Test]
+    public void TestMessageLiteWriteDelimitedTo() {
+      TestRequiredLite msg = TestRequiredLite.CreateBuilder()
+        .SetD(42)
+        .SetEn(ExtraEnum.EXLITE_BAZ)
+        .Build();
+
+      MemoryStream ms = new MemoryStream();
+      msg.WriteDelimitedTo(ms);
+      byte[] buffer = ms.ToArray();
+
+      Assert.AreEqual(5, buffer.Length);
+      Assert.AreEqual(4, buffer[0]);
+      byte[] msgBytes = new byte[4];
+      Array.Copy(buffer, 1, msgBytes, 0, 4);
+      Assert.AreEqual(msg.ToByteArray(), msgBytes);
+    }
+
+    [Test]
+    public void TestIMessageLiteWeakCreateBuilderForType() {
+      IMessageLite msg = TestRequiredLite.DefaultInstance;
+      Assert.AreEqual(typeof(TestRequiredLite.Builder), msg.WeakCreateBuilderForType().GetType());
+    }
+
+    [Test]
+    public void TestMessageLiteWeakToBuilder() {
+      IMessageLite msg = TestRequiredLite.CreateBuilder()
+        .SetD(42)
+        .SetEn(ExtraEnum.EXLITE_BAZ)
+        .Build();
+
+      IMessageLite copy = msg.WeakToBuilder().WeakBuild();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestMessageLiteWeakDefaultInstanceForType() {
+      IMessageLite msg = TestRequiredLite.DefaultInstance;
+      Assert.IsTrue(Object.ReferenceEquals(TestRequiredLite.DefaultInstance, msg.WeakDefaultInstanceForType));
+    }
+  }
+}

+ 267 - 267
src/ProtocolBuffersLite.Test/ExtendableBuilderLiteTest.cs

@@ -1,267 +1,267 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using Google.ProtocolBuffers;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class ExtendableBuilderLiteTest {
-
-    [Test]
-    public void TestHasExtensionT() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-          .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123);
-
-      Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestHasExtensionTMissing() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-      Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestGetExtensionCountT() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 3);
-
-      Assert.AreEqual(3, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestGetExtensionCountTEmpty() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-      Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestGetExtensionTNull() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-      string value = builder.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite);
-      Assert.IsNull(value);
-    }
-
-    [Test]
-    public void TestGetExtensionTValue() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-          .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 3);
-
-      Assert.AreEqual(3, builder.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestGetExtensionTEmpty() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-      Assert.AreEqual(0, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite).Count);
-    }
-
-    [Test]
-    public void TestGetExtensionTList() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 3);
-
-      IList<int> values = builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite);
-      Assert.AreEqual(3, values.Count);
-    }
-
-    [Test]
-    public void TestGetExtensionTIndex() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2);
-
-      for(int i = 0; i < 3; i++ )
-        Assert.AreEqual(i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i));
-    }
-
-    [Test,ExpectedException(typeof(ArgumentOutOfRangeException))]
-    public void TestGetExtensionTIndexOutOfRange() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-      builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
-    }
-
-    [Test]
-    public void TestSetExtensionTIndex() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2);
-
-      for (int i = 0; i < 3; i++)
-        Assert.AreEqual(i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i));
-
-      builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0, 5);
-      builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1, 6);
-      builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2, 7);
-
-      for (int i = 0; i < 3; i++)
-        Assert.AreEqual(5 + i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i));
-    }
-
-    [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
-    public void TestSetExtensionTIndexOutOfRange() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-      builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0, -1);
-    }
-
-    [Test]
-    public void TestClearExtensionTList() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
-      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-      
-      builder.ClearExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite);
-      Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestClearExtensionTValue() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-        .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 0);
-      Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-
-      builder.ClearExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite);
-      Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestIndexedByDescriptor() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-      Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-      
-      builder[UnitTestLiteProtoFile.OptionalInt32ExtensionLite.Descriptor] = 123;
-      
-      Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-      Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestIndexedByDescriptorAndOrdinal() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
-      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-
-      IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor;
-      builder[f, 0] = 123;
-
-      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-      Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0));
-    }
-
-    [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
-    public void TestIndexedByDescriptorAndOrdinalOutOfRange() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-      Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-
-      IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor;
-      builder[f, 0] = 123;
-    }
-
-    [Test]
-    public void TestClearFieldByDescriptor() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
-      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-
-      IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor;
-      builder.ClearField(f);
-      Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-    }
-
-    [Test]
-    public void TestAddRepeatedFieldByDescriptor() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
-      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-
-      IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor;
-      builder.AddRepeatedField(f, 123);
-      Assert.AreEqual(2, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
-      Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1));
-    }
-
-    [Test]
-    public void TestMissingExtensionsLite()
-    {
-        const int optionalInt32 = 12345678;
-        TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
-        builder.SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, optionalInt32);
-        builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.1);
-        builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.2);
-        builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.3);
-        TestAllExtensionsLite msg = builder.Build();
-
-        Assert.IsTrue(msg.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-        Assert.AreEqual(3, msg.GetExtensionCount(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite));
-
-        byte[] bits = msg.ToByteArray();
-        TestAllExtensionsLite copy = TestAllExtensionsLite.ParseFrom(bits);
-        Assert.IsFalse(copy.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-        Assert.AreEqual(0, copy.GetExtensionCount(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite));
-        Assert.AreNotEqual(msg, copy);
-
-        //The lite runtime removes all unknown fields and extensions
-        byte[] copybits = copy.ToByteArray();
-        Assert.AreEqual(0, copybits.Length);
-    }
-
-    [Test]
-    public void TestMissingFieldsLite()
-    {
-        TestAllTypesLite msg = TestAllTypesLite.CreateBuilder()
-            .SetOptionalInt32(123)
-            .SetOptionalString("123")
-            .Build();
-
-        byte[] bits = msg.ToByteArray();
-        TestAllExtensionsLite copy = TestAllExtensionsLite.ParseFrom(bits);
-        Assert.AreNotEqual(msg, copy);
-
-        //The lite runtime removes all unknown fields and extensions
-        byte[] copybits = copy.ToByteArray();
-        Assert.AreEqual(0, copybits.Length);
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Google.ProtocolBuffers;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers {
+  [TestFixture]
+  public class ExtendableBuilderLiteTest {
+
+    [Test]
+    public void TestHasExtensionT() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+          .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123);
+
+      Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestHasExtensionTMissing() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+      Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestGetExtensionCountT() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 3);
+
+      Assert.AreEqual(3, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestGetExtensionCountTEmpty() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+      Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestGetExtensionTNull() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+      string value = builder.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite);
+      Assert.IsNull(value);
+    }
+
+    [Test]
+    public void TestGetExtensionTValue() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+          .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 3);
+
+      Assert.AreEqual(3, builder.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestGetExtensionTEmpty() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+      Assert.AreEqual(0, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite).Count);
+    }
+
+    [Test]
+    public void TestGetExtensionTList() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 3);
+
+      IList<int> values = builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite);
+      Assert.AreEqual(3, values.Count);
+    }
+
+    [Test]
+    public void TestGetExtensionTIndex() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2);
+
+      for(int i = 0; i < 3; i++ )
+        Assert.AreEqual(i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i));
+    }
+
+    [Test,ExpectedException(typeof(ArgumentOutOfRangeException))]
+    public void TestGetExtensionTIndexOutOfRange() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+      builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
+    }
+
+    [Test]
+    public void TestSetExtensionTIndex() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2);
+
+      for (int i = 0; i < 3; i++)
+        Assert.AreEqual(i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i));
+
+      builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0, 5);
+      builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1, 6);
+      builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2, 7);
+
+      for (int i = 0; i < 3; i++)
+        Assert.AreEqual(5 + i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i));
+    }
+
+    [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
+    public void TestSetExtensionTIndexOutOfRange() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+      builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0, -1);
+    }
+
+    [Test]
+    public void TestClearExtensionTList() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
+      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+      
+      builder.ClearExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite);
+      Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestClearExtensionTValue() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+        .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 0);
+      Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+
+      builder.ClearExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite);
+      Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestIndexedByDescriptor() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+      Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+      
+      builder[UnitTestLiteProtoFile.OptionalInt32ExtensionLite.Descriptor] = 123;
+      
+      Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+      Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestIndexedByDescriptorAndOrdinal() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
+      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+
+      IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor;
+      builder[f, 0] = 123;
+
+      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+      Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0));
+    }
+
+    [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
+    public void TestIndexedByDescriptorAndOrdinalOutOfRange() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+      Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+
+      IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor;
+      builder[f, 0] = 123;
+    }
+
+    [Test]
+    public void TestClearFieldByDescriptor() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
+      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+
+      IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor;
+      builder.ClearField(f);
+      Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+    }
+
+    [Test]
+    public void TestAddRepeatedFieldByDescriptor() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0);
+      Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+
+      IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor;
+      builder.AddRepeatedField(f, 123);
+      Assert.AreEqual(2, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite));
+      Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1));
+    }
+
+    [Test]
+    public void TestMissingExtensionsLite()
+    {
+        const int optionalInt32 = 12345678;
+        TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder();
+        builder.SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, optionalInt32);
+        builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.1);
+        builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.2);
+        builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.3);
+        TestAllExtensionsLite msg = builder.Build();
+
+        Assert.IsTrue(msg.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+        Assert.AreEqual(3, msg.GetExtensionCount(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite));
+
+        byte[] bits = msg.ToByteArray();
+        TestAllExtensionsLite copy = TestAllExtensionsLite.ParseFrom(bits);
+        Assert.IsFalse(copy.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+        Assert.AreEqual(0, copy.GetExtensionCount(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite));
+        Assert.AreNotEqual(msg, copy);
+
+        //The lite runtime removes all unknown fields and extensions
+        byte[] copybits = copy.ToByteArray();
+        Assert.AreEqual(0, copybits.Length);
+    }
+
+    [Test]
+    public void TestMissingFieldsLite()
+    {
+        TestAllTypesLite msg = TestAllTypesLite.CreateBuilder()
+            .SetOptionalInt32(123)
+            .SetOptionalString("123")
+            .Build();
+
+        byte[] bits = msg.ToByteArray();
+        TestAllExtensionsLite copy = TestAllExtensionsLite.ParseFrom(bits);
+        Assert.AreNotEqual(msg, copy);
+
+        //The lite runtime removes all unknown fields and extensions
+        byte[] copybits = copy.ToByteArray();
+        Assert.AreEqual(0, copybits.Length);
+    }
+  }
+}

+ 304 - 304
src/ProtocolBuffersLite.Test/ExtendableMessageLiteTest.cs

@@ -1,304 +1,304 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Google.ProtocolBuffers;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class ExtendableMessageLiteTest {
-
-    [Test, Ignore("Not implemented, no assertion made"), ExpectedException(typeof(ArgumentException))]
-    public void ExtensionWriterInvalidExtension() {
-      TestPackedExtensionsLite.CreateBuilder()[UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite.Descriptor] = 
-        ForeignMessageLite.DefaultInstance;
-    }
-
-    [Test]
-    public void ExtensionWriterTestMessages() {
-      TestAllExtensionsLite.Builder b = TestAllExtensionsLite.CreateBuilder().SetExtension(
-        UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite, ForeignMessageLite.CreateBuilder().SetC(123).Build());
-      TestAllExtensionsLite copy, msg = b.Build();
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
-
-      copy = TestAllExtensionsLite.ParseFrom(msg.ToByteArray(), registry);
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void ExtensionWriterIsInitialized() {
-      Assert.IsTrue(ForeignMessageLite.DefaultInstance.IsInitialized);
-      Assert.IsTrue(TestPackedExtensionsLite.CreateBuilder().IsInitialized);
-      Assert.IsTrue(TestAllExtensionsLite.CreateBuilder().SetExtension(
-        UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite, ForeignMessageLite.DefaultInstance)
-        .IsInitialized);
-    }
-
-    [Test]
-    public void ExtensionWriterTestSetExtensionLists() {
-      TestAllExtensionsLite msg, copy;
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-        .SetExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, new[] { true, false })
-        .SetExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, new[] { "123", "456" })
-        .SetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, new[] { ForeignEnumLite.FOREIGN_LITE_BAZ, ForeignEnumLite.FOREIGN_LITE_FOO })
-        ;
-
-      msg = builder.Build();
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
-
-      copy = TestAllExtensionsLite.ParseFrom(msg.ToByteArray(), registry);
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_FOO, copy.GetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, 1));
-    }
-
-    [Test]
-    public void ExtensionWriterTest() {
-      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
-        .SetExtension(UnitTestLiteProtoFile.DefaultBoolExtensionLite, true)
-        .SetExtension(UnitTestLiteProtoFile.DefaultBytesExtensionLite, ByteString.CopyFromUtf8("123"))
-        .SetExtension(UnitTestLiteProtoFile.DefaultCordExtensionLite, "123")
-        .SetExtension(UnitTestLiteProtoFile.DefaultDoubleExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.DefaultFixed32ExtensionLite, 123u)
-        .SetExtension(UnitTestLiteProtoFile.DefaultFixed64ExtensionLite, 123u)
-        .SetExtension(UnitTestLiteProtoFile.DefaultFloatExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.DefaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ)
-        .SetExtension(UnitTestLiteProtoFile.DefaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ)
-        .SetExtension(UnitTestLiteProtoFile.DefaultInt32ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.DefaultInt64ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.DefaultNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO)
-        .SetExtension(UnitTestLiteProtoFile.DefaultSfixed32ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.DefaultSfixed64ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.DefaultSint32ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.DefaultSint64ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.DefaultStringExtensionLite, "123")
-        .SetExtension(UnitTestLiteProtoFile.DefaultStringPieceExtensionLite, "123")
-        .SetExtension(UnitTestLiteProtoFile.DefaultUint32ExtensionLite, 123u)
-        .SetExtension(UnitTestLiteProtoFile.DefaultUint64ExtensionLite, 123u)
-        //Optional
-        .SetExtension(UnitTestLiteProtoFile.OptionalBoolExtensionLite, true)
-        .SetExtension(UnitTestLiteProtoFile.OptionalBytesExtensionLite, ByteString.CopyFromUtf8("123"))
-        .SetExtension(UnitTestLiteProtoFile.OptionalCordExtensionLite, "123")
-        .SetExtension(UnitTestLiteProtoFile.OptionalDoubleExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.OptionalFixed32ExtensionLite, 123u)
-        .SetExtension(UnitTestLiteProtoFile.OptionalFixed64ExtensionLite, 123u)
-        .SetExtension(UnitTestLiteProtoFile.OptionalFloatExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.OptionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ)
-        .SetExtension(UnitTestLiteProtoFile.OptionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ)
-        .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.OptionalInt64ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO)
-        .SetExtension(UnitTestLiteProtoFile.OptionalSfixed32ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.OptionalSfixed64ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.OptionalSint32ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.OptionalSint64ExtensionLite, 123)
-        .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "123")
-        .SetExtension(UnitTestLiteProtoFile.OptionalStringPieceExtensionLite, "123")
-        .SetExtension(UnitTestLiteProtoFile.OptionalUint32ExtensionLite, 123u)
-        .SetExtension(UnitTestLiteProtoFile.OptionalUint64ExtensionLite, 123u)
-        //Repeated
-        .AddExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, true)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedBytesExtensionLite, ByteString.CopyFromUtf8("123"))
-        .AddExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, "123")
-        .AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedFixed32ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedFixed64ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedFloatExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedInt64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedSfixed32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedSfixed64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedSint32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedSint64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, "123")
-        .AddExtension(UnitTestLiteProtoFile.RepeatedStringPieceExtensionLite, "123")
-        .AddExtension(UnitTestLiteProtoFile.RepeatedUint32ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.RepeatedUint64ExtensionLite, 123u)
-        ;
-      TestAllExtensionsLite msg = builder.Build();
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
-
-      TestAllExtensionsLite.Builder copyBuilder = TestAllExtensionsLite.CreateBuilder().MergeFrom(msg.ToByteArray(), registry);
-      TestAllExtensionsLite copy = copyBuilder.Build();
-
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.DefaultBoolExtensionLite));
-      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.DefaultBytesExtensionLite));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultCordExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultDoubleExtensionLite));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultFixed32ExtensionLite));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultFixed64ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultFloatExtensionLite));
-      Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.DefaultForeignEnumExtensionLite));
-      Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.DefaultImportEnumExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultInt32ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultInt64ExtensionLite));
-      Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.DefaultNestedEnumExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSfixed32ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSfixed64ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSint32ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSint64ExtensionLite));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultStringExtensionLite));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultStringPieceExtensionLite));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultUint32ExtensionLite));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultUint64ExtensionLite));
-
-      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.OptionalBoolExtensionLite));
-      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.OptionalBytesExtensionLite));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalCordExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalDoubleExtensionLite));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalFixed32ExtensionLite));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalFixed64ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalFloatExtensionLite));
-      Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.OptionalForeignEnumExtensionLite));
-      Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.OptionalImportEnumExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalInt64ExtensionLite));
-      Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSfixed32ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSfixed64ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSint32ExtensionLite));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSint64ExtensionLite));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringPieceExtensionLite));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalUint32ExtensionLite));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalUint64ExtensionLite));
-
-      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, 0));
-      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.RepeatedBytesExtensionLite, 0));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFixed32ExtensionLite, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFixed64ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFloatExtensionLite, 0));
-      Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, 0));
-      Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.RepeatedImportEnumExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedInt64ExtensionLite, 0));
-      Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.RepeatedNestedEnumExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSfixed32ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSfixed64ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSint32ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSint64ExtensionLite, 0));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, 0));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedStringPieceExtensionLite, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedUint32ExtensionLite, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedUint64ExtensionLite, 0));
-    }
-
-    [Test]
-    public void ExtensionWriterTestPacked() {
-
-      TestPackedExtensionsLite.Builder builder = TestPackedExtensionsLite.CreateBuilder()
-        .AddExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, true)
-        .AddExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, true)
-        .AddExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 123)
-        .AddExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 123u)
-        .AddExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 123u);
-
-      TestPackedExtensionsLite msg = builder.Build();
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
-
-      TestPackedExtensionsLite.Builder copyBuilder = TestPackedExtensionsLite.CreateBuilder().MergeFrom(msg.ToByteArray(), registry);
-      TestPackedExtensionsLite copy = copyBuilder.Build();
-
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 0));
-
-      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, 1));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 1));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 1));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 1));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 1));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 1));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 1));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 1));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 1));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 1));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 1));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 1));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 1));
-
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Google.ProtocolBuffers;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers {
+  [TestFixture]
+  public class ExtendableMessageLiteTest {
+
+    [Test, Ignore("Not implemented, no assertion made"), ExpectedException(typeof(ArgumentException))]
+    public void ExtensionWriterInvalidExtension() {
+      TestPackedExtensionsLite.CreateBuilder()[UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite.Descriptor] = 
+        ForeignMessageLite.DefaultInstance;
+    }
+
+    [Test]
+    public void ExtensionWriterTestMessages() {
+      TestAllExtensionsLite.Builder b = TestAllExtensionsLite.CreateBuilder().SetExtension(
+        UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite, ForeignMessageLite.CreateBuilder().SetC(123).Build());
+      TestAllExtensionsLite copy, msg = b.Build();
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
+
+      copy = TestAllExtensionsLite.ParseFrom(msg.ToByteArray(), registry);
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void ExtensionWriterIsInitialized() {
+      Assert.IsTrue(ForeignMessageLite.DefaultInstance.IsInitialized);
+      Assert.IsTrue(TestPackedExtensionsLite.CreateBuilder().IsInitialized);
+      Assert.IsTrue(TestAllExtensionsLite.CreateBuilder().SetExtension(
+        UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite, ForeignMessageLite.DefaultInstance)
+        .IsInitialized);
+    }
+
+    [Test]
+    public void ExtensionWriterTestSetExtensionLists() {
+      TestAllExtensionsLite msg, copy;
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+        .SetExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, new[] { true, false })
+        .SetExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, new[] { "123", "456" })
+        .SetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, new[] { ForeignEnumLite.FOREIGN_LITE_BAZ, ForeignEnumLite.FOREIGN_LITE_FOO })
+        ;
+
+      msg = builder.Build();
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
+
+      copy = TestAllExtensionsLite.ParseFrom(msg.ToByteArray(), registry);
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_FOO, copy.GetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, 1));
+    }
+
+    [Test]
+    public void ExtensionWriterTest() {
+      TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder()
+        .SetExtension(UnitTestLiteProtoFile.DefaultBoolExtensionLite, true)
+        .SetExtension(UnitTestLiteProtoFile.DefaultBytesExtensionLite, ByteString.CopyFromUtf8("123"))
+        .SetExtension(UnitTestLiteProtoFile.DefaultCordExtensionLite, "123")
+        .SetExtension(UnitTestLiteProtoFile.DefaultDoubleExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.DefaultFixed32ExtensionLite, 123u)
+        .SetExtension(UnitTestLiteProtoFile.DefaultFixed64ExtensionLite, 123u)
+        .SetExtension(UnitTestLiteProtoFile.DefaultFloatExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.DefaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ)
+        .SetExtension(UnitTestLiteProtoFile.DefaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ)
+        .SetExtension(UnitTestLiteProtoFile.DefaultInt32ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.DefaultInt64ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.DefaultNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO)
+        .SetExtension(UnitTestLiteProtoFile.DefaultSfixed32ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.DefaultSfixed64ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.DefaultSint32ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.DefaultSint64ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.DefaultStringExtensionLite, "123")
+        .SetExtension(UnitTestLiteProtoFile.DefaultStringPieceExtensionLite, "123")
+        .SetExtension(UnitTestLiteProtoFile.DefaultUint32ExtensionLite, 123u)
+        .SetExtension(UnitTestLiteProtoFile.DefaultUint64ExtensionLite, 123u)
+        //Optional
+        .SetExtension(UnitTestLiteProtoFile.OptionalBoolExtensionLite, true)
+        .SetExtension(UnitTestLiteProtoFile.OptionalBytesExtensionLite, ByteString.CopyFromUtf8("123"))
+        .SetExtension(UnitTestLiteProtoFile.OptionalCordExtensionLite, "123")
+        .SetExtension(UnitTestLiteProtoFile.OptionalDoubleExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.OptionalFixed32ExtensionLite, 123u)
+        .SetExtension(UnitTestLiteProtoFile.OptionalFixed64ExtensionLite, 123u)
+        .SetExtension(UnitTestLiteProtoFile.OptionalFloatExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.OptionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ)
+        .SetExtension(UnitTestLiteProtoFile.OptionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ)
+        .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.OptionalInt64ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO)
+        .SetExtension(UnitTestLiteProtoFile.OptionalSfixed32ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.OptionalSfixed64ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.OptionalSint32ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.OptionalSint64ExtensionLite, 123)
+        .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "123")
+        .SetExtension(UnitTestLiteProtoFile.OptionalStringPieceExtensionLite, "123")
+        .SetExtension(UnitTestLiteProtoFile.OptionalUint32ExtensionLite, 123u)
+        .SetExtension(UnitTestLiteProtoFile.OptionalUint64ExtensionLite, 123u)
+        //Repeated
+        .AddExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, true)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedBytesExtensionLite, ByteString.CopyFromUtf8("123"))
+        .AddExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, "123")
+        .AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedFixed32ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedFixed64ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedFloatExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedInt64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedSfixed32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedSfixed64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedSint32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedSint64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, "123")
+        .AddExtension(UnitTestLiteProtoFile.RepeatedStringPieceExtensionLite, "123")
+        .AddExtension(UnitTestLiteProtoFile.RepeatedUint32ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.RepeatedUint64ExtensionLite, 123u)
+        ;
+      TestAllExtensionsLite msg = builder.Build();
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
+
+      TestAllExtensionsLite.Builder copyBuilder = TestAllExtensionsLite.CreateBuilder().MergeFrom(msg.ToByteArray(), registry);
+      TestAllExtensionsLite copy = copyBuilder.Build();
+
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.DefaultBoolExtensionLite));
+      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.DefaultBytesExtensionLite));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultCordExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultDoubleExtensionLite));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultFixed32ExtensionLite));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultFixed64ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultFloatExtensionLite));
+      Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.DefaultForeignEnumExtensionLite));
+      Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.DefaultImportEnumExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultInt32ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultInt64ExtensionLite));
+      Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.DefaultNestedEnumExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSfixed32ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSfixed64ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSint32ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSint64ExtensionLite));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultStringExtensionLite));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultStringPieceExtensionLite));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultUint32ExtensionLite));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultUint64ExtensionLite));
+
+      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.OptionalBoolExtensionLite));
+      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.OptionalBytesExtensionLite));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalCordExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalDoubleExtensionLite));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalFixed32ExtensionLite));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalFixed64ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalFloatExtensionLite));
+      Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.OptionalForeignEnumExtensionLite));
+      Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.OptionalImportEnumExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalInt64ExtensionLite));
+      Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSfixed32ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSfixed64ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSint32ExtensionLite));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSint64ExtensionLite));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringPieceExtensionLite));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalUint32ExtensionLite));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalUint64ExtensionLite));
+
+      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, 0));
+      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.RepeatedBytesExtensionLite, 0));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 0));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFixed32ExtensionLite, 0));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFixed64ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFloatExtensionLite, 0));
+      Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, 0));
+      Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.RepeatedImportEnumExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedInt64ExtensionLite, 0));
+      Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.RepeatedNestedEnumExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSfixed32ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSfixed64ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSint32ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSint64ExtensionLite, 0));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, 0));
+      Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedStringPieceExtensionLite, 0));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedUint32ExtensionLite, 0));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedUint64ExtensionLite, 0));
+    }
+
+    [Test]
+    public void ExtensionWriterTestPacked() {
+
+      TestPackedExtensionsLite.Builder builder = TestPackedExtensionsLite.CreateBuilder()
+        .AddExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, true)
+        .AddExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, true)
+        .AddExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 123)
+        .AddExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 123u)
+        .AddExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 123u);
+
+      TestPackedExtensionsLite msg = builder.Build();
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestLiteProtoFile.RegisterAllExtensions(registry);
+
+      TestPackedExtensionsLite.Builder copyBuilder = TestPackedExtensionsLite.CreateBuilder().MergeFrom(msg.ToByteArray(), registry);
+      TestPackedExtensionsLite copy = copyBuilder.Build();
+
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+
+      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 0));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 0));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 0));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 0));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 0));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 0));
+
+      Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, 1));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 1));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 1));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 1));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 1));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 1));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 1));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 1));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 1));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 1));
+      Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 1));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 1));
+      Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 1));
+
+    }
+  }
+}

+ 162 - 162
src/ProtocolBuffersLite.Test/InteropLiteTest.cs

@@ -1,162 +1,162 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using Google.ProtocolBuffers;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class InteropLiteTest {
-
-    [Test]
-    public void TestConvertFromFullMinimal() {
-      TestInteropPerson person = TestInteropPerson.CreateBuilder()
-        .SetId(123)
-        .SetName("abc")
-        .Build();
-      Assert.IsTrue(person.IsInitialized);
-
-      TestInteropPersonLite copy = TestInteropPersonLite.ParseFrom(person.ToByteArray());
-
-      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestConvertFromFullComplete() {
-      TestInteropPerson person = TestInteropPerson.CreateBuilder()
-        .SetId(123)
-        .SetName("abc")
-        .SetEmail("abc@123.com")
-        .AddRangeCodes(new[] { 1, 2, 3 })
-        .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build())
-        .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build())
-        .AddAddresses(TestInteropPerson.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build())
-        .SetExtension(UnitTestExtrasFullProtoFile.EmployeeId, TestInteropEmployeeId.CreateBuilder().SetNumber("123").Build())
-        .Build();
-      Assert.IsTrue(person.IsInitialized);
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestExtrasLiteProtoFile.RegisterAllExtensions(registry);
-
-      TestInteropPersonLite copy = TestInteropPersonLite.ParseFrom(person.ToByteArray(), registry);
-
-      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestConvertFromLiteMinimal() {
-      TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder()
-        .SetId(123)
-        .SetName("abc")
-        .Build();
-      Assert.IsTrue(person.IsInitialized);
-
-      TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray());
-
-      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestConvertFromLiteComplete() {
-      TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder()
-        .SetId(123)
-        .SetName("abc")
-        .SetEmail("abc@123.com")
-        .AddRangeCodes(new[] { 1, 2, 3 })
-        .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build())
-        .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build())
-        .AddAddresses(TestInteropPersonLite.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build())
-        .SetExtension(UnitTestExtrasLiteProtoFile.EmployeeIdLite, TestInteropEmployeeIdLite.CreateBuilder().SetNumber("123").Build())
-        .Build();
-      Assert.IsTrue(person.IsInitialized);
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry);
-
-      TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray(), registry);
-
-      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
-    }
-
-    public ByteString AllBytes {
-      get {
-        byte[] bytes = new byte[256];
-        for (int i = 0; i < bytes.Length; i++)
-          bytes[i] = (byte)i;
-        return ByteString.CopyFrom(bytes);
-      }
-    }
-
-      [Test]
-    public void TestCompareStringValues() {
-      TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder()
-        .SetId(123)
-        .SetName("abc")
-        .SetEmail("abc@123.com")
-        .AddRangeCodes(new[] { 1, 2, 3 })
-        .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build())
-        .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber(System.Text.Encoding.ASCII.GetString(AllBytes.ToByteArray())).Build())
-        .AddAddresses(TestInteropPersonLite.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build())
-        .SetExtension(UnitTestExtrasLiteProtoFile.EmployeeIdLite, TestInteropEmployeeIdLite.CreateBuilder().SetNumber("123").Build())
-        .Build();
-      Assert.IsTrue(person.IsInitialized);
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry);
-
-      TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray(), registry);
-
-      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
-
-      TestInteropPerson.Builder copyBuilder = TestInteropPerson.CreateBuilder();
-      TextFormat.Merge(person.ToString().Replace("[protobuf_unittest_extra.employee_id_lite]", "[protobuf_unittest_extra.employee_id]"), registry, copyBuilder);
-
-      copy = copyBuilder.Build();
-      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
-
-      string liteText = person.ToString().TrimEnd().Replace("\r", "");
-      string fullText = copy.ToString().TrimEnd().Replace("\r", "");
-      //map the extension type
-      liteText = liteText.Replace("[protobuf_unittest_extra.employee_id_lite]", "[protobuf_unittest_extra.employee_id]");
-      //lite version does not indent
-      while (fullText.IndexOf("\n ") >= 0)
-        fullText = fullText.Replace("\n ", "\n");
-
-      Assert.AreEqual(fullText, liteText);
-    }
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Google.ProtocolBuffers;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers {
+  [TestFixture]
+  public class InteropLiteTest {
+
+    [Test]
+    public void TestConvertFromFullMinimal() {
+      TestInteropPerson person = TestInteropPerson.CreateBuilder()
+        .SetId(123)
+        .SetName("abc")
+        .Build();
+      Assert.IsTrue(person.IsInitialized);
+
+      TestInteropPersonLite copy = TestInteropPersonLite.ParseFrom(person.ToByteArray());
+
+      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestConvertFromFullComplete() {
+      TestInteropPerson person = TestInteropPerson.CreateBuilder()
+        .SetId(123)
+        .SetName("abc")
+        .SetEmail("abc@123.com")
+        .AddRangeCodes(new[] { 1, 2, 3 })
+        .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build())
+        .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build())
+        .AddAddresses(TestInteropPerson.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build())
+        .SetExtension(UnitTestExtrasFullProtoFile.EmployeeId, TestInteropEmployeeId.CreateBuilder().SetNumber("123").Build())
+        .Build();
+      Assert.IsTrue(person.IsInitialized);
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestExtrasLiteProtoFile.RegisterAllExtensions(registry);
+
+      TestInteropPersonLite copy = TestInteropPersonLite.ParseFrom(person.ToByteArray(), registry);
+
+      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestConvertFromLiteMinimal() {
+      TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder()
+        .SetId(123)
+        .SetName("abc")
+        .Build();
+      Assert.IsTrue(person.IsInitialized);
+
+      TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray());
+
+      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestConvertFromLiteComplete() {
+      TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder()
+        .SetId(123)
+        .SetName("abc")
+        .SetEmail("abc@123.com")
+        .AddRangeCodes(new[] { 1, 2, 3 })
+        .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build())
+        .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build())
+        .AddAddresses(TestInteropPersonLite.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build())
+        .SetExtension(UnitTestExtrasLiteProtoFile.EmployeeIdLite, TestInteropEmployeeIdLite.CreateBuilder().SetNumber("123").Build())
+        .Build();
+      Assert.IsTrue(person.IsInitialized);
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry);
+
+      TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray(), registry);
+
+      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
+    }
+
+    public ByteString AllBytes {
+      get {
+        byte[] bytes = new byte[256];
+        for (int i = 0; i < bytes.Length; i++)
+          bytes[i] = (byte)i;
+        return ByteString.CopyFrom(bytes);
+      }
+    }
+
+      [Test]
+    public void TestCompareStringValues() {
+      TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder()
+        .SetId(123)
+        .SetName("abc")
+        .SetEmail("abc@123.com")
+        .AddRangeCodes(new[] { 1, 2, 3 })
+        .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build())
+        .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber(System.Text.Encoding.ASCII.GetString(AllBytes.ToByteArray())).Build())
+        .AddAddresses(TestInteropPersonLite.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build())
+        .SetExtension(UnitTestExtrasLiteProtoFile.EmployeeIdLite, TestInteropEmployeeIdLite.CreateBuilder().SetNumber("123").Build())
+        .Build();
+      Assert.IsTrue(person.IsInitialized);
+
+      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+      UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry);
+
+      TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray(), registry);
+
+      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
+
+      TestInteropPerson.Builder copyBuilder = TestInteropPerson.CreateBuilder();
+      TextFormat.Merge(person.ToString().Replace("[protobuf_unittest_extra.employee_id_lite]", "[protobuf_unittest_extra.employee_id]"), registry, copyBuilder);
+
+      copy = copyBuilder.Build();
+      Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
+
+      string liteText = person.ToString().TrimEnd().Replace("\r", "");
+      string fullText = copy.ToString().TrimEnd().Replace("\r", "");
+      //map the extension type
+      liteText = liteText.Replace("[protobuf_unittest_extra.employee_id_lite]", "[protobuf_unittest_extra.employee_id]");
+      //lite version does not indent
+      while (fullText.IndexOf("\n ") >= 0)
+        fullText = fullText.Replace("\n ", "\n");
+
+      Assert.AreEqual(fullText, liteText);
+    }
+  }
+}

+ 111 - 111
src/ProtocolBuffersLite.Test/LiteTest.cs

@@ -1,112 +1,112 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Google.ProtocolBuffers.Descriptors;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Miscellaneous tests for message operations that apply to both
-  /// generated and dynamic messages.
-  /// </summary>
-  [TestFixture]
-  public class LiteTest {
-    [Test]
-    public void TestLite() {
-      // Since lite messages are a subset of regular messages, we can mostly
-      // assume that the functionality of lite messages is already thoroughly
-      // tested by the regular tests.  All this test really verifies is that
-      // a proto with optimize_for = LITE_RUNTIME compiles correctly when
-      // linked only against the lite library.  That is all tested at compile
-      // time, leaving not much to do in this method.  Let's just do some random
-      // stuff to make sure the lite message is actually here and usable.
-
-      TestAllTypesLite message =
-        TestAllTypesLite.CreateBuilder()
-                        .SetOptionalInt32(123)
-                        .AddRepeatedString("hello")
-                        .SetOptionalNestedMessage(
-                            TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7))
-                        .Build();
-
-      ByteString data = message.ToByteString();
-
-      TestAllTypesLite message2 = TestAllTypesLite.ParseFrom(data);
-
-      Assert.AreEqual(123, message2.OptionalInt32);
-      Assert.AreEqual(1, message2.RepeatedStringCount);
-      Assert.AreEqual("hello", message2.RepeatedStringList[0]);
-      Assert.AreEqual(7, message2.OptionalNestedMessage.Bb);
-    }
-
-    [Test]
-    public void TestLiteExtensions() {
-      // TODO(kenton):  Unlike other features of the lite library, extensions are
-      //   implemented completely differently from the regular library.  We
-      //   should probably test them more thoroughly.
-
-      TestAllExtensionsLite message =
-        TestAllExtensionsLite.CreateBuilder()
-          .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123)
-          .AddExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, "hello")
-          .SetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite,
-              TestAllTypesLite.Types.NestedEnum.BAZ)
-          .SetExtension(UnitTestLiteProtoFile.OptionalNestedMessageExtensionLite,
-              TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7).Build())
-          .Build();
-
-      // Test copying a message, since coping extensions actually does use a
-      // different code path between lite and regular libraries, and as of this
-      // writing, parsing hasn't been implemented yet.
-      TestAllExtensionsLite message2 = message.ToBuilder().Build();
-
-      Assert.AreEqual(123, (int)message2.GetExtension(
-          UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
-      Assert.AreEqual(1, message2.GetExtensionCount(
-          UnitTestLiteProtoFile.RepeatedStringExtensionLite));
-      Assert.AreEqual(1, message2.GetExtension(
-          UnitTestLiteProtoFile.RepeatedStringExtensionLite).Count);
-      Assert.AreEqual("hello", message2.GetExtension(
-          UnitTestLiteProtoFile.RepeatedStringExtensionLite, 0));
-      Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.BAZ, message2.GetExtension(
-          UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite));
-      Assert.AreEqual(7, message2.GetExtension(
-          UnitTestLiteProtoFile.OptionalNestedMessageExtensionLite).Bb);
-    }
-  }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Google.ProtocolBuffers.Descriptors;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Miscellaneous tests for message operations that apply to both
+  /// generated and dynamic messages.
+  /// </summary>
+  [TestFixture]
+  public class LiteTest {
+    [Test]
+    public void TestLite() {
+      // Since lite messages are a subset of regular messages, we can mostly
+      // assume that the functionality of lite messages is already thoroughly
+      // tested by the regular tests.  All this test really verifies is that
+      // a proto with optimize_for = LITE_RUNTIME compiles correctly when
+      // linked only against the lite library.  That is all tested at compile
+      // time, leaving not much to do in this method.  Let's just do some random
+      // stuff to make sure the lite message is actually here and usable.
+
+      TestAllTypesLite message =
+        TestAllTypesLite.CreateBuilder()
+                        .SetOptionalInt32(123)
+                        .AddRepeatedString("hello")
+                        .SetOptionalNestedMessage(
+                            TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7))
+                        .Build();
+
+      ByteString data = message.ToByteString();
+
+      TestAllTypesLite message2 = TestAllTypesLite.ParseFrom(data);
+
+      Assert.AreEqual(123, message2.OptionalInt32);
+      Assert.AreEqual(1, message2.RepeatedStringCount);
+      Assert.AreEqual("hello", message2.RepeatedStringList[0]);
+      Assert.AreEqual(7, message2.OptionalNestedMessage.Bb);
+    }
+
+    [Test]
+    public void TestLiteExtensions() {
+      // TODO(kenton):  Unlike other features of the lite library, extensions are
+      //   implemented completely differently from the regular library.  We
+      //   should probably test them more thoroughly.
+
+      TestAllExtensionsLite message =
+        TestAllExtensionsLite.CreateBuilder()
+          .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123)
+          .AddExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, "hello")
+          .SetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite,
+              TestAllTypesLite.Types.NestedEnum.BAZ)
+          .SetExtension(UnitTestLiteProtoFile.OptionalNestedMessageExtensionLite,
+              TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7).Build())
+          .Build();
+
+      // Test copying a message, since coping extensions actually does use a
+      // different code path between lite and regular libraries, and as of this
+      // writing, parsing hasn't been implemented yet.
+      TestAllExtensionsLite message2 = message.ToBuilder().Build();
+
+      Assert.AreEqual(123, (int)message2.GetExtension(
+          UnitTestLiteProtoFile.OptionalInt32ExtensionLite));
+      Assert.AreEqual(1, message2.GetExtensionCount(
+          UnitTestLiteProtoFile.RepeatedStringExtensionLite));
+      Assert.AreEqual(1, message2.GetExtension(
+          UnitTestLiteProtoFile.RepeatedStringExtensionLite).Count);
+      Assert.AreEqual("hello", message2.GetExtension(
+          UnitTestLiteProtoFile.RepeatedStringExtensionLite, 0));
+      Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.BAZ, message2.GetExtension(
+          UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite));
+      Assert.AreEqual(7, message2.GetExtension(
+          UnitTestLiteProtoFile.OptionalNestedMessageExtensionLite).Bb);
+    }
+  }
 }

+ 218 - 218
src/ProtocolBuffersLite.Test/MissingFieldAndExtensionTest.cs

@@ -1,219 +1,219 @@
-#region Copyright notice and license
-
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-
-#endregion
-
-using System.IO;
-using NUnit.Framework;
-using System.Collections.Generic;
-using Google.ProtocolBuffers.TestProtos;
-
-namespace Google.ProtocolBuffers {
-    [TestFixture]
-    public class MissingFieldAndExtensionTest {
-        [Test]
-        public void TestRecoverMissingExtensions() {
-            const int optionalInt32 = 12345678;
-            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-            builder.SetExtension(UnitTestProtoFile.OptionalInt32Extension, optionalInt32);
-            builder.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1.1);
-            builder.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1.2);
-            builder.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1.3);
-            TestAllExtensions msg = builder.Build();
-
-            Assert.IsTrue(msg.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
-            Assert.AreEqual(3, msg.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
-
-            byte[] bits = msg.ToByteArray();
-            TestAllExtensions copy = TestAllExtensions.ParseFrom(bits);
-            Assert.IsFalse(copy.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
-            Assert.AreEqual(0, copy.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
-            Assert.AreNotEqual(msg, copy);
-
-            //Even though copy does not understand the typees they serialize correctly
-            byte[] copybits = copy.ToByteArray();
-            Assert.AreEqual(bits, copybits);
-
-            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-            UnitTestProtoFile.RegisterAllExtensions(registry);
-
-            //Now we can take those copy bits and restore the full message with extensions
-            copy = TestAllExtensions.ParseFrom(copybits, registry);
-            Assert.IsTrue(copy.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
-            Assert.AreEqual(3, copy.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
-
-            Assert.AreEqual(msg, copy);
-            Assert.AreEqual(bits, copy.ToByteArray());
-
-            //If we modify the object this should all continue to work as before
-            copybits = copy.ToBuilder().Build().ToByteArray();
-            Assert.AreEqual(bits, copybits);
-
-            //If we replace extension the object this should all continue to work as before
-            copybits = copy.ToBuilder()
-                .SetExtension(UnitTestProtoFile.OptionalInt32Extension, optionalInt32)
-                .Build().ToByteArray();
-            Assert.AreEqual(bits, copybits);
-        }
-
-        [Test]
-        public void TestRecoverMissingFields() {
-            TestMissingFieldsA msga = TestMissingFieldsA.CreateBuilder()
-                .SetId(1001)
-                .SetName("Name")
-                .SetEmail("missing@field.value")
-                .Build();
-
-            //serialize to type B and verify all fields exist
-            TestMissingFieldsB msgb = TestMissingFieldsB.ParseFrom(msga.ToByteArray());
-            Assert.AreEqual(1001, msgb.Id);
-            Assert.AreEqual("Name", msgb.Name);
-            Assert.IsFalse(msgb.HasWebsite);
-            Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count);
-            Assert.AreEqual("missing@field.value", msgb.UnknownFields[TestMissingFieldsA.EmailFieldNumber].LengthDelimitedList[0].ToStringUtf8());
-
-            //serializes exactly the same (at least for this simple example)
-            Assert.AreEqual(msga.ToByteArray(), msgb.ToByteArray());
-            Assert.AreEqual(msga, TestMissingFieldsA.ParseFrom(msgb.ToByteArray()));
-
-            //now re-create an exact copy of A from serialized B
-            TestMissingFieldsA copya = TestMissingFieldsA.ParseFrom(msgb.ToByteArray());
-            Assert.AreEqual(msga, copya);
-            Assert.AreEqual(1001, copya.Id);
-            Assert.AreEqual("Name", copya.Name);
-            Assert.AreEqual("missing@field.value", copya.Email);
-
-            //Now we modify B... and try again
-            msgb = msgb.ToBuilder().SetWebsite("http://new.missing.field").Build();
-            //Does B still have the missing field?
-            Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count);
-
-            //Convert back to A and see if all fields are there?
-            copya = TestMissingFieldsA.ParseFrom(msgb.ToByteArray());
-            Assert.AreNotEqual(msga, copya);
-            Assert.AreEqual(1001, copya.Id);
-            Assert.AreEqual("Name", copya.Name);
-            Assert.AreEqual("missing@field.value", copya.Email);
-            Assert.AreEqual(1, copya.UnknownFields.FieldDictionary.Count);
-            Assert.AreEqual("http://new.missing.field", copya.UnknownFields[TestMissingFieldsB.WebsiteFieldNumber].LengthDelimitedList[0].ToStringUtf8());
-
-            //Lastly we can even still trip back to type B and see all fields:
-            TestMissingFieldsB copyb = TestMissingFieldsB.ParseFrom(copya.ToByteArray());
-            Assert.AreEqual(copya.ToByteArray().Length, copyb.ToByteArray().Length); //not exact order.
-            Assert.AreEqual(1001, copyb.Id);
-            Assert.AreEqual("Name", copyb.Name);
-            Assert.AreEqual("http://new.missing.field", copyb.Website);
-            Assert.AreEqual(1, copyb.UnknownFields.FieldDictionary.Count);
-            Assert.AreEqual("missing@field.value", copyb.UnknownFields[TestMissingFieldsA.EmailFieldNumber].LengthDelimitedList[0].ToStringUtf8());
-        }
-
-        [Test]
-        public void TestRecoverMissingMessage() {
-            TestMissingFieldsA.Types.SubA suba = TestMissingFieldsA.Types.SubA.CreateBuilder().SetCount(3).AddValues("a").AddValues("b").AddValues("c").Build();
-            TestMissingFieldsA msga = TestMissingFieldsA.CreateBuilder()
-                .SetId(1001)
-                .SetName("Name")
-                .SetTestA(suba)
-                .Build();
-
-            //serialize to type B and verify all fields exist
-            TestMissingFieldsB msgb = TestMissingFieldsB.ParseFrom(msga.ToByteArray());
-            Assert.AreEqual(1001, msgb.Id);
-            Assert.AreEqual("Name", msgb.Name);
-            Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count);
-            Assert.AreEqual(suba.ToString(), TestMissingFieldsA.Types.SubA.ParseFrom(msgb.UnknownFields[TestMissingFieldsA.TestAFieldNumber].LengthDelimitedList[0]).ToString());
-
-            //serializes exactly the same (at least for this simple example)
-            Assert.AreEqual(msga.ToByteArray(), msgb.ToByteArray());
-            Assert.AreEqual(msga, TestMissingFieldsA.ParseFrom(msgb.ToByteArray()));
-
-            //now re-create an exact copy of A from serialized B
-            TestMissingFieldsA copya = TestMissingFieldsA.ParseFrom(msgb.ToByteArray());
-            Assert.AreEqual(msga, copya);
-            Assert.AreEqual(1001, copya.Id);
-            Assert.AreEqual("Name", copya.Name);
-            Assert.AreEqual(suba, copya.TestA);
-
-            //Now we modify B... and try again
-            TestMissingFieldsB.Types.SubB subb = TestMissingFieldsB.Types.SubB.CreateBuilder().AddValues("test-b").Build();
-            msgb = msgb.ToBuilder().SetTestB(subb).Build();
-            //Does B still have the missing field?
-            Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count);
-
-            //Convert back to A and see if all fields are there?
-            copya = TestMissingFieldsA.ParseFrom(msgb.ToByteArray());
-            Assert.AreNotEqual(msga, copya);
-            Assert.AreEqual(1001, copya.Id);
-            Assert.AreEqual("Name", copya.Name);
-            Assert.AreEqual(suba, copya.TestA);
-            Assert.AreEqual(1, copya.UnknownFields.FieldDictionary.Count);
-            Assert.AreEqual(subb.ToByteArray(), copya.UnknownFields[TestMissingFieldsB.TestBFieldNumber].LengthDelimitedList[0].ToByteArray());
-
-            //Lastly we can even still trip back to type B and see all fields:
-            TestMissingFieldsB copyb = TestMissingFieldsB.ParseFrom(copya.ToByteArray());
-            Assert.AreEqual(copya.ToByteArray().Length, copyb.ToByteArray().Length); //not exact order.
-            Assert.AreEqual(1001, copyb.Id);
-            Assert.AreEqual("Name", copyb.Name);
-            Assert.AreEqual(subb, copyb.TestB);
-            Assert.AreEqual(1, copyb.UnknownFields.FieldDictionary.Count);
-        }
-
-        [Test]
-        public void TestRestoreFromOtherType() {
-            TestInteropPerson person = TestInteropPerson.CreateBuilder()
-                .SetId(123)
-                .SetName("abc")
-                .SetEmail("abc@123.com")
-                .AddRangeCodes(new[] {1, 2, 3})
-                .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build())
-                .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build())
-                .AddAddresses(TestInteropPerson.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build())
-                .SetExtension(UnitTestExtrasFullProtoFile.EmployeeId, TestInteropEmployeeId.CreateBuilder().SetNumber("123").Build())
-                .Build();
-            Assert.IsTrue(person.IsInitialized);
-
-            TestEmptyMessage temp = TestEmptyMessage.ParseFrom(person.ToByteArray());
-            Assert.AreEqual(7, temp.UnknownFields.FieldDictionary.Count);
-            temp = temp.ToBuilder().Build();
-            Assert.AreEqual(7, temp.UnknownFields.FieldDictionary.Count);
-
-            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-            UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry);
-
-            TestInteropPerson copy = TestInteropPerson.ParseFrom(temp.ToByteArray(), registry);
-            Assert.AreEqual(person, copy);
-            Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
-        }
-    }
+#region Copyright notice and license
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+#endregion
+
+using System.IO;
+using NUnit.Framework;
+using System.Collections.Generic;
+using Google.ProtocolBuffers.TestProtos;
+
+namespace Google.ProtocolBuffers {
+    [TestFixture]
+    public class MissingFieldAndExtensionTest {
+        [Test]
+        public void TestRecoverMissingExtensions() {
+            const int optionalInt32 = 12345678;
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            builder.SetExtension(UnitTestProtoFile.OptionalInt32Extension, optionalInt32);
+            builder.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1.1);
+            builder.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1.2);
+            builder.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1.3);
+            TestAllExtensions msg = builder.Build();
+
+            Assert.IsTrue(msg.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.AreEqual(3, msg.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
+
+            byte[] bits = msg.ToByteArray();
+            TestAllExtensions copy = TestAllExtensions.ParseFrom(bits);
+            Assert.IsFalse(copy.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.AreEqual(0, copy.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
+            Assert.AreNotEqual(msg, copy);
+
+            //Even though copy does not understand the typees they serialize correctly
+            byte[] copybits = copy.ToByteArray();
+            Assert.AreEqual(bits, copybits);
+
+            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+            UnitTestProtoFile.RegisterAllExtensions(registry);
+
+            //Now we can take those copy bits and restore the full message with extensions
+            copy = TestAllExtensions.ParseFrom(copybits, registry);
+            Assert.IsTrue(copy.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.AreEqual(3, copy.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
+
+            Assert.AreEqual(msg, copy);
+            Assert.AreEqual(bits, copy.ToByteArray());
+
+            //If we modify the object this should all continue to work as before
+            copybits = copy.ToBuilder().Build().ToByteArray();
+            Assert.AreEqual(bits, copybits);
+
+            //If we replace extension the object this should all continue to work as before
+            copybits = copy.ToBuilder()
+                .SetExtension(UnitTestProtoFile.OptionalInt32Extension, optionalInt32)
+                .Build().ToByteArray();
+            Assert.AreEqual(bits, copybits);
+        }
+
+        [Test]
+        public void TestRecoverMissingFields() {
+            TestMissingFieldsA msga = TestMissingFieldsA.CreateBuilder()
+                .SetId(1001)
+                .SetName("Name")
+                .SetEmail("missing@field.value")
+                .Build();
+
+            //serialize to type B and verify all fields exist
+            TestMissingFieldsB msgb = TestMissingFieldsB.ParseFrom(msga.ToByteArray());
+            Assert.AreEqual(1001, msgb.Id);
+            Assert.AreEqual("Name", msgb.Name);
+            Assert.IsFalse(msgb.HasWebsite);
+            Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count);
+            Assert.AreEqual("missing@field.value", msgb.UnknownFields[TestMissingFieldsA.EmailFieldNumber].LengthDelimitedList[0].ToStringUtf8());
+
+            //serializes exactly the same (at least for this simple example)
+            Assert.AreEqual(msga.ToByteArray(), msgb.ToByteArray());
+            Assert.AreEqual(msga, TestMissingFieldsA.ParseFrom(msgb.ToByteArray()));
+
+            //now re-create an exact copy of A from serialized B
+            TestMissingFieldsA copya = TestMissingFieldsA.ParseFrom(msgb.ToByteArray());
+            Assert.AreEqual(msga, copya);
+            Assert.AreEqual(1001, copya.Id);
+            Assert.AreEqual("Name", copya.Name);
+            Assert.AreEqual("missing@field.value", copya.Email);
+
+            //Now we modify B... and try again
+            msgb = msgb.ToBuilder().SetWebsite("http://new.missing.field").Build();
+            //Does B still have the missing field?
+            Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count);
+
+            //Convert back to A and see if all fields are there?
+            copya = TestMissingFieldsA.ParseFrom(msgb.ToByteArray());
+            Assert.AreNotEqual(msga, copya);
+            Assert.AreEqual(1001, copya.Id);
+            Assert.AreEqual("Name", copya.Name);
+            Assert.AreEqual("missing@field.value", copya.Email);
+            Assert.AreEqual(1, copya.UnknownFields.FieldDictionary.Count);
+            Assert.AreEqual("http://new.missing.field", copya.UnknownFields[TestMissingFieldsB.WebsiteFieldNumber].LengthDelimitedList[0].ToStringUtf8());
+
+            //Lastly we can even still trip back to type B and see all fields:
+            TestMissingFieldsB copyb = TestMissingFieldsB.ParseFrom(copya.ToByteArray());
+            Assert.AreEqual(copya.ToByteArray().Length, copyb.ToByteArray().Length); //not exact order.
+            Assert.AreEqual(1001, copyb.Id);
+            Assert.AreEqual("Name", copyb.Name);
+            Assert.AreEqual("http://new.missing.field", copyb.Website);
+            Assert.AreEqual(1, copyb.UnknownFields.FieldDictionary.Count);
+            Assert.AreEqual("missing@field.value", copyb.UnknownFields[TestMissingFieldsA.EmailFieldNumber].LengthDelimitedList[0].ToStringUtf8());
+        }
+
+        [Test]
+        public void TestRecoverMissingMessage() {
+            TestMissingFieldsA.Types.SubA suba = TestMissingFieldsA.Types.SubA.CreateBuilder().SetCount(3).AddValues("a").AddValues("b").AddValues("c").Build();
+            TestMissingFieldsA msga = TestMissingFieldsA.CreateBuilder()
+                .SetId(1001)
+                .SetName("Name")
+                .SetTestA(suba)
+                .Build();
+
+            //serialize to type B and verify all fields exist
+            TestMissingFieldsB msgb = TestMissingFieldsB.ParseFrom(msga.ToByteArray());
+            Assert.AreEqual(1001, msgb.Id);
+            Assert.AreEqual("Name", msgb.Name);
+            Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count);
+            Assert.AreEqual(suba.ToString(), TestMissingFieldsA.Types.SubA.ParseFrom(msgb.UnknownFields[TestMissingFieldsA.TestAFieldNumber].LengthDelimitedList[0]).ToString());
+
+            //serializes exactly the same (at least for this simple example)
+            Assert.AreEqual(msga.ToByteArray(), msgb.ToByteArray());
+            Assert.AreEqual(msga, TestMissingFieldsA.ParseFrom(msgb.ToByteArray()));
+
+            //now re-create an exact copy of A from serialized B
+            TestMissingFieldsA copya = TestMissingFieldsA.ParseFrom(msgb.ToByteArray());
+            Assert.AreEqual(msga, copya);
+            Assert.AreEqual(1001, copya.Id);
+            Assert.AreEqual("Name", copya.Name);
+            Assert.AreEqual(suba, copya.TestA);
+
+            //Now we modify B... and try again
+            TestMissingFieldsB.Types.SubB subb = TestMissingFieldsB.Types.SubB.CreateBuilder().AddValues("test-b").Build();
+            msgb = msgb.ToBuilder().SetTestB(subb).Build();
+            //Does B still have the missing field?
+            Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count);
+
+            //Convert back to A and see if all fields are there?
+            copya = TestMissingFieldsA.ParseFrom(msgb.ToByteArray());
+            Assert.AreNotEqual(msga, copya);
+            Assert.AreEqual(1001, copya.Id);
+            Assert.AreEqual("Name", copya.Name);
+            Assert.AreEqual(suba, copya.TestA);
+            Assert.AreEqual(1, copya.UnknownFields.FieldDictionary.Count);
+            Assert.AreEqual(subb.ToByteArray(), copya.UnknownFields[TestMissingFieldsB.TestBFieldNumber].LengthDelimitedList[0].ToByteArray());
+
+            //Lastly we can even still trip back to type B and see all fields:
+            TestMissingFieldsB copyb = TestMissingFieldsB.ParseFrom(copya.ToByteArray());
+            Assert.AreEqual(copya.ToByteArray().Length, copyb.ToByteArray().Length); //not exact order.
+            Assert.AreEqual(1001, copyb.Id);
+            Assert.AreEqual("Name", copyb.Name);
+            Assert.AreEqual(subb, copyb.TestB);
+            Assert.AreEqual(1, copyb.UnknownFields.FieldDictionary.Count);
+        }
+
+        [Test]
+        public void TestRestoreFromOtherType() {
+            TestInteropPerson person = TestInteropPerson.CreateBuilder()
+                .SetId(123)
+                .SetName("abc")
+                .SetEmail("abc@123.com")
+                .AddRangeCodes(new[] {1, 2, 3})
+                .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build())
+                .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build())
+                .AddAddresses(TestInteropPerson.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build())
+                .SetExtension(UnitTestExtrasFullProtoFile.EmployeeId, TestInteropEmployeeId.CreateBuilder().SetNumber("123").Build())
+                .Build();
+            Assert.IsTrue(person.IsInitialized);
+
+            TestEmptyMessage temp = TestEmptyMessage.ParseFrom(person.ToByteArray());
+            Assert.AreEqual(7, temp.UnknownFields.FieldDictionary.Count);
+            temp = temp.ToBuilder().Build();
+            Assert.AreEqual(7, temp.UnknownFields.FieldDictionary.Count);
+
+            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+            UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry);
+
+            TestInteropPerson copy = TestInteropPerson.ParseFrom(temp.ToByteArray(), registry);
+            Assert.AreEqual(person, copy);
+            Assert.AreEqual(person.ToByteArray(), copy.ToByteArray());
+        }
+    }
 }

+ 83 - 83
src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj

@@ -1,84 +1,84 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{EE01ED24-3750-4567-9A23-1DB676A15610}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Google.ProtocolBuffers</RootNamespace>
-    <AssemblyName>Google.ProtocolBuffersLite.Test</AssemblyName>
-    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <SignAssembly>true</SignAssembly>
-    <AssemblyOriginatorKeyFile>..\..\keys\Google.ProtocolBuffers.snk</AssemblyOriginatorKeyFile>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>3.5</OldToolsVersion>
-    <UpgradeBackupLocation />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <NoStdLib>true</NoStdLib>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <NoStdLib>true</NoStdLib>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\lib\NUnit 2.2.8.0\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="Rhino.Mocks, Version=3.5.0.2, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\lib\Rhino.Mocks.dll</HintPath>
-    </Reference>
-    <Reference Include="mscorlib" />
-    <Reference Include="System" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\ProtocolBuffers.Test\Properties\AssemblyInfo.cs">
-      <Link>Properties\AssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="AbstractBuilderLiteTest.cs" />
-    <Compile Include="AbstractMessageLiteTest.cs" />
-    <Compile Include="ExtendableBuilderLiteTest.cs" />
-    <Compile Include="ExtendableMessageLiteTest.cs" />
-    <Compile Include="LiteTest.cs" />
-    <Compile Include="TestLiteByApi.cs" />
-    <Compile Include="TestProtos\UnitTestExtrasLiteProtoFile.cs" />
-    <Compile Include="TestProtos\UnitTestImportLiteProtoFile.cs" />
-    <Compile Include="TestProtos\UnitTestLiteProtoFile.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\ProtocolBuffers\ProtocolBuffersLite.csproj">
-      <Project>{6969BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
-      <Name>ProtocolBuffersLite</Name>
-      <Private>True</Private>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{EE01ED24-3750-4567-9A23-1DB676A15610}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Google.ProtocolBuffers</RootNamespace>
+    <AssemblyName>Google.ProtocolBuffersLite.Test</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>..\..\keys\Google.ProtocolBuffers.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\lib\NUnit 2.2.8.0\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="Rhino.Mocks, Version=3.5.0.2, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\lib\Rhino.Mocks.dll</HintPath>
+    </Reference>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\ProtocolBuffers.Test\Properties\AssemblyInfo.cs">
+      <Link>Properties\AssemblyInfo.cs</Link>
+    </Compile>
+    <Compile Include="AbstractBuilderLiteTest.cs" />
+    <Compile Include="AbstractMessageLiteTest.cs" />
+    <Compile Include="ExtendableBuilderLiteTest.cs" />
+    <Compile Include="ExtendableMessageLiteTest.cs" />
+    <Compile Include="LiteTest.cs" />
+    <Compile Include="TestLiteByApi.cs" />
+    <Compile Include="TestProtos\UnitTestExtrasLiteProtoFile.cs" />
+    <Compile Include="TestProtos\UnitTestImportLiteProtoFile.cs" />
+    <Compile Include="TestProtos\UnitTestLiteProtoFile.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\ProtocolBuffers\ProtocolBuffersLite.csproj">
+      <Project>{6969BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
+      <Name>ProtocolBuffersLite</Name>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
 </Project>

+ 88 - 88
src/ProtocolBuffersLite.Test/ProtocolBuffersLiteMixed.Test.csproj

@@ -1,89 +1,89 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{EEFFED24-3750-4567-9A23-1DB676A15610}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Google.ProtocolBuffers</RootNamespace>
-    <AssemblyName>Google.ProtocolBuffersMixedLite.Test</AssemblyName>
-    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <SignAssembly>true</SignAssembly>
-    <AssemblyOriginatorKeyFile>..\..\keys\Google.ProtocolBuffers.snk</AssemblyOriginatorKeyFile>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>3.5</OldToolsVersion>
-    <UpgradeBackupLocation />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <NoStdLib>true</NoStdLib>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <NoStdLib>true</NoStdLib>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\lib\NUnit 2.2.8.0\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="Rhino.Mocks, Version=3.5.0.2, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\lib\Rhino.Mocks.dll</HintPath>
-    </Reference>
-    <Reference Include="mscorlib" />
-    <Reference Include="System" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\ProtocolBuffers.Test\Properties\AssemblyInfo.cs">
-      <Link>Properties\AssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="AbstractBuilderLiteTest.cs" />
-    <Compile Include="AbstractMessageLiteTest.cs" />
-    <Compile Include="ExtendableBuilderLiteTest.cs" />
-    <Compile Include="ExtendableMessageLiteTest.cs" />
-    <Compile Include="InteropLiteTest.cs" />
-    <Compile Include="LiteTest.cs" />
-    <Compile Include="MissingFieldAndExtensionTest.cs" />
-    <Compile Include="TestLiteByApi.cs" />
-    <Compile Include="TestProtos\UnitTestExtrasFullProtoFile.cs" />
-    <Compile Include="TestProtos\UnitTestExtrasLiteProtoFile.cs" />
-    <Compile Include="TestProtos\UnitTestImportLiteProtoFile.cs" />
-    <Compile Include="TestProtos\UnitTestImportProtoFile.cs" />
-    <Compile Include="TestProtos\UnitTestLiteImportNonLiteProtoFile.cs" />
-    <Compile Include="TestProtos\UnitTestLiteProtoFile.cs" />
-    <Compile Include="TestProtos\UnitTestProtoFile.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\ProtocolBuffers\ProtocolBuffers.csproj">
-      <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
-      <Name>ProtocolBuffers</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{EEFFED24-3750-4567-9A23-1DB676A15610}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Google.ProtocolBuffers</RootNamespace>
+    <AssemblyName>Google.ProtocolBuffersMixedLite.Test</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>..\..\keys\Google.ProtocolBuffers.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <NoStdLib>true</NoStdLib>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <NoStdLib>true</NoStdLib>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\lib\NUnit 2.2.8.0\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="Rhino.Mocks, Version=3.5.0.2, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\lib\Rhino.Mocks.dll</HintPath>
+    </Reference>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\ProtocolBuffers.Test\Properties\AssemblyInfo.cs">
+      <Link>Properties\AssemblyInfo.cs</Link>
+    </Compile>
+    <Compile Include="AbstractBuilderLiteTest.cs" />
+    <Compile Include="AbstractMessageLiteTest.cs" />
+    <Compile Include="ExtendableBuilderLiteTest.cs" />
+    <Compile Include="ExtendableMessageLiteTest.cs" />
+    <Compile Include="InteropLiteTest.cs" />
+    <Compile Include="LiteTest.cs" />
+    <Compile Include="MissingFieldAndExtensionTest.cs" />
+    <Compile Include="TestLiteByApi.cs" />
+    <Compile Include="TestProtos\UnitTestExtrasFullProtoFile.cs" />
+    <Compile Include="TestProtos\UnitTestExtrasLiteProtoFile.cs" />
+    <Compile Include="TestProtos\UnitTestImportLiteProtoFile.cs" />
+    <Compile Include="TestProtos\UnitTestImportProtoFile.cs" />
+    <Compile Include="TestProtos\UnitTestLiteImportNonLiteProtoFile.cs" />
+    <Compile Include="TestProtos\UnitTestLiteProtoFile.cs" />
+    <Compile Include="TestProtos\UnitTestProtoFile.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\ProtocolBuffers\ProtocolBuffers.csproj">
+      <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
+      <Name>ProtocolBuffers</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
 </Project>

+ 113 - 113
src/ProtocolBuffersLite.Test/TestLiteByApi.cs

@@ -1,113 +1,113 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// 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.
-#endregion
-
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class TestLiteByApi {
-
-    [Test]
-    public void TestAllTypesEquality() {
-      TestAllTypesLite msg = TestAllTypesLite.DefaultInstance;
-      TestAllTypesLite copy = msg.ToBuilder().Build();
-      Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode());
-      Assert.IsTrue(msg.Equals(copy));
-      msg = msg.ToBuilder().SetOptionalString("Hi").Build();
-      Assert.AreNotEqual(msg.GetHashCode(), copy.GetHashCode());
-      Assert.IsFalse(msg.Equals(copy));
-      copy = copy.ToBuilder().SetOptionalString("Hi").Build();
-      Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode());
-      Assert.IsTrue(msg.Equals(copy));
-    }
-
-    [Test]
-    public void TestEqualityOnExtensions() {
-      TestAllExtensionsLite msg = TestAllExtensionsLite.DefaultInstance;
-      TestAllExtensionsLite copy = msg.ToBuilder().Build();
-      Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode());
-      Assert.IsTrue(msg.Equals(copy));
-      msg = msg.ToBuilder().SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Hi").Build();
-      Assert.AreNotEqual(msg.GetHashCode(), copy.GetHashCode());
-      Assert.IsFalse(msg.Equals(copy));
-      copy = copy.ToBuilder().SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Hi").Build();
-      Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode());
-      Assert.IsTrue(msg.Equals(copy));
-    }
-
-    [Test]
-    public void TestAllTypesToString() {
-      TestAllTypesLite msg = TestAllTypesLite.DefaultInstance;
-      TestAllTypesLite copy = msg.ToBuilder().Build();
-      Assert.AreEqual(msg.ToString(), copy.ToString());
-      Assert.IsEmpty(msg.ToString());
-      msg = msg.ToBuilder().SetOptionalInt32(-1).Build();
-      Assert.AreEqual("optional_int32: -1", msg.ToString().TrimEnd());
-      msg = msg.ToBuilder().SetOptionalString("abc123").Build();
-      Assert.AreEqual("optional_int32: -1\noptional_string: \"abc123\"", msg.ToString().Replace("\r", "").TrimEnd());
-    }
-
-    [Test]
-    public void TestAllTypesDefaultedRoundTrip() {
-      TestAllTypesLite msg = TestAllTypesLite.DefaultInstance;
-      Assert.IsTrue(msg.IsInitialized);
-      TestAllTypesLite copy = TestAllTypesLite.CreateBuilder().MergeFrom(msg.ToByteArray()).Build();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-    [Test]
-    public void TestAllTypesModifiedRoundTrip() {
-      TestAllTypesLite msg = TestAllTypesLite.DefaultInstance;
-      msg.ToBuilder()
-        .SetOptionalBool(true)
-        .SetOptionalCord("Hi")
-        .SetOptionalDouble(1.123)
-        .SetOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_FOO)
-        .SetOptionalForeignMessage(ForeignMessageLite.CreateBuilder().SetC('c').Build())
-        .SetOptionalGroup(TestAllTypesLite.Types.OptionalGroup.CreateBuilder().SetA('a').Build())
-        .SetOptionalImportEnum(ImportEnumLite.IMPORT_LITE_BAR)
-        .SetOptionalInt32(32)
-        .SetOptionalInt64(64)
-        .SetOptionalNestedEnum(TestAllTypesLite.Types.NestedEnum.FOO)
-        .SetOptionalString("SetOptionalString")
-        .AddRepeatedGroup(TestAllTypesLite.Types.RepeatedGroup.CreateBuilder().SetA('a').Build())
-        .AddRepeatedGroup(TestAllTypesLite.Types.RepeatedGroup.CreateBuilder().SetA('A').Build())
-        ;
-      TestAllTypesLite copy = TestAllTypesLite.CreateBuilder().MergeFrom(msg.ToByteArray()).Build();
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-    }
-
-  }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// 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.
+#endregion
+
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers {
+  [TestFixture]
+  public class TestLiteByApi {
+
+    [Test]
+    public void TestAllTypesEquality() {
+      TestAllTypesLite msg = TestAllTypesLite.DefaultInstance;
+      TestAllTypesLite copy = msg.ToBuilder().Build();
+      Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode());
+      Assert.IsTrue(msg.Equals(copy));
+      msg = msg.ToBuilder().SetOptionalString("Hi").Build();
+      Assert.AreNotEqual(msg.GetHashCode(), copy.GetHashCode());
+      Assert.IsFalse(msg.Equals(copy));
+      copy = copy.ToBuilder().SetOptionalString("Hi").Build();
+      Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode());
+      Assert.IsTrue(msg.Equals(copy));
+    }
+
+    [Test]
+    public void TestEqualityOnExtensions() {
+      TestAllExtensionsLite msg = TestAllExtensionsLite.DefaultInstance;
+      TestAllExtensionsLite copy = msg.ToBuilder().Build();
+      Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode());
+      Assert.IsTrue(msg.Equals(copy));
+      msg = msg.ToBuilder().SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Hi").Build();
+      Assert.AreNotEqual(msg.GetHashCode(), copy.GetHashCode());
+      Assert.IsFalse(msg.Equals(copy));
+      copy = copy.ToBuilder().SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Hi").Build();
+      Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode());
+      Assert.IsTrue(msg.Equals(copy));
+    }
+
+    [Test]
+    public void TestAllTypesToString() {
+      TestAllTypesLite msg = TestAllTypesLite.DefaultInstance;
+      TestAllTypesLite copy = msg.ToBuilder().Build();
+      Assert.AreEqual(msg.ToString(), copy.ToString());
+      Assert.IsEmpty(msg.ToString());
+      msg = msg.ToBuilder().SetOptionalInt32(-1).Build();
+      Assert.AreEqual("optional_int32: -1", msg.ToString().TrimEnd());
+      msg = msg.ToBuilder().SetOptionalString("abc123").Build();
+      Assert.AreEqual("optional_int32: -1\noptional_string: \"abc123\"", msg.ToString().Replace("\r", "").TrimEnd());
+    }
+
+    [Test]
+    public void TestAllTypesDefaultedRoundTrip() {
+      TestAllTypesLite msg = TestAllTypesLite.DefaultInstance;
+      Assert.IsTrue(msg.IsInitialized);
+      TestAllTypesLite copy = TestAllTypesLite.CreateBuilder().MergeFrom(msg.ToByteArray()).Build();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+    [Test]
+    public void TestAllTypesModifiedRoundTrip() {
+      TestAllTypesLite msg = TestAllTypesLite.DefaultInstance;
+      msg.ToBuilder()
+        .SetOptionalBool(true)
+        .SetOptionalCord("Hi")
+        .SetOptionalDouble(1.123)
+        .SetOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_FOO)
+        .SetOptionalForeignMessage(ForeignMessageLite.CreateBuilder().SetC('c').Build())
+        .SetOptionalGroup(TestAllTypesLite.Types.OptionalGroup.CreateBuilder().SetA('a').Build())
+        .SetOptionalImportEnum(ImportEnumLite.IMPORT_LITE_BAR)
+        .SetOptionalInt32(32)
+        .SetOptionalInt64(64)
+        .SetOptionalNestedEnum(TestAllTypesLite.Types.NestedEnum.FOO)
+        .SetOptionalString("SetOptionalString")
+        .AddRepeatedGroup(TestAllTypesLite.Types.RepeatedGroup.CreateBuilder().SetA('a').Build())
+        .AddRepeatedGroup(TestAllTypesLite.Types.RepeatedGroup.CreateBuilder().SetA('A').Build())
+        ;
+      TestAllTypesLite copy = TestAllTypesLite.CreateBuilder().MergeFrom(msg.ToByteArray()).Build();
+      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+    }
+
+  }
+}

+ 1721 - 1721
src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs

@@ -1,1721 +1,1721 @@
-// Generated by ProtoGen, Version=0.9.0.0, Culture=neutral, PublicKeyToken=8fd7408b07f8d2cd.  DO NOT EDIT!
-
-using pb = global::Google.ProtocolBuffers;
-using pbc = global::Google.ProtocolBuffers.Collections;
-using pbd = global::Google.ProtocolBuffers.Descriptors;
-using scg = global::System.Collections.Generic;
-namespace Google.ProtocolBuffers.TestProtos {
-  
-  public static partial class UnitTestExtrasLiteProtoFile {
-  
-    #region Extension registration
-    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
-      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.EmployeeIdLite);
-    }
-    #endregion
-    #region Extensions
-    public const int EmployeeIdLiteFieldNumber = 126;
-    public static pb::GeneratedExtensionLite<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite, global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite> EmployeeIdLite;
-    #endregion
-    
-    #region Static variables
-    #endregion
-    #region Extensions
-    internal static readonly object Descriptor;
-    static UnitTestExtrasLiteProtoFile() {
-      Descriptor = null;
-      global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.EmployeeIdLite = 
-        new pb::GeneratedExtensionLite<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite, global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite>(
-          "protobuf_unittest_extra.employee_id_lite",
-          global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.DefaultInstance,
-          null,
-          global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite.DefaultInstance,
-          null,
-          global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.EmployeeIdLiteFieldNumber,
-          pbd::FieldType.Message);
-    }
-    #endregion
-    
-  }
-  #region Enums
-  public enum ExtraEnum {
-    DEFAULT = 10,
-    EXLITE_FOO = 7,
-    EXLITE_BAR = 8,
-    EXLITE_BAZ = 9,
-  }
-  
-  #endregion
-  
-  #region Messages
-  public sealed partial class TestRequiredLite : pb::GeneratedMessageLite<TestRequiredLite, TestRequiredLite.Builder> {
-    private static readonly TestRequiredLite defaultInstance = new Builder().BuildPartial();
-    public static TestRequiredLite DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override TestRequiredLite DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override TestRequiredLite ThisMessage {
-      get { return this; }
-    }
-    
-    public const int DFieldNumber = 1;
-    private bool hasD;
-    private int d_ = 0;
-    public bool HasD {
-      get { return hasD; }
-    }
-    public int D {
-      get { return d_; }
-    }
-    
-    public const int EnFieldNumber = 2;
-    private bool hasEn;
-    private global::Google.ProtocolBuffers.TestProtos.ExtraEnum en_ = global::Google.ProtocolBuffers.TestProtos.ExtraEnum.DEFAULT;
-    public bool HasEn {
-      get { return hasEn; }
-    }
-    public global::Google.ProtocolBuffers.TestProtos.ExtraEnum En {
-      get { return en_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        if (!hasD) return false;
-        if (!hasEn) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasD) {
-        output.WriteInt32(1, D);
-      }
-      if (HasEn) {
-        output.WriteEnum(2, (int) En);
-      }
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasD) {
-          size += pb::CodedOutputStream.ComputeInt32Size(1, D);
-        }
-        if (HasEn) {
-          size += pb::CodedOutputStream.ComputeEnumSize(2, (int) En);
-        }
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    #region Lite runtime methods
-    public override int GetHashCode() {
-      int hash = GetType().GetHashCode();
-      if (hasD) hash ^= d_.GetHashCode();
-      if (hasEn) hash ^= en_.GetHashCode();
-      return hash;
-    }
-    
-    public override bool Equals(object obj) {
-      TestRequiredLite other = obj as TestRequiredLite;
-      if (other == null) return false;
-      if (hasD != other.hasD || (hasD && !d_.Equals(other.d_))) return false;
-      if (hasEn != other.hasEn || (hasEn && !en_.Equals(other.en_))) return false;
-      return true;
-    }
-    
-    public override void PrintTo(global::System.IO.TextWriter writer) {
-      PrintField("d", hasD, d_, writer);
-      PrintField("en", hasEn, en_, writer);
-    }
-    #endregion
-    
-    public static TestRequiredLite ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static TestRequiredLite ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static TestRequiredLite ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static TestRequiredLite ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static TestRequiredLite ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static TestRequiredLite ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static TestRequiredLite ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static TestRequiredLite ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static TestRequiredLite ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static TestRequiredLite ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(TestRequiredLite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilderLite<TestRequiredLite, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      TestRequiredLite result = new TestRequiredLite();
-      
-      protected override TestRequiredLite MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new TestRequiredLite();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override TestRequiredLite DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.TestProtos.TestRequiredLite.DefaultInstance; }
-      }
-      
-      public override TestRequiredLite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        TestRequiredLite returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessageLite other) {
-        if (other is TestRequiredLite) {
-          return MergeFrom((TestRequiredLite) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(TestRequiredLite other) {
-        if (other == global::Google.ProtocolBuffers.TestProtos.TestRequiredLite.DefaultInstance) return this;
-        if (other.HasD) {
-          D = other.D;
-        }
-        if (other.HasEn) {
-          En = other.En;
-        }
-        return this;
-      }
-      
-      public override Builder MergeFrom(pb::CodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-      
-      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                return this;
-              }
-              ParseUnknownField(input, extensionRegistry, tag);
-              break;
-            }
-            case 8: {
-              D = input.ReadInt32();
-              break;
-            }
-            case 16: {
-              int rawValue = input.ReadEnum();
-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ExtraEnum), rawValue)) {
-              } else {
-                En = (global::Google.ProtocolBuffers.TestProtos.ExtraEnum) rawValue;
-              }
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasD {
-        get { return result.HasD; }
-      }
-      public int D {
-        get { return result.D; }
-        set { SetD(value); }
-      }
-      public Builder SetD(int value) {
-        result.hasD = true;
-        result.d_ = value;
-        return this;
-      }
-      public Builder ClearD() {
-        result.hasD = false;
-        result.d_ = 0;
-        return this;
-      }
-      
-      public bool HasEn {
-       get { return result.HasEn; }
-      }
-      public global::Google.ProtocolBuffers.TestProtos.ExtraEnum En {
-        get { return result.En; }
-        set { SetEn(value); }
-      }
-      public Builder SetEn(global::Google.ProtocolBuffers.TestProtos.ExtraEnum value) {
-        result.hasEn = true;
-        result.en_ = value;
-        return this;
-      }
-      public Builder ClearEn() {
-        result.hasEn = false;
-        result.en_ = global::Google.ProtocolBuffers.TestProtos.ExtraEnum.DEFAULT;
-        return this;
-      }
-    }
-    static TestRequiredLite() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class TestInteropPersonLite : pb::ExtendableMessageLite<TestInteropPersonLite, TestInteropPersonLite.Builder> {
-    private static readonly TestInteropPersonLite defaultInstance = new Builder().BuildPartial();
-    public static TestInteropPersonLite DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override TestInteropPersonLite DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override TestInteropPersonLite ThisMessage {
-      get { return this; }
-    }
-    
-    #region Nested types
-    public static class Types {
-      public enum PhoneType {
-        MOBILE = 0,
-        HOME = 1,
-        WORK = 2,
-      }
-      
-      public sealed partial class PhoneNumber : pb::GeneratedMessageLite<PhoneNumber, PhoneNumber.Builder> {
-        private static readonly PhoneNumber defaultInstance = new Builder().BuildPartial();
-        public static PhoneNumber DefaultInstance {
-          get { return defaultInstance; }
-        }
-        
-        public override PhoneNumber DefaultInstanceForType {
-          get { return defaultInstance; }
-        }
-        
-        protected override PhoneNumber ThisMessage {
-          get { return this; }
-        }
-        
-        public const int NumberFieldNumber = 1;
-        private bool hasNumber;
-        private string number_ = "";
-        public bool HasNumber {
-          get { return hasNumber; }
-        }
-        public string Number {
-          get { return number_; }
-        }
-        
-        public const int TypeFieldNumber = 2;
-        private bool hasType;
-        private global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType type_ = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType.HOME;
-        public bool HasType {
-          get { return hasType; }
-        }
-        public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType Type {
-          get { return type_; }
-        }
-        
-        public override bool IsInitialized {
-          get {
-            if (!hasNumber) return false;
-            return true;
-          }
-        }
-        
-        public override void WriteTo(pb::CodedOutputStream output) {
-          int size = SerializedSize;
-          if (HasNumber) {
-            output.WriteString(1, Number);
-          }
-          if (HasType) {
-            output.WriteEnum(2, (int) Type);
-          }
-        }
-        
-        private int memoizedSerializedSize = -1;
-        public override int SerializedSize {
-          get {
-            int size = memoizedSerializedSize;
-            if (size != -1) return size;
-            
-            size = 0;
-            if (HasNumber) {
-              size += pb::CodedOutputStream.ComputeStringSize(1, Number);
-            }
-            if (HasType) {
-              size += pb::CodedOutputStream.ComputeEnumSize(2, (int) Type);
-            }
-            memoizedSerializedSize = size;
-            return size;
-          }
-        }
-        
-        #region Lite runtime methods
-        public override int GetHashCode() {
-          int hash = GetType().GetHashCode();
-          if (hasNumber) hash ^= number_.GetHashCode();
-          if (hasType) hash ^= type_.GetHashCode();
-          return hash;
-        }
-        
-        public override bool Equals(object obj) {
-          PhoneNumber other = obj as PhoneNumber;
-          if (other == null) return false;
-          if (hasNumber != other.hasNumber || (hasNumber && !number_.Equals(other.number_))) return false;
-          if (hasType != other.hasType || (hasType && !type_.Equals(other.type_))) return false;
-          return true;
-        }
-        
-        public override void PrintTo(global::System.IO.TextWriter writer) {
-          PrintField("number", hasNumber, number_, writer);
-          PrintField("type", hasType, type_, writer);
-        }
-        #endregion
-        
-        public static PhoneNumber ParseFrom(pb::ByteString data) {
-          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-        }
-        public static PhoneNumber ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-        }
-        public static PhoneNumber ParseFrom(byte[] data) {
-          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-        }
-        public static PhoneNumber ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-        }
-        public static PhoneNumber ParseFrom(global::System.IO.Stream input) {
-          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-        }
-        public static PhoneNumber ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-        }
-        public static PhoneNumber ParseDelimitedFrom(global::System.IO.Stream input) {
-          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-        }
-        public static PhoneNumber ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-        }
-        public static PhoneNumber ParseFrom(pb::CodedInputStream input) {
-          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-        }
-        public static PhoneNumber ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-        }
-        public static Builder CreateBuilder() { return new Builder(); }
-        public override Builder ToBuilder() { return CreateBuilder(this); }
-        public override Builder CreateBuilderForType() { return new Builder(); }
-        public static Builder CreateBuilder(PhoneNumber prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
-        }
-        
-        public sealed partial class Builder : pb::GeneratedBuilderLite<PhoneNumber, Builder> {
-          protected override Builder ThisBuilder {
-            get { return this; }
-          }
-          public Builder() {}
-          
-          PhoneNumber result = new PhoneNumber();
-          
-          protected override PhoneNumber MessageBeingBuilt {
-            get { return result; }
-          }
-          
-          public override Builder Clear() {
-            result = new PhoneNumber();
-            return this;
-          }
-          
-          public override Builder Clone() {
-            return new Builder().MergeFrom(result);
-          }
-          
-          public override PhoneNumber DefaultInstanceForType {
-            get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.DefaultInstance; }
-          }
-          
-          public override PhoneNumber BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-            }
-            PhoneNumber returnMe = result;
-            result = null;
-            return returnMe;
-          }
-          
-          public override Builder MergeFrom(pb::IMessageLite other) {
-            if (other is PhoneNumber) {
-              return MergeFrom((PhoneNumber) other);
-            } else {
-              base.MergeFrom(other);
-              return this;
-            }
-          }
-          
-          public override Builder MergeFrom(PhoneNumber other) {
-            if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.DefaultInstance) return this;
-            if (other.HasNumber) {
-              Number = other.Number;
-            }
-            if (other.HasType) {
-              Type = other.Type;
-            }
-            return this;
-          }
-          
-          public override Builder MergeFrom(pb::CodedInputStream input) {
-            return MergeFrom(input, pb::ExtensionRegistry.Empty);
-          }
-          
-          public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            while (true) {
-              uint tag = input.ReadTag();
-              switch (tag) {
-                case 0: {
-                  return this;
-                }
-                default: {
-                  if (pb::WireFormat.IsEndGroupTag(tag)) {
-                    return this;
-                  }
-                  ParseUnknownField(input, extensionRegistry, tag);
-                  break;
-                }
-                case 10: {
-                  Number = input.ReadString();
-                  break;
-                }
-                case 16: {
-                  int rawValue = input.ReadEnum();
-                  if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType), rawValue)) {
-                  } else {
-                    Type = (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType) rawValue;
-                  }
-                  break;
-                }
-              }
-            }
-          }
-          
-          
-          public bool HasNumber {
-            get { return result.HasNumber; }
-          }
-          public string Number {
-            get { return result.Number; }
-            set { SetNumber(value); }
-          }
-          public Builder SetNumber(string value) {
-            pb::ThrowHelper.ThrowIfNull(value, "value");
-            result.hasNumber = true;
-            result.number_ = value;
-            return this;
-          }
-          public Builder ClearNumber() {
-            result.hasNumber = false;
-            result.number_ = "";
-            return this;
-          }
-          
-          public bool HasType {
-           get { return result.HasType; }
-          }
-          public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType Type {
-            get { return result.Type; }
-            set { SetType(value); }
-          }
-          public Builder SetType(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType value) {
-            result.hasType = true;
-            result.type_ = value;
-            return this;
-          }
-          public Builder ClearType() {
-            result.hasType = false;
-            result.type_ = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType.HOME;
-            return this;
-          }
-        }
-        static PhoneNumber() {
-          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
-        }
-      }
-      
-      public sealed partial class Addresses : pb::GeneratedMessageLite<Addresses, Addresses.Builder> {
-        private static readonly Addresses defaultInstance = new Builder().BuildPartial();
-        public static Addresses DefaultInstance {
-          get { return defaultInstance; }
-        }
-        
-        public override Addresses DefaultInstanceForType {
-          get { return defaultInstance; }
-        }
-        
-        protected override Addresses ThisMessage {
-          get { return this; }
-        }
-        
-        public const int AddressFieldNumber = 1;
-        private bool hasAddress;
-        private string address_ = "";
-        public bool HasAddress {
-          get { return hasAddress; }
-        }
-        public string Address {
-          get { return address_; }
-        }
-        
-        public const int Address2FieldNumber = 2;
-        private bool hasAddress2;
-        private string address2_ = "";
-        public bool HasAddress2 {
-          get { return hasAddress2; }
-        }
-        public string Address2 {
-          get { return address2_; }
-        }
-        
-        public const int CityFieldNumber = 3;
-        private bool hasCity;
-        private string city_ = "";
-        public bool HasCity {
-          get { return hasCity; }
-        }
-        public string City {
-          get { return city_; }
-        }
-        
-        public const int StateFieldNumber = 4;
-        private bool hasState;
-        private string state_ = "";
-        public bool HasState {
-          get { return hasState; }
-        }
-        public string State {
-          get { return state_; }
-        }
-        
-        public const int ZipFieldNumber = 5;
-        private bool hasZip;
-        private uint zip_ = 0;
-        public bool HasZip {
-          get { return hasZip; }
-        }
-        [global::System.CLSCompliant(false)]
-        public uint Zip {
-          get { return zip_; }
-        }
-        
-        public override bool IsInitialized {
-          get {
-            if (!hasAddress) return false;
-            if (!hasCity) return false;
-            if (!hasState) return false;
-            if (!hasZip) return false;
-            return true;
-          }
-        }
-        
-        public override void WriteTo(pb::CodedOutputStream output) {
-          int size = SerializedSize;
-          if (HasAddress) {
-            output.WriteString(1, Address);
-          }
-          if (HasAddress2) {
-            output.WriteString(2, Address2);
-          }
-          if (HasCity) {
-            output.WriteString(3, City);
-          }
-          if (HasState) {
-            output.WriteString(4, State);
-          }
-          if (HasZip) {
-            output.WriteFixed32(5, Zip);
-          }
-        }
-        
-        private int memoizedSerializedSize = -1;
-        public override int SerializedSize {
-          get {
-            int size = memoizedSerializedSize;
-            if (size != -1) return size;
-            
-            size = 0;
-            if (HasAddress) {
-              size += pb::CodedOutputStream.ComputeStringSize(1, Address);
-            }
-            if (HasAddress2) {
-              size += pb::CodedOutputStream.ComputeStringSize(2, Address2);
-            }
-            if (HasCity) {
-              size += pb::CodedOutputStream.ComputeStringSize(3, City);
-            }
-            if (HasState) {
-              size += pb::CodedOutputStream.ComputeStringSize(4, State);
-            }
-            if (HasZip) {
-              size += pb::CodedOutputStream.ComputeFixed32Size(5, Zip);
-            }
-            memoizedSerializedSize = size;
-            return size;
-          }
-        }
-        
-        #region Lite runtime methods
-        public override int GetHashCode() {
-          int hash = GetType().GetHashCode();
-          if (hasAddress) hash ^= address_.GetHashCode();
-          if (hasAddress2) hash ^= address2_.GetHashCode();
-          if (hasCity) hash ^= city_.GetHashCode();
-          if (hasState) hash ^= state_.GetHashCode();
-          if (hasZip) hash ^= zip_.GetHashCode();
-          return hash;
-        }
-        
-        public override bool Equals(object obj) {
-          Addresses other = obj as Addresses;
-          if (other == null) return false;
-          if (hasAddress != other.hasAddress || (hasAddress && !address_.Equals(other.address_))) return false;
-          if (hasAddress2 != other.hasAddress2 || (hasAddress2 && !address2_.Equals(other.address2_))) return false;
-          if (hasCity != other.hasCity || (hasCity && !city_.Equals(other.city_))) return false;
-          if (hasState != other.hasState || (hasState && !state_.Equals(other.state_))) return false;
-          if (hasZip != other.hasZip || (hasZip && !zip_.Equals(other.zip_))) return false;
-          return true;
-        }
-        
-        public override void PrintTo(global::System.IO.TextWriter writer) {
-          PrintField("address", hasAddress, address_, writer);
-          PrintField("address2", hasAddress2, address2_, writer);
-          PrintField("city", hasCity, city_, writer);
-          PrintField("state", hasState, state_, writer);
-          PrintField("zip", hasZip, zip_, writer);
-        }
-        #endregion
-        
-        public static Addresses ParseFrom(pb::ByteString data) {
-          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-        }
-        public static Addresses ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-        }
-        public static Addresses ParseFrom(byte[] data) {
-          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-        }
-        public static Addresses ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-        }
-        public static Addresses ParseFrom(global::System.IO.Stream input) {
-          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-        }
-        public static Addresses ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-        }
-        public static Addresses ParseDelimitedFrom(global::System.IO.Stream input) {
-          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-        }
-        public static Addresses ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-        }
-        public static Addresses ParseFrom(pb::CodedInputStream input) {
-          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-        }
-        public static Addresses ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-        }
-        public static Builder CreateBuilder() { return new Builder(); }
-        public override Builder ToBuilder() { return CreateBuilder(this); }
-        public override Builder CreateBuilderForType() { return new Builder(); }
-        public static Builder CreateBuilder(Addresses prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
-        }
-        
-        public sealed partial class Builder : pb::GeneratedBuilderLite<Addresses, Builder> {
-          protected override Builder ThisBuilder {
-            get { return this; }
-          }
-          public Builder() {}
-          
-          Addresses result = new Addresses();
-          
-          protected override Addresses MessageBeingBuilt {
-            get { return result; }
-          }
-          
-          public override Builder Clear() {
-            result = new Addresses();
-            return this;
-          }
-          
-          public override Builder Clone() {
-            return new Builder().MergeFrom(result);
-          }
-          
-          public override Addresses DefaultInstanceForType {
-            get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.DefaultInstance; }
-          }
-          
-          public override Addresses BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-            }
-            Addresses returnMe = result;
-            result = null;
-            return returnMe;
-          }
-          
-          public override Builder MergeFrom(pb::IMessageLite other) {
-            if (other is Addresses) {
-              return MergeFrom((Addresses) other);
-            } else {
-              base.MergeFrom(other);
-              return this;
-            }
-          }
-          
-          public override Builder MergeFrom(Addresses other) {
-            if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.DefaultInstance) return this;
-            if (other.HasAddress) {
-              Address = other.Address;
-            }
-            if (other.HasAddress2) {
-              Address2 = other.Address2;
-            }
-            if (other.HasCity) {
-              City = other.City;
-            }
-            if (other.HasState) {
-              State = other.State;
-            }
-            if (other.HasZip) {
-              Zip = other.Zip;
-            }
-            return this;
-          }
-          
-          public override Builder MergeFrom(pb::CodedInputStream input) {
-            return MergeFrom(input, pb::ExtensionRegistry.Empty);
-          }
-          
-          public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            while (true) {
-              uint tag = input.ReadTag();
-              switch (tag) {
-                case 0: {
-                  return this;
-                }
-                default: {
-                  if (pb::WireFormat.IsEndGroupTag(tag)) {
-                    return this;
-                  }
-                  ParseUnknownField(input, extensionRegistry, tag);
-                  break;
-                }
-                case 10: {
-                  Address = input.ReadString();
-                  break;
-                }
-                case 18: {
-                  Address2 = input.ReadString();
-                  break;
-                }
-                case 26: {
-                  City = input.ReadString();
-                  break;
-                }
-                case 34: {
-                  State = input.ReadString();
-                  break;
-                }
-                case 45: {
-                  Zip = input.ReadFixed32();
-                  break;
-                }
-              }
-            }
-          }
-          
-          
-          public bool HasAddress {
-            get { return result.HasAddress; }
-          }
-          public string Address {
-            get { return result.Address; }
-            set { SetAddress(value); }
-          }
-          public Builder SetAddress(string value) {
-            pb::ThrowHelper.ThrowIfNull(value, "value");
-            result.hasAddress = true;
-            result.address_ = value;
-            return this;
-          }
-          public Builder ClearAddress() {
-            result.hasAddress = false;
-            result.address_ = "";
-            return this;
-          }
-          
-          public bool HasAddress2 {
-            get { return result.HasAddress2; }
-          }
-          public string Address2 {
-            get { return result.Address2; }
-            set { SetAddress2(value); }
-          }
-          public Builder SetAddress2(string value) {
-            pb::ThrowHelper.ThrowIfNull(value, "value");
-            result.hasAddress2 = true;
-            result.address2_ = value;
-            return this;
-          }
-          public Builder ClearAddress2() {
-            result.hasAddress2 = false;
-            result.address2_ = "";
-            return this;
-          }
-          
-          public bool HasCity {
-            get { return result.HasCity; }
-          }
-          public string City {
-            get { return result.City; }
-            set { SetCity(value); }
-          }
-          public Builder SetCity(string value) {
-            pb::ThrowHelper.ThrowIfNull(value, "value");
-            result.hasCity = true;
-            result.city_ = value;
-            return this;
-          }
-          public Builder ClearCity() {
-            result.hasCity = false;
-            result.city_ = "";
-            return this;
-          }
-          
-          public bool HasState {
-            get { return result.HasState; }
-          }
-          public string State {
-            get { return result.State; }
-            set { SetState(value); }
-          }
-          public Builder SetState(string value) {
-            pb::ThrowHelper.ThrowIfNull(value, "value");
-            result.hasState = true;
-            result.state_ = value;
-            return this;
-          }
-          public Builder ClearState() {
-            result.hasState = false;
-            result.state_ = "";
-            return this;
-          }
-          
-          public bool HasZip {
-            get { return result.HasZip; }
-          }
-          [global::System.CLSCompliant(false)]
-          public uint Zip {
-            get { return result.Zip; }
-            set { SetZip(value); }
-          }
-          [global::System.CLSCompliant(false)]
-          public Builder SetZip(uint value) {
-            result.hasZip = true;
-            result.zip_ = value;
-            return this;
-          }
-          public Builder ClearZip() {
-            result.hasZip = false;
-            result.zip_ = 0;
-            return this;
-          }
-        }
-        static Addresses() {
-          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
-        }
-      }
-      
-    }
-    #endregion
-    
-    public const int NameFieldNumber = 1;
-    private bool hasName;
-    private string name_ = "";
-    public bool HasName {
-      get { return hasName; }
-    }
-    public string Name {
-      get { return name_; }
-    }
-    
-    public const int IdFieldNumber = 2;
-    private bool hasId;
-    private int id_ = 0;
-    public bool HasId {
-      get { return hasId; }
-    }
-    public int Id {
-      get { return id_; }
-    }
-    
-    public const int EmailFieldNumber = 3;
-    private bool hasEmail;
-    private string email_ = "";
-    public bool HasEmail {
-      get { return hasEmail; }
-    }
-    public string Email {
-      get { return email_; }
-    }
-    
-    public const int CodesFieldNumber = 10;
-    private int codesMemoizedSerializedSize;
-    private pbc::PopsicleList<int> codes_ = new pbc::PopsicleList<int>();
-    public scg::IList<int> CodesList {
-      get { return pbc::Lists.AsReadOnly(codes_); }
-    }
-    public int CodesCount {
-      get { return codes_.Count; }
-    }
-    public int GetCodes(int index) {
-      return codes_[index];
-    }
-    
-    public const int PhoneFieldNumber = 4;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> phone_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber>();
-    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> PhoneList {
-      get { return phone_; }
-    }
-    public int PhoneCount {
-      get { return phone_.Count; }
-    }
-    public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber GetPhone(int index) {
-      return phone_[index];
-    }
-    
-    public const int AddressesFieldNumber = 5;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> addresses_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses>();
-    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> AddressesList {
-      get { return addresses_; }
-    }
-    public int AddressesCount {
-      get { return addresses_.Count; }
-    }
-    public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses GetAddresses(int index) {
-      return addresses_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        if (!hasName) return false;
-        if (!hasId) return false;
-        foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber element in PhoneList) {
-          if (!element.IsInitialized) return false;
-        }
-        if (!ExtensionsAreInitialized) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      pb::ExtendableMessageLite<TestInteropPersonLite, TestInteropPersonLite.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
-      if (HasName) {
-        output.WriteString(1, Name);
-      }
-      if (HasId) {
-        output.WriteInt32(2, Id);
-      }
-      if (HasEmail) {
-        output.WriteString(3, Email);
-      }
-      foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber element in PhoneList) {
-        output.WriteMessage(4, element);
-      }
-      foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses element in AddressesList) {
-        output.WriteGroup(5, element);
-      }
-      if (codes_.Count > 0) {
-        output.WriteRawVarint32(82);
-        output.WriteRawVarint32((uint) codesMemoizedSerializedSize);
-        foreach (int element in codes_) {
-          output.WriteInt32NoTag(element);
-        }
-      }
-      extensionWriter.WriteUntil(200, output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasName) {
-          size += pb::CodedOutputStream.ComputeStringSize(1, Name);
-        }
-        if (HasId) {
-          size += pb::CodedOutputStream.ComputeInt32Size(2, Id);
-        }
-        if (HasEmail) {
-          size += pb::CodedOutputStream.ComputeStringSize(3, Email);
-        }
-        {
-          int dataSize = 0;
-          foreach (int element in CodesList) {
-            dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
-          }
-          size += dataSize;
-          if (codes_.Count != 0) {
-            size += 1 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
-          }
-          codesMemoizedSerializedSize = dataSize;
-        }
-        foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber element in PhoneList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(4, element);
-        }
-        foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses element in AddressesList) {
-          size += pb::CodedOutputStream.ComputeGroupSize(5, element);
-        }
-        size += ExtensionsSerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    #region Lite runtime methods
-    public override int GetHashCode() {
-      int hash = GetType().GetHashCode();
-      if (hasName) hash ^= name_.GetHashCode();
-      if (hasId) hash ^= id_.GetHashCode();
-      if (hasEmail) hash ^= email_.GetHashCode();
-      foreach(int i in codes_)
-        hash ^= i.GetHashCode();
-      foreach(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber i in phone_)
-        hash ^= i.GetHashCode();
-      foreach(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses i in addresses_)
-        hash ^= i.GetHashCode();
-      hash ^= base.GetHashCode();
-      return hash;
-    }
-    
-    public override bool Equals(object obj) {
-      TestInteropPersonLite other = obj as TestInteropPersonLite;
-      if (other == null) return false;
-      if (hasName != other.hasName || (hasName && !name_.Equals(other.name_))) return false;
-      if (hasId != other.hasId || (hasId && !id_.Equals(other.id_))) return false;
-      if (hasEmail != other.hasEmail || (hasEmail && !email_.Equals(other.email_))) return false;
-      if(codes_.Count != other.codes_.Count) return false;
-      for(int ix=0; ix < codes_.Count; ix++)
-        if(!codes_[ix].Equals(other.codes_[ix])) return false;
-      if(phone_.Count != other.phone_.Count) return false;
-      for(int ix=0; ix < phone_.Count; ix++)
-        if(!phone_[ix].Equals(other.phone_[ix])) return false;
-      if(addresses_.Count != other.addresses_.Count) return false;
-      for(int ix=0; ix < addresses_.Count; ix++)
-        if(!addresses_[ix].Equals(other.addresses_[ix])) return false;
-      if (!base.Equals(other)) return false;
-      return true;
-    }
-    
-    public override void PrintTo(global::System.IO.TextWriter writer) {
-      PrintField("name", hasName, name_, writer);
-      PrintField("id", hasId, id_, writer);
-      PrintField("email", hasEmail, email_, writer);
-      PrintField("phone", phone_, writer);
-      PrintField("Addresses", addresses_, writer);
-      PrintField("codes", codes_, writer);
-      base.PrintTo(writer);
-    }
-    #endregion
-    
-    public static TestInteropPersonLite ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static TestInteropPersonLite ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(TestInteropPersonLite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::ExtendableBuilderLite<TestInteropPersonLite, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      TestInteropPersonLite result = new TestInteropPersonLite();
-      
-      protected override TestInteropPersonLite MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new TestInteropPersonLite();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override TestInteropPersonLite DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.DefaultInstance; }
-      }
-      
-      public override TestInteropPersonLite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.codes_.MakeReadOnly();
-        result.phone_.MakeReadOnly();
-        result.addresses_.MakeReadOnly();
-        TestInteropPersonLite returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessageLite other) {
-        if (other is TestInteropPersonLite) {
-          return MergeFrom((TestInteropPersonLite) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(TestInteropPersonLite other) {
-        if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.DefaultInstance) return this;
-        if (other.HasName) {
-          Name = other.Name;
-        }
-        if (other.HasId) {
-          Id = other.Id;
-        }
-        if (other.HasEmail) {
-          Email = other.Email;
-        }
-        if (other.codes_.Count != 0) {
-          base.AddRange(other.codes_, result.codes_);
-        }
-        if (other.phone_.Count != 0) {
-          base.AddRange(other.phone_, result.phone_);
-        }
-        if (other.addresses_.Count != 0) {
-          base.AddRange(other.addresses_, result.addresses_);
-        }
-          this.MergeExtensionFields(other);
-        return this;
-      }
-      
-      public override Builder MergeFrom(pb::CodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-      
-      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                return this;
-              }
-              ParseUnknownField(input, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Name = input.ReadString();
-              break;
-            }
-            case 16: {
-              Id = input.ReadInt32();
-              break;
-            }
-            case 26: {
-              Email = input.ReadString();
-              break;
-            }
-            case 34: {
-              global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddPhone(subBuilder.BuildPartial());
-              break;
-            }
-            case 43: {
-              global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.CreateBuilder();
-              input.ReadGroup(5, subBuilder, extensionRegistry);
-              AddAddresses(subBuilder.BuildPartial());
-              break;
-            }
-            case 82: {
-              int length = input.ReadInt32();
-              int limit = input.PushLimit(length);
-              while (!input.ReachedLimit) {
-                AddCodes(input.ReadInt32());
-              }
-              input.PopLimit(limit);
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasName {
-        get { return result.HasName; }
-      }
-      public string Name {
-        get { return result.Name; }
-        set { SetName(value); }
-      }
-      public Builder SetName(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasName = true;
-        result.name_ = value;
-        return this;
-      }
-      public Builder ClearName() {
-        result.hasName = false;
-        result.name_ = "";
-        return this;
-      }
-      
-      public bool HasId {
-        get { return result.HasId; }
-      }
-      public int Id {
-        get { return result.Id; }
-        set { SetId(value); }
-      }
-      public Builder SetId(int value) {
-        result.hasId = true;
-        result.id_ = value;
-        return this;
-      }
-      public Builder ClearId() {
-        result.hasId = false;
-        result.id_ = 0;
-        return this;
-      }
-      
-      public bool HasEmail {
-        get { return result.HasEmail; }
-      }
-      public string Email {
-        get { return result.Email; }
-        set { SetEmail(value); }
-      }
-      public Builder SetEmail(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasEmail = true;
-        result.email_ = value;
-        return this;
-      }
-      public Builder ClearEmail() {
-        result.hasEmail = false;
-        result.email_ = "";
-        return this;
-      }
-      
-      public pbc::IPopsicleList<int> CodesList {
-        get { return result.codes_; }
-      }
-      public int CodesCount {
-        get { return result.CodesCount; }
-      }
-      public int GetCodes(int index) {
-        return result.GetCodes(index);
-      }
-      public Builder SetCodes(int index, int value) {
-        result.codes_[index] = value;
-        return this;
-      }
-      public Builder AddCodes(int value) {
-        result.codes_.Add(value);
-        return this;
-      }
-      public Builder AddRangeCodes(scg::IEnumerable<int> values) {
-        base.AddRange(values, result.codes_);
-        return this;
-      }
-      public Builder ClearCodes() {
-        result.codes_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> PhoneList {
-        get { return result.phone_; }
-      }
-      public int PhoneCount {
-        get { return result.PhoneCount; }
-      }
-      public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber GetPhone(int index) {
-        return result.GetPhone(index);
-      }
-      public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.phone_[index] = value;
-        return this;
-      }
-      public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.phone_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.phone_.Add(value);
-        return this;
-      }
-      public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.phone_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangePhone(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> values) {
-        base.AddRange(values, result.phone_);
-        return this;
-      }
-      public Builder ClearPhone() {
-        result.phone_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> AddressesList {
-        get { return result.addresses_; }
-      }
-      public int AddressesCount {
-        get { return result.AddressesCount; }
-      }
-      public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses GetAddresses(int index) {
-        return result.GetAddresses(index);
-      }
-      public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.addresses_[index] = value;
-        return this;
-      }
-      public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.addresses_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.addresses_.Add(value);
-        return this;
-      }
-      public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.addresses_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeAddresses(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> values) {
-        base.AddRange(values, result.addresses_);
-        return this;
-      }
-      public Builder ClearAddresses() {
-        result.addresses_.Clear();
-        return this;
-      }
-    }
-    static TestInteropPersonLite() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class TestInteropEmployeeIdLite : pb::GeneratedMessageLite<TestInteropEmployeeIdLite, TestInteropEmployeeIdLite.Builder> {
-    private static readonly TestInteropEmployeeIdLite defaultInstance = new Builder().BuildPartial();
-    public static TestInteropEmployeeIdLite DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override TestInteropEmployeeIdLite DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override TestInteropEmployeeIdLite ThisMessage {
-      get { return this; }
-    }
-    
-    public const int NumberFieldNumber = 1;
-    private bool hasNumber;
-    private string number_ = "";
-    public bool HasNumber {
-      get { return hasNumber; }
-    }
-    public string Number {
-      get { return number_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        if (!hasNumber) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasNumber) {
-        output.WriteString(1, Number);
-      }
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasNumber) {
-          size += pb::CodedOutputStream.ComputeStringSize(1, Number);
-        }
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    #region Lite runtime methods
-    public override int GetHashCode() {
-      int hash = GetType().GetHashCode();
-      if (hasNumber) hash ^= number_.GetHashCode();
-      return hash;
-    }
-    
-    public override bool Equals(object obj) {
-      TestInteropEmployeeIdLite other = obj as TestInteropEmployeeIdLite;
-      if (other == null) return false;
-      if (hasNumber != other.hasNumber || (hasNumber && !number_.Equals(other.number_))) return false;
-      return true;
-    }
-    
-    public override void PrintTo(global::System.IO.TextWriter writer) {
-      PrintField("number", hasNumber, number_, writer);
-    }
-    #endregion
-    
-    public static TestInteropEmployeeIdLite ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static TestInteropEmployeeIdLite ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(TestInteropEmployeeIdLite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilderLite<TestInteropEmployeeIdLite, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      TestInteropEmployeeIdLite result = new TestInteropEmployeeIdLite();
-      
-      protected override TestInteropEmployeeIdLite MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new TestInteropEmployeeIdLite();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override TestInteropEmployeeIdLite DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite.DefaultInstance; }
-      }
-      
-      public override TestInteropEmployeeIdLite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        TestInteropEmployeeIdLite returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessageLite other) {
-        if (other is TestInteropEmployeeIdLite) {
-          return MergeFrom((TestInteropEmployeeIdLite) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(TestInteropEmployeeIdLite other) {
-        if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite.DefaultInstance) return this;
-        if (other.HasNumber) {
-          Number = other.Number;
-        }
-        return this;
-      }
-      
-      public override Builder MergeFrom(pb::CodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-      
-      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                return this;
-              }
-              ParseUnknownField(input, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Number = input.ReadString();
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasNumber {
-        get { return result.HasNumber; }
-      }
-      public string Number {
-        get { return result.Number; }
-        set { SetNumber(value); }
-      }
-      public Builder SetNumber(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasNumber = true;
-        result.number_ = value;
-        return this;
-      }
-      public Builder ClearNumber() {
-        result.hasNumber = false;
-        result.number_ = "";
-        return this;
-      }
-    }
-    static TestInteropEmployeeIdLite() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
-    }
-  }
-  
-  #endregion
-  
-}
+// Generated by ProtoGen, Version=0.9.0.0, Culture=neutral, PublicKeyToken=8fd7408b07f8d2cd.  DO NOT EDIT!
+
+using pb = global::Google.ProtocolBuffers;
+using pbc = global::Google.ProtocolBuffers.Collections;
+using pbd = global::Google.ProtocolBuffers.Descriptors;
+using scg = global::System.Collections.Generic;
+namespace Google.ProtocolBuffers.TestProtos {
+  
+  public static partial class UnitTestExtrasLiteProtoFile {
+  
+    #region Extension registration
+    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
+      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.EmployeeIdLite);
+    }
+    #endregion
+    #region Extensions
+    public const int EmployeeIdLiteFieldNumber = 126;
+    public static pb::GeneratedExtensionLite<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite, global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite> EmployeeIdLite;
+    #endregion
+    
+    #region Static variables
+    #endregion
+    #region Extensions
+    internal static readonly object Descriptor;
+    static UnitTestExtrasLiteProtoFile() {
+      Descriptor = null;
+      global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.EmployeeIdLite = 
+        new pb::GeneratedExtensionLite<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite, global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite>(
+          "protobuf_unittest_extra.employee_id_lite",
+          global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.DefaultInstance,
+          null,
+          global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite.DefaultInstance,
+          null,
+          global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.EmployeeIdLiteFieldNumber,
+          pbd::FieldType.Message);
+    }
+    #endregion
+    
+  }
+  #region Enums
+  public enum ExtraEnum {
+    DEFAULT = 10,
+    EXLITE_FOO = 7,
+    EXLITE_BAR = 8,
+    EXLITE_BAZ = 9,
+  }
+  
+  #endregion
+  
+  #region Messages
+  public sealed partial class TestRequiredLite : pb::GeneratedMessageLite<TestRequiredLite, TestRequiredLite.Builder> {
+    private static readonly TestRequiredLite defaultInstance = new Builder().BuildPartial();
+    public static TestRequiredLite DefaultInstance {
+      get { return defaultInstance; }
+    }
+    
+    public override TestRequiredLite DefaultInstanceForType {
+      get { return defaultInstance; }
+    }
+    
+    protected override TestRequiredLite ThisMessage {
+      get { return this; }
+    }
+    
+    public const int DFieldNumber = 1;
+    private bool hasD;
+    private int d_ = 0;
+    public bool HasD {
+      get { return hasD; }
+    }
+    public int D {
+      get { return d_; }
+    }
+    
+    public const int EnFieldNumber = 2;
+    private bool hasEn;
+    private global::Google.ProtocolBuffers.TestProtos.ExtraEnum en_ = global::Google.ProtocolBuffers.TestProtos.ExtraEnum.DEFAULT;
+    public bool HasEn {
+      get { return hasEn; }
+    }
+    public global::Google.ProtocolBuffers.TestProtos.ExtraEnum En {
+      get { return en_; }
+    }
+    
+    public override bool IsInitialized {
+      get {
+        if (!hasD) return false;
+        if (!hasEn) return false;
+        return true;
+      }
+    }
+    
+    public override void WriteTo(pb::CodedOutputStream output) {
+      int size = SerializedSize;
+      if (HasD) {
+        output.WriteInt32(1, D);
+      }
+      if (HasEn) {
+        output.WriteEnum(2, (int) En);
+      }
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        
+        size = 0;
+        if (HasD) {
+          size += pb::CodedOutputStream.ComputeInt32Size(1, D);
+        }
+        if (HasEn) {
+          size += pb::CodedOutputStream.ComputeEnumSize(2, (int) En);
+        }
+        memoizedSerializedSize = size;
+        return size;
+      }
+    }
+    
+    #region Lite runtime methods
+    public override int GetHashCode() {
+      int hash = GetType().GetHashCode();
+      if (hasD) hash ^= d_.GetHashCode();
+      if (hasEn) hash ^= en_.GetHashCode();
+      return hash;
+    }
+    
+    public override bool Equals(object obj) {
+      TestRequiredLite other = obj as TestRequiredLite;
+      if (other == null) return false;
+      if (hasD != other.hasD || (hasD && !d_.Equals(other.d_))) return false;
+      if (hasEn != other.hasEn || (hasEn && !en_.Equals(other.en_))) return false;
+      return true;
+    }
+    
+    public override void PrintTo(global::System.IO.TextWriter writer) {
+      PrintField("d", hasD, d_, writer);
+      PrintField("en", hasEn, en_, writer);
+    }
+    #endregion
+    
+    public static TestRequiredLite ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static TestRequiredLite ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static TestRequiredLite ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static TestRequiredLite ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static TestRequiredLite ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static TestRequiredLite ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static TestRequiredLite ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static TestRequiredLite ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static TestRequiredLite ParseFrom(pb::CodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static TestRequiredLite ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(TestRequiredLite prototype) {
+      return (Builder) new Builder().MergeFrom(prototype);
+    }
+    
+    public sealed partial class Builder : pb::GeneratedBuilderLite<TestRequiredLite, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {}
+      
+      TestRequiredLite result = new TestRequiredLite();
+      
+      protected override TestRequiredLite MessageBeingBuilt {
+        get { return result; }
+      }
+      
+      public override Builder Clear() {
+        result = new TestRequiredLite();
+        return this;
+      }
+      
+      public override Builder Clone() {
+        return new Builder().MergeFrom(result);
+      }
+      
+      public override TestRequiredLite DefaultInstanceForType {
+        get { return global::Google.ProtocolBuffers.TestProtos.TestRequiredLite.DefaultInstance; }
+      }
+      
+      public override TestRequiredLite BuildPartial() {
+        if (result == null) {
+          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        }
+        TestRequiredLite returnMe = result;
+        result = null;
+        return returnMe;
+      }
+      
+      public override Builder MergeFrom(pb::IMessageLite other) {
+        if (other is TestRequiredLite) {
+          return MergeFrom((TestRequiredLite) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+      
+      public override Builder MergeFrom(TestRequiredLite other) {
+        if (other == global::Google.ProtocolBuffers.TestProtos.TestRequiredLite.DefaultInstance) return this;
+        if (other.HasD) {
+          D = other.D;
+        }
+        if (other.HasEn) {
+          En = other.En;
+        }
+        return this;
+      }
+      
+      public override Builder MergeFrom(pb::CodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+      
+      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        while (true) {
+          uint tag = input.ReadTag();
+          switch (tag) {
+            case 0: {
+              return this;
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                return this;
+              }
+              ParseUnknownField(input, extensionRegistry, tag);
+              break;
+            }
+            case 8: {
+              D = input.ReadInt32();
+              break;
+            }
+            case 16: {
+              int rawValue = input.ReadEnum();
+              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ExtraEnum), rawValue)) {
+              } else {
+                En = (global::Google.ProtocolBuffers.TestProtos.ExtraEnum) rawValue;
+              }
+              break;
+            }
+          }
+        }
+      }
+      
+      
+      public bool HasD {
+        get { return result.HasD; }
+      }
+      public int D {
+        get { return result.D; }
+        set { SetD(value); }
+      }
+      public Builder SetD(int value) {
+        result.hasD = true;
+        result.d_ = value;
+        return this;
+      }
+      public Builder ClearD() {
+        result.hasD = false;
+        result.d_ = 0;
+        return this;
+      }
+      
+      public bool HasEn {
+       get { return result.HasEn; }
+      }
+      public global::Google.ProtocolBuffers.TestProtos.ExtraEnum En {
+        get { return result.En; }
+        set { SetEn(value); }
+      }
+      public Builder SetEn(global::Google.ProtocolBuffers.TestProtos.ExtraEnum value) {
+        result.hasEn = true;
+        result.en_ = value;
+        return this;
+      }
+      public Builder ClearEn() {
+        result.hasEn = false;
+        result.en_ = global::Google.ProtocolBuffers.TestProtos.ExtraEnum.DEFAULT;
+        return this;
+      }
+    }
+    static TestRequiredLite() {
+      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
+    }
+  }
+  
+  public sealed partial class TestInteropPersonLite : pb::ExtendableMessageLite<TestInteropPersonLite, TestInteropPersonLite.Builder> {
+    private static readonly TestInteropPersonLite defaultInstance = new Builder().BuildPartial();
+    public static TestInteropPersonLite DefaultInstance {
+      get { return defaultInstance; }
+    }
+    
+    public override TestInteropPersonLite DefaultInstanceForType {
+      get { return defaultInstance; }
+    }
+    
+    protected override TestInteropPersonLite ThisMessage {
+      get { return this; }
+    }
+    
+    #region Nested types
+    public static class Types {
+      public enum PhoneType {
+        MOBILE = 0,
+        HOME = 1,
+        WORK = 2,
+      }
+      
+      public sealed partial class PhoneNumber : pb::GeneratedMessageLite<PhoneNumber, PhoneNumber.Builder> {
+        private static readonly PhoneNumber defaultInstance = new Builder().BuildPartial();
+        public static PhoneNumber DefaultInstance {
+          get { return defaultInstance; }
+        }
+        
+        public override PhoneNumber DefaultInstanceForType {
+          get { return defaultInstance; }
+        }
+        
+        protected override PhoneNumber ThisMessage {
+          get { return this; }
+        }
+        
+        public const int NumberFieldNumber = 1;
+        private bool hasNumber;
+        private string number_ = "";
+        public bool HasNumber {
+          get { return hasNumber; }
+        }
+        public string Number {
+          get { return number_; }
+        }
+        
+        public const int TypeFieldNumber = 2;
+        private bool hasType;
+        private global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType type_ = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType.HOME;
+        public bool HasType {
+          get { return hasType; }
+        }
+        public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType Type {
+          get { return type_; }
+        }
+        
+        public override bool IsInitialized {
+          get {
+            if (!hasNumber) return false;
+            return true;
+          }
+        }
+        
+        public override void WriteTo(pb::CodedOutputStream output) {
+          int size = SerializedSize;
+          if (HasNumber) {
+            output.WriteString(1, Number);
+          }
+          if (HasType) {
+            output.WriteEnum(2, (int) Type);
+          }
+        }
+        
+        private int memoizedSerializedSize = -1;
+        public override int SerializedSize {
+          get {
+            int size = memoizedSerializedSize;
+            if (size != -1) return size;
+            
+            size = 0;
+            if (HasNumber) {
+              size += pb::CodedOutputStream.ComputeStringSize(1, Number);
+            }
+            if (HasType) {
+              size += pb::CodedOutputStream.ComputeEnumSize(2, (int) Type);
+            }
+            memoizedSerializedSize = size;
+            return size;
+          }
+        }
+        
+        #region Lite runtime methods
+        public override int GetHashCode() {
+          int hash = GetType().GetHashCode();
+          if (hasNumber) hash ^= number_.GetHashCode();
+          if (hasType) hash ^= type_.GetHashCode();
+          return hash;
+        }
+        
+        public override bool Equals(object obj) {
+          PhoneNumber other = obj as PhoneNumber;
+          if (other == null) return false;
+          if (hasNumber != other.hasNumber || (hasNumber && !number_.Equals(other.number_))) return false;
+          if (hasType != other.hasType || (hasType && !type_.Equals(other.type_))) return false;
+          return true;
+        }
+        
+        public override void PrintTo(global::System.IO.TextWriter writer) {
+          PrintField("number", hasNumber, number_, writer);
+          PrintField("type", hasType, type_, writer);
+        }
+        #endregion
+        
+        public static PhoneNumber ParseFrom(pb::ByteString data) {
+          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+        public static PhoneNumber ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+        public static PhoneNumber ParseFrom(byte[] data) {
+          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+        public static PhoneNumber ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+        public static PhoneNumber ParseFrom(global::System.IO.Stream input) {
+          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+        public static PhoneNumber ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+        public static PhoneNumber ParseDelimitedFrom(global::System.IO.Stream input) {
+          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+        public static PhoneNumber ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+        public static PhoneNumber ParseFrom(pb::CodedInputStream input) {
+          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+        public static PhoneNumber ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+        public static Builder CreateBuilder() { return new Builder(); }
+        public override Builder ToBuilder() { return CreateBuilder(this); }
+        public override Builder CreateBuilderForType() { return new Builder(); }
+        public static Builder CreateBuilder(PhoneNumber prototype) {
+          return (Builder) new Builder().MergeFrom(prototype);
+        }
+        
+        public sealed partial class Builder : pb::GeneratedBuilderLite<PhoneNumber, Builder> {
+          protected override Builder ThisBuilder {
+            get { return this; }
+          }
+          public Builder() {}
+          
+          PhoneNumber result = new PhoneNumber();
+          
+          protected override PhoneNumber MessageBeingBuilt {
+            get { return result; }
+          }
+          
+          public override Builder Clear() {
+            result = new PhoneNumber();
+            return this;
+          }
+          
+          public override Builder Clone() {
+            return new Builder().MergeFrom(result);
+          }
+          
+          public override PhoneNumber DefaultInstanceForType {
+            get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.DefaultInstance; }
+          }
+          
+          public override PhoneNumber BuildPartial() {
+            if (result == null) {
+              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+            }
+            PhoneNumber returnMe = result;
+            result = null;
+            return returnMe;
+          }
+          
+          public override Builder MergeFrom(pb::IMessageLite other) {
+            if (other is PhoneNumber) {
+              return MergeFrom((PhoneNumber) other);
+            } else {
+              base.MergeFrom(other);
+              return this;
+            }
+          }
+          
+          public override Builder MergeFrom(PhoneNumber other) {
+            if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.DefaultInstance) return this;
+            if (other.HasNumber) {
+              Number = other.Number;
+            }
+            if (other.HasType) {
+              Type = other.Type;
+            }
+            return this;
+          }
+          
+          public override Builder MergeFrom(pb::CodedInputStream input) {
+            return MergeFrom(input, pb::ExtensionRegistry.Empty);
+          }
+          
+          public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+            while (true) {
+              uint tag = input.ReadTag();
+              switch (tag) {
+                case 0: {
+                  return this;
+                }
+                default: {
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    return this;
+                  }
+                  ParseUnknownField(input, extensionRegistry, tag);
+                  break;
+                }
+                case 10: {
+                  Number = input.ReadString();
+                  break;
+                }
+                case 16: {
+                  int rawValue = input.ReadEnum();
+                  if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType), rawValue)) {
+                  } else {
+                    Type = (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType) rawValue;
+                  }
+                  break;
+                }
+              }
+            }
+          }
+          
+          
+          public bool HasNumber {
+            get { return result.HasNumber; }
+          }
+          public string Number {
+            get { return result.Number; }
+            set { SetNumber(value); }
+          }
+          public Builder SetNumber(string value) {
+            pb::ThrowHelper.ThrowIfNull(value, "value");
+            result.hasNumber = true;
+            result.number_ = value;
+            return this;
+          }
+          public Builder ClearNumber() {
+            result.hasNumber = false;
+            result.number_ = "";
+            return this;
+          }
+          
+          public bool HasType {
+           get { return result.HasType; }
+          }
+          public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType Type {
+            get { return result.Type; }
+            set { SetType(value); }
+          }
+          public Builder SetType(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType value) {
+            result.hasType = true;
+            result.type_ = value;
+            return this;
+          }
+          public Builder ClearType() {
+            result.hasType = false;
+            result.type_ = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType.HOME;
+            return this;
+          }
+        }
+        static PhoneNumber() {
+          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
+        }
+      }
+      
+      public sealed partial class Addresses : pb::GeneratedMessageLite<Addresses, Addresses.Builder> {
+        private static readonly Addresses defaultInstance = new Builder().BuildPartial();
+        public static Addresses DefaultInstance {
+          get { return defaultInstance; }
+        }
+        
+        public override Addresses DefaultInstanceForType {
+          get { return defaultInstance; }
+        }
+        
+        protected override Addresses ThisMessage {
+          get { return this; }
+        }
+        
+        public const int AddressFieldNumber = 1;
+        private bool hasAddress;
+        private string address_ = "";
+        public bool HasAddress {
+          get { return hasAddress; }
+        }
+        public string Address {
+          get { return address_; }
+        }
+        
+        public const int Address2FieldNumber = 2;
+        private bool hasAddress2;
+        private string address2_ = "";
+        public bool HasAddress2 {
+          get { return hasAddress2; }
+        }
+        public string Address2 {
+          get { return address2_; }
+        }
+        
+        public const int CityFieldNumber = 3;
+        private bool hasCity;
+        private string city_ = "";
+        public bool HasCity {
+          get { return hasCity; }
+        }
+        public string City {
+          get { return city_; }
+        }
+        
+        public const int StateFieldNumber = 4;
+        private bool hasState;
+        private string state_ = "";
+        public bool HasState {
+          get { return hasState; }
+        }
+        public string State {
+          get { return state_; }
+        }
+        
+        public const int ZipFieldNumber = 5;
+        private bool hasZip;
+        private uint zip_ = 0;
+        public bool HasZip {
+          get { return hasZip; }
+        }
+        [global::System.CLSCompliant(false)]
+        public uint Zip {
+          get { return zip_; }
+        }
+        
+        public override bool IsInitialized {
+          get {
+            if (!hasAddress) return false;
+            if (!hasCity) return false;
+            if (!hasState) return false;
+            if (!hasZip) return false;
+            return true;
+          }
+        }
+        
+        public override void WriteTo(pb::CodedOutputStream output) {
+          int size = SerializedSize;
+          if (HasAddress) {
+            output.WriteString(1, Address);
+          }
+          if (HasAddress2) {
+            output.WriteString(2, Address2);
+          }
+          if (HasCity) {
+            output.WriteString(3, City);
+          }
+          if (HasState) {
+            output.WriteString(4, State);
+          }
+          if (HasZip) {
+            output.WriteFixed32(5, Zip);
+          }
+        }
+        
+        private int memoizedSerializedSize = -1;
+        public override int SerializedSize {
+          get {
+            int size = memoizedSerializedSize;
+            if (size != -1) return size;
+            
+            size = 0;
+            if (HasAddress) {
+              size += pb::CodedOutputStream.ComputeStringSize(1, Address);
+            }
+            if (HasAddress2) {
+              size += pb::CodedOutputStream.ComputeStringSize(2, Address2);
+            }
+            if (HasCity) {
+              size += pb::CodedOutputStream.ComputeStringSize(3, City);
+            }
+            if (HasState) {
+              size += pb::CodedOutputStream.ComputeStringSize(4, State);
+            }
+            if (HasZip) {
+              size += pb::CodedOutputStream.ComputeFixed32Size(5, Zip);
+            }
+            memoizedSerializedSize = size;
+            return size;
+          }
+        }
+        
+        #region Lite runtime methods
+        public override int GetHashCode() {
+          int hash = GetType().GetHashCode();
+          if (hasAddress) hash ^= address_.GetHashCode();
+          if (hasAddress2) hash ^= address2_.GetHashCode();
+          if (hasCity) hash ^= city_.GetHashCode();
+          if (hasState) hash ^= state_.GetHashCode();
+          if (hasZip) hash ^= zip_.GetHashCode();
+          return hash;
+        }
+        
+        public override bool Equals(object obj) {
+          Addresses other = obj as Addresses;
+          if (other == null) return false;
+          if (hasAddress != other.hasAddress || (hasAddress && !address_.Equals(other.address_))) return false;
+          if (hasAddress2 != other.hasAddress2 || (hasAddress2 && !address2_.Equals(other.address2_))) return false;
+          if (hasCity != other.hasCity || (hasCity && !city_.Equals(other.city_))) return false;
+          if (hasState != other.hasState || (hasState && !state_.Equals(other.state_))) return false;
+          if (hasZip != other.hasZip || (hasZip && !zip_.Equals(other.zip_))) return false;
+          return true;
+        }
+        
+        public override void PrintTo(global::System.IO.TextWriter writer) {
+          PrintField("address", hasAddress, address_, writer);
+          PrintField("address2", hasAddress2, address2_, writer);
+          PrintField("city", hasCity, city_, writer);
+          PrintField("state", hasState, state_, writer);
+          PrintField("zip", hasZip, zip_, writer);
+        }
+        #endregion
+        
+        public static Addresses ParseFrom(pb::ByteString data) {
+          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+        public static Addresses ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+        public static Addresses ParseFrom(byte[] data) {
+          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+        public static Addresses ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+        public static Addresses ParseFrom(global::System.IO.Stream input) {
+          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+        public static Addresses ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+        public static Addresses ParseDelimitedFrom(global::System.IO.Stream input) {
+          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+        public static Addresses ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+        public static Addresses ParseFrom(pb::CodedInputStream input) {
+          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+        public static Addresses ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+        public static Builder CreateBuilder() { return new Builder(); }
+        public override Builder ToBuilder() { return CreateBuilder(this); }
+        public override Builder CreateBuilderForType() { return new Builder(); }
+        public static Builder CreateBuilder(Addresses prototype) {
+          return (Builder) new Builder().MergeFrom(prototype);
+        }
+        
+        public sealed partial class Builder : pb::GeneratedBuilderLite<Addresses, Builder> {
+          protected override Builder ThisBuilder {
+            get { return this; }
+          }
+          public Builder() {}
+          
+          Addresses result = new Addresses();
+          
+          protected override Addresses MessageBeingBuilt {
+            get { return result; }
+          }
+          
+          public override Builder Clear() {
+            result = new Addresses();
+            return this;
+          }
+          
+          public override Builder Clone() {
+            return new Builder().MergeFrom(result);
+          }
+          
+          public override Addresses DefaultInstanceForType {
+            get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.DefaultInstance; }
+          }
+          
+          public override Addresses BuildPartial() {
+            if (result == null) {
+              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+            }
+            Addresses returnMe = result;
+            result = null;
+            return returnMe;
+          }
+          
+          public override Builder MergeFrom(pb::IMessageLite other) {
+            if (other is Addresses) {
+              return MergeFrom((Addresses) other);
+            } else {
+              base.MergeFrom(other);
+              return this;
+            }
+          }
+          
+          public override Builder MergeFrom(Addresses other) {
+            if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.DefaultInstance) return this;
+            if (other.HasAddress) {
+              Address = other.Address;
+            }
+            if (other.HasAddress2) {
+              Address2 = other.Address2;
+            }
+            if (other.HasCity) {
+              City = other.City;
+            }
+            if (other.HasState) {
+              State = other.State;
+            }
+            if (other.HasZip) {
+              Zip = other.Zip;
+            }
+            return this;
+          }
+          
+          public override Builder MergeFrom(pb::CodedInputStream input) {
+            return MergeFrom(input, pb::ExtensionRegistry.Empty);
+          }
+          
+          public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+            while (true) {
+              uint tag = input.ReadTag();
+              switch (tag) {
+                case 0: {
+                  return this;
+                }
+                default: {
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    return this;
+                  }
+                  ParseUnknownField(input, extensionRegistry, tag);
+                  break;
+                }
+                case 10: {
+                  Address = input.ReadString();
+                  break;
+                }
+                case 18: {
+                  Address2 = input.ReadString();
+                  break;
+                }
+                case 26: {
+                  City = input.ReadString();
+                  break;
+                }
+                case 34: {
+                  State = input.ReadString();
+                  break;
+                }
+                case 45: {
+                  Zip = input.ReadFixed32();
+                  break;
+                }
+              }
+            }
+          }
+          
+          
+          public bool HasAddress {
+            get { return result.HasAddress; }
+          }
+          public string Address {
+            get { return result.Address; }
+            set { SetAddress(value); }
+          }
+          public Builder SetAddress(string value) {
+            pb::ThrowHelper.ThrowIfNull(value, "value");
+            result.hasAddress = true;
+            result.address_ = value;
+            return this;
+          }
+          public Builder ClearAddress() {
+            result.hasAddress = false;
+            result.address_ = "";
+            return this;
+          }
+          
+          public bool HasAddress2 {
+            get { return result.HasAddress2; }
+          }
+          public string Address2 {
+            get { return result.Address2; }
+            set { SetAddress2(value); }
+          }
+          public Builder SetAddress2(string value) {
+            pb::ThrowHelper.ThrowIfNull(value, "value");
+            result.hasAddress2 = true;
+            result.address2_ = value;
+            return this;
+          }
+          public Builder ClearAddress2() {
+            result.hasAddress2 = false;
+            result.address2_ = "";
+            return this;
+          }
+          
+          public bool HasCity {
+            get { return result.HasCity; }
+          }
+          public string City {
+            get { return result.City; }
+            set { SetCity(value); }
+          }
+          public Builder SetCity(string value) {
+            pb::ThrowHelper.ThrowIfNull(value, "value");
+            result.hasCity = true;
+            result.city_ = value;
+            return this;
+          }
+          public Builder ClearCity() {
+            result.hasCity = false;
+            result.city_ = "";
+            return this;
+          }
+          
+          public bool HasState {
+            get { return result.HasState; }
+          }
+          public string State {
+            get { return result.State; }
+            set { SetState(value); }
+          }
+          public Builder SetState(string value) {
+            pb::ThrowHelper.ThrowIfNull(value, "value");
+            result.hasState = true;
+            result.state_ = value;
+            return this;
+          }
+          public Builder ClearState() {
+            result.hasState = false;
+            result.state_ = "";
+            return this;
+          }
+          
+          public bool HasZip {
+            get { return result.HasZip; }
+          }
+          [global::System.CLSCompliant(false)]
+          public uint Zip {
+            get { return result.Zip; }
+            set { SetZip(value); }
+          }
+          [global::System.CLSCompliant(false)]
+          public Builder SetZip(uint value) {
+            result.hasZip = true;
+            result.zip_ = value;
+            return this;
+          }
+          public Builder ClearZip() {
+            result.hasZip = false;
+            result.zip_ = 0;
+            return this;
+          }
+        }
+        static Addresses() {
+          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
+        }
+      }
+      
+    }
+    #endregion
+    
+    public const int NameFieldNumber = 1;
+    private bool hasName;
+    private string name_ = "";
+    public bool HasName {
+      get { return hasName; }
+    }
+    public string Name {
+      get { return name_; }
+    }
+    
+    public const int IdFieldNumber = 2;
+    private bool hasId;
+    private int id_ = 0;
+    public bool HasId {
+      get { return hasId; }
+    }
+    public int Id {
+      get { return id_; }
+    }
+    
+    public const int EmailFieldNumber = 3;
+    private bool hasEmail;
+    private string email_ = "";
+    public bool HasEmail {
+      get { return hasEmail; }
+    }
+    public string Email {
+      get { return email_; }
+    }
+    
+    public const int CodesFieldNumber = 10;
+    private int codesMemoizedSerializedSize;
+    private pbc::PopsicleList<int> codes_ = new pbc::PopsicleList<int>();
+    public scg::IList<int> CodesList {
+      get { return pbc::Lists.AsReadOnly(codes_); }
+    }
+    public int CodesCount {
+      get { return codes_.Count; }
+    }
+    public int GetCodes(int index) {
+      return codes_[index];
+    }
+    
+    public const int PhoneFieldNumber = 4;
+    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> phone_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber>();
+    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> PhoneList {
+      get { return phone_; }
+    }
+    public int PhoneCount {
+      get { return phone_.Count; }
+    }
+    public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber GetPhone(int index) {
+      return phone_[index];
+    }
+    
+    public const int AddressesFieldNumber = 5;
+    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> addresses_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses>();
+    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> AddressesList {
+      get { return addresses_; }
+    }
+    public int AddressesCount {
+      get { return addresses_.Count; }
+    }
+    public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses GetAddresses(int index) {
+      return addresses_[index];
+    }
+    
+    public override bool IsInitialized {
+      get {
+        if (!hasName) return false;
+        if (!hasId) return false;
+        foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber element in PhoneList) {
+          if (!element.IsInitialized) return false;
+        }
+        if (!ExtensionsAreInitialized) return false;
+        return true;
+      }
+    }
+    
+    public override void WriteTo(pb::CodedOutputStream output) {
+      int size = SerializedSize;
+      pb::ExtendableMessageLite<TestInteropPersonLite, TestInteropPersonLite.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
+      if (HasName) {
+        output.WriteString(1, Name);
+      }
+      if (HasId) {
+        output.WriteInt32(2, Id);
+      }
+      if (HasEmail) {
+        output.WriteString(3, Email);
+      }
+      foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber element in PhoneList) {
+        output.WriteMessage(4, element);
+      }
+      foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses element in AddressesList) {
+        output.WriteGroup(5, element);
+      }
+      if (codes_.Count > 0) {
+        output.WriteRawVarint32(82);
+        output.WriteRawVarint32((uint) codesMemoizedSerializedSize);
+        foreach (int element in codes_) {
+          output.WriteInt32NoTag(element);
+        }
+      }
+      extensionWriter.WriteUntil(200, output);
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        
+        size = 0;
+        if (HasName) {
+          size += pb::CodedOutputStream.ComputeStringSize(1, Name);
+        }
+        if (HasId) {
+          size += pb::CodedOutputStream.ComputeInt32Size(2, Id);
+        }
+        if (HasEmail) {
+          size += pb::CodedOutputStream.ComputeStringSize(3, Email);
+        }
+        {
+          int dataSize = 0;
+          foreach (int element in CodesList) {
+            dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
+          }
+          size += dataSize;
+          if (codes_.Count != 0) {
+            size += 1 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
+          }
+          codesMemoizedSerializedSize = dataSize;
+        }
+        foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber element in PhoneList) {
+          size += pb::CodedOutputStream.ComputeMessageSize(4, element);
+        }
+        foreach (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses element in AddressesList) {
+          size += pb::CodedOutputStream.ComputeGroupSize(5, element);
+        }
+        size += ExtensionsSerializedSize;
+        memoizedSerializedSize = size;
+        return size;
+      }
+    }
+    
+    #region Lite runtime methods
+    public override int GetHashCode() {
+      int hash = GetType().GetHashCode();
+      if (hasName) hash ^= name_.GetHashCode();
+      if (hasId) hash ^= id_.GetHashCode();
+      if (hasEmail) hash ^= email_.GetHashCode();
+      foreach(int i in codes_)
+        hash ^= i.GetHashCode();
+      foreach(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber i in phone_)
+        hash ^= i.GetHashCode();
+      foreach(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses i in addresses_)
+        hash ^= i.GetHashCode();
+      hash ^= base.GetHashCode();
+      return hash;
+    }
+    
+    public override bool Equals(object obj) {
+      TestInteropPersonLite other = obj as TestInteropPersonLite;
+      if (other == null) return false;
+      if (hasName != other.hasName || (hasName && !name_.Equals(other.name_))) return false;
+      if (hasId != other.hasId || (hasId && !id_.Equals(other.id_))) return false;
+      if (hasEmail != other.hasEmail || (hasEmail && !email_.Equals(other.email_))) return false;
+      if(codes_.Count != other.codes_.Count) return false;
+      for(int ix=0; ix < codes_.Count; ix++)
+        if(!codes_[ix].Equals(other.codes_[ix])) return false;
+      if(phone_.Count != other.phone_.Count) return false;
+      for(int ix=0; ix < phone_.Count; ix++)
+        if(!phone_[ix].Equals(other.phone_[ix])) return false;
+      if(addresses_.Count != other.addresses_.Count) return false;
+      for(int ix=0; ix < addresses_.Count; ix++)
+        if(!addresses_[ix].Equals(other.addresses_[ix])) return false;
+      if (!base.Equals(other)) return false;
+      return true;
+    }
+    
+    public override void PrintTo(global::System.IO.TextWriter writer) {
+      PrintField("name", hasName, name_, writer);
+      PrintField("id", hasId, id_, writer);
+      PrintField("email", hasEmail, email_, writer);
+      PrintField("phone", phone_, writer);
+      PrintField("Addresses", addresses_, writer);
+      PrintField("codes", codes_, writer);
+      base.PrintTo(writer);
+    }
+    #endregion
+    
+    public static TestInteropPersonLite ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseFrom(pb::CodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static TestInteropPersonLite ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(TestInteropPersonLite prototype) {
+      return (Builder) new Builder().MergeFrom(prototype);
+    }
+    
+    public sealed partial class Builder : pb::ExtendableBuilderLite<TestInteropPersonLite, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {}
+      
+      TestInteropPersonLite result = new TestInteropPersonLite();
+      
+      protected override TestInteropPersonLite MessageBeingBuilt {
+        get { return result; }
+      }
+      
+      public override Builder Clear() {
+        result = new TestInteropPersonLite();
+        return this;
+      }
+      
+      public override Builder Clone() {
+        return new Builder().MergeFrom(result);
+      }
+      
+      public override TestInteropPersonLite DefaultInstanceForType {
+        get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.DefaultInstance; }
+      }
+      
+      public override TestInteropPersonLite BuildPartial() {
+        if (result == null) {
+          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        }
+        result.codes_.MakeReadOnly();
+        result.phone_.MakeReadOnly();
+        result.addresses_.MakeReadOnly();
+        TestInteropPersonLite returnMe = result;
+        result = null;
+        return returnMe;
+      }
+      
+      public override Builder MergeFrom(pb::IMessageLite other) {
+        if (other is TestInteropPersonLite) {
+          return MergeFrom((TestInteropPersonLite) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+      
+      public override Builder MergeFrom(TestInteropPersonLite other) {
+        if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.DefaultInstance) return this;
+        if (other.HasName) {
+          Name = other.Name;
+        }
+        if (other.HasId) {
+          Id = other.Id;
+        }
+        if (other.HasEmail) {
+          Email = other.Email;
+        }
+        if (other.codes_.Count != 0) {
+          base.AddRange(other.codes_, result.codes_);
+        }
+        if (other.phone_.Count != 0) {
+          base.AddRange(other.phone_, result.phone_);
+        }
+        if (other.addresses_.Count != 0) {
+          base.AddRange(other.addresses_, result.addresses_);
+        }
+          this.MergeExtensionFields(other);
+        return this;
+      }
+      
+      public override Builder MergeFrom(pb::CodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+      
+      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        while (true) {
+          uint tag = input.ReadTag();
+          switch (tag) {
+            case 0: {
+              return this;
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                return this;
+              }
+              ParseUnknownField(input, extensionRegistry, tag);
+              break;
+            }
+            case 10: {
+              Name = input.ReadString();
+              break;
+            }
+            case 16: {
+              Id = input.ReadInt32();
+              break;
+            }
+            case 26: {
+              Email = input.ReadString();
+              break;
+            }
+            case 34: {
+              global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.CreateBuilder();
+              input.ReadMessage(subBuilder, extensionRegistry);
+              AddPhone(subBuilder.BuildPartial());
+              break;
+            }
+            case 43: {
+              global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.CreateBuilder();
+              input.ReadGroup(5, subBuilder, extensionRegistry);
+              AddAddresses(subBuilder.BuildPartial());
+              break;
+            }
+            case 82: {
+              int length = input.ReadInt32();
+              int limit = input.PushLimit(length);
+              while (!input.ReachedLimit) {
+                AddCodes(input.ReadInt32());
+              }
+              input.PopLimit(limit);
+              break;
+            }
+          }
+        }
+      }
+      
+      
+      public bool HasName {
+        get { return result.HasName; }
+      }
+      public string Name {
+        get { return result.Name; }
+        set { SetName(value); }
+      }
+      public Builder SetName(string value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        result.hasName = true;
+        result.name_ = value;
+        return this;
+      }
+      public Builder ClearName() {
+        result.hasName = false;
+        result.name_ = "";
+        return this;
+      }
+      
+      public bool HasId {
+        get { return result.HasId; }
+      }
+      public int Id {
+        get { return result.Id; }
+        set { SetId(value); }
+      }
+      public Builder SetId(int value) {
+        result.hasId = true;
+        result.id_ = value;
+        return this;
+      }
+      public Builder ClearId() {
+        result.hasId = false;
+        result.id_ = 0;
+        return this;
+      }
+      
+      public bool HasEmail {
+        get { return result.HasEmail; }
+      }
+      public string Email {
+        get { return result.Email; }
+        set { SetEmail(value); }
+      }
+      public Builder SetEmail(string value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        result.hasEmail = true;
+        result.email_ = value;
+        return this;
+      }
+      public Builder ClearEmail() {
+        result.hasEmail = false;
+        result.email_ = "";
+        return this;
+      }
+      
+      public pbc::IPopsicleList<int> CodesList {
+        get { return result.codes_; }
+      }
+      public int CodesCount {
+        get { return result.CodesCount; }
+      }
+      public int GetCodes(int index) {
+        return result.GetCodes(index);
+      }
+      public Builder SetCodes(int index, int value) {
+        result.codes_[index] = value;
+        return this;
+      }
+      public Builder AddCodes(int value) {
+        result.codes_.Add(value);
+        return this;
+      }
+      public Builder AddRangeCodes(scg::IEnumerable<int> values) {
+        base.AddRange(values, result.codes_);
+        return this;
+      }
+      public Builder ClearCodes() {
+        result.codes_.Clear();
+        return this;
+      }
+      
+      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> PhoneList {
+        get { return result.phone_; }
+      }
+      public int PhoneCount {
+        get { return result.PhoneCount; }
+      }
+      public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber GetPhone(int index) {
+        return result.GetPhone(index);
+      }
+      public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        result.phone_[index] = value;
+        return this;
+      }
+      public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        result.phone_[index] = builderForValue.Build();
+        return this;
+      }
+      public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        result.phone_.Add(value);
+        return this;
+      }
+      public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        result.phone_.Add(builderForValue.Build());
+        return this;
+      }
+      public Builder AddRangePhone(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> values) {
+        base.AddRange(values, result.phone_);
+        return this;
+      }
+      public Builder ClearPhone() {
+        result.phone_.Clear();
+        return this;
+      }
+      
+      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> AddressesList {
+        get { return result.addresses_; }
+      }
+      public int AddressesCount {
+        get { return result.AddressesCount; }
+      }
+      public global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses GetAddresses(int index) {
+        return result.GetAddresses(index);
+      }
+      public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        result.addresses_[index] = value;
+        return this;
+      }
+      public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        result.addresses_[index] = builderForValue.Build();
+        return this;
+      }
+      public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        result.addresses_.Add(value);
+        return this;
+      }
+      public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        result.addresses_.Add(builderForValue.Build());
+        return this;
+      }
+      public Builder AddRangeAddresses(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> values) {
+        base.AddRange(values, result.addresses_);
+        return this;
+      }
+      public Builder ClearAddresses() {
+        result.addresses_.Clear();
+        return this;
+      }
+    }
+    static TestInteropPersonLite() {
+      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
+    }
+  }
+  
+  public sealed partial class TestInteropEmployeeIdLite : pb::GeneratedMessageLite<TestInteropEmployeeIdLite, TestInteropEmployeeIdLite.Builder> {
+    private static readonly TestInteropEmployeeIdLite defaultInstance = new Builder().BuildPartial();
+    public static TestInteropEmployeeIdLite DefaultInstance {
+      get { return defaultInstance; }
+    }
+    
+    public override TestInteropEmployeeIdLite DefaultInstanceForType {
+      get { return defaultInstance; }
+    }
+    
+    protected override TestInteropEmployeeIdLite ThisMessage {
+      get { return this; }
+    }
+    
+    public const int NumberFieldNumber = 1;
+    private bool hasNumber;
+    private string number_ = "";
+    public bool HasNumber {
+      get { return hasNumber; }
+    }
+    public string Number {
+      get { return number_; }
+    }
+    
+    public override bool IsInitialized {
+      get {
+        if (!hasNumber) return false;
+        return true;
+      }
+    }
+    
+    public override void WriteTo(pb::CodedOutputStream output) {
+      int size = SerializedSize;
+      if (HasNumber) {
+        output.WriteString(1, Number);
+      }
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        
+        size = 0;
+        if (HasNumber) {
+          size += pb::CodedOutputStream.ComputeStringSize(1, Number);
+        }
+        memoizedSerializedSize = size;
+        return size;
+      }
+    }
+    
+    #region Lite runtime methods
+    public override int GetHashCode() {
+      int hash = GetType().GetHashCode();
+      if (hasNumber) hash ^= number_.GetHashCode();
+      return hash;
+    }
+    
+    public override bool Equals(object obj) {
+      TestInteropEmployeeIdLite other = obj as TestInteropEmployeeIdLite;
+      if (other == null) return false;
+      if (hasNumber != other.hasNumber || (hasNumber && !number_.Equals(other.number_))) return false;
+      return true;
+    }
+    
+    public override void PrintTo(global::System.IO.TextWriter writer) {
+      PrintField("number", hasNumber, number_, writer);
+    }
+    #endregion
+    
+    public static TestInteropEmployeeIdLite ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseFrom(pb::CodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static TestInteropEmployeeIdLite ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(TestInteropEmployeeIdLite prototype) {
+      return (Builder) new Builder().MergeFrom(prototype);
+    }
+    
+    public sealed partial class Builder : pb::GeneratedBuilderLite<TestInteropEmployeeIdLite, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {}
+      
+      TestInteropEmployeeIdLite result = new TestInteropEmployeeIdLite();
+      
+      protected override TestInteropEmployeeIdLite MessageBeingBuilt {
+        get { return result; }
+      }
+      
+      public override Builder Clear() {
+        result = new TestInteropEmployeeIdLite();
+        return this;
+      }
+      
+      public override Builder Clone() {
+        return new Builder().MergeFrom(result);
+      }
+      
+      public override TestInteropEmployeeIdLite DefaultInstanceForType {
+        get { return global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite.DefaultInstance; }
+      }
+      
+      public override TestInteropEmployeeIdLite BuildPartial() {
+        if (result == null) {
+          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        }
+        TestInteropEmployeeIdLite returnMe = result;
+        result = null;
+        return returnMe;
+      }
+      
+      public override Builder MergeFrom(pb::IMessageLite other) {
+        if (other is TestInteropEmployeeIdLite) {
+          return MergeFrom((TestInteropEmployeeIdLite) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+      
+      public override Builder MergeFrom(TestInteropEmployeeIdLite other) {
+        if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite.DefaultInstance) return this;
+        if (other.HasNumber) {
+          Number = other.Number;
+        }
+        return this;
+      }
+      
+      public override Builder MergeFrom(pb::CodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+      
+      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        while (true) {
+          uint tag = input.ReadTag();
+          switch (tag) {
+            case 0: {
+              return this;
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                return this;
+              }
+              ParseUnknownField(input, extensionRegistry, tag);
+              break;
+            }
+            case 10: {
+              Number = input.ReadString();
+              break;
+            }
+          }
+        }
+      }
+      
+      
+      public bool HasNumber {
+        get { return result.HasNumber; }
+      }
+      public string Number {
+        get { return result.Number; }
+        set { SetNumber(value); }
+      }
+      public Builder SetNumber(string value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        result.hasNumber = true;
+        result.number_ = value;
+        return this;
+      }
+      public Builder ClearNumber() {
+        result.hasNumber = false;
+        result.number_ = "";
+        return this;
+      }
+    }
+    static TestInteropEmployeeIdLite() {
+      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasLiteProtoFile.Descriptor, null);
+    }
+  }
+  
+  #endregion
+  
+}

+ 116 - 116
testdata/text_format_unittest_data.txt

@@ -1,116 +1,116 @@
-optional_int32: 101
-optional_int64: 102
-optional_uint32: 103
-optional_uint64: 104
-optional_sint32: 105
-optional_sint64: 106
-optional_fixed32: 107
-optional_fixed64: 108
-optional_sfixed32: 109
-optional_sfixed64: 110
-optional_float: 111
-optional_double: 112
-optional_bool: true
-optional_string: "115"
-optional_bytes: "116"
-OptionalGroup {
-  a: 117
-}
-optional_nested_message {
-  bb: 118
-}
-optional_foreign_message {
-  c: 119
-}
-optional_import_message {
-  d: 120
-}
-optional_nested_enum: BAZ
-optional_foreign_enum: FOREIGN_BAZ
-optional_import_enum: IMPORT_BAZ
-optional_string_piece: "124"
-optional_cord: "125"
-repeated_int32: 201
-repeated_int32: 301
-repeated_int64: 202
-repeated_int64: 302
-repeated_uint32: 203
-repeated_uint32: 303
-repeated_uint64: 204
-repeated_uint64: 304
-repeated_sint32: 205
-repeated_sint32: 305
-repeated_sint64: 206
-repeated_sint64: 306
-repeated_fixed32: 207
-repeated_fixed32: 307
-repeated_fixed64: 208
-repeated_fixed64: 308
-repeated_sfixed32: 209
-repeated_sfixed32: 309
-repeated_sfixed64: 210
-repeated_sfixed64: 310
-repeated_float: 211
-repeated_float: 311
-repeated_double: 212
-repeated_double: 312
-repeated_bool: true
-repeated_bool: false
-repeated_string: "215"
-repeated_string: "315"
-repeated_bytes: "216"
-repeated_bytes: "316"
-RepeatedGroup {
-  a: 217
-}
-RepeatedGroup {
-  a: 317
-}
-repeated_nested_message {
-  bb: 218
-}
-repeated_nested_message {
-  bb: 318
-}
-repeated_foreign_message {
-  c: 219
-}
-repeated_foreign_message {
-  c: 319
-}
-repeated_import_message {
-  d: 220
-}
-repeated_import_message {
-  d: 320
-}
-repeated_nested_enum: BAR
-repeated_nested_enum: BAZ
-repeated_foreign_enum: FOREIGN_BAR
-repeated_foreign_enum: FOREIGN_BAZ
-repeated_import_enum: IMPORT_BAR
-repeated_import_enum: IMPORT_BAZ
-repeated_string_piece: "224"
-repeated_string_piece: "324"
-repeated_cord: "225"
-repeated_cord: "325"
-default_int32: 401
-default_int64: 402
-default_uint32: 403
-default_uint64: 404
-default_sint32: 405
-default_sint64: 406
-default_fixed32: 407
-default_fixed64: 408
-default_sfixed32: 409
-default_sfixed64: 410
-default_float: 411
-default_double: 412
-default_bool: false
-default_string: "415"
-default_bytes: "416"
-default_nested_enum: FOO
-default_foreign_enum: FOREIGN_FOO
-default_import_enum: IMPORT_FOO
-default_string_piece: "424"
-default_cord: "425"
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup {
+  a: 117
+}
+optional_nested_message {
+  bb: 118
+}
+optional_foreign_message {
+  c: 119
+}
+optional_import_message {
+  d: 120
+}
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup {
+  a: 217
+}
+RepeatedGroup {
+  a: 317
+}
+repeated_nested_message {
+  bb: 218
+}
+repeated_nested_message {
+  bb: 318
+}
+repeated_foreign_message {
+  c: 219
+}
+repeated_foreign_message {
+  c: 319
+}
+repeated_import_message {
+  d: 220
+}
+repeated_import_message {
+  d: 320
+}
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"

+ 116 - 116
testdata/text_format_unittest_extensions_data.txt

@@ -1,116 +1,116 @@
-[protobuf_unittest.optional_int32_extension]: 101
-[protobuf_unittest.optional_int64_extension]: 102
-[protobuf_unittest.optional_uint32_extension]: 103
-[protobuf_unittest.optional_uint64_extension]: 104
-[protobuf_unittest.optional_sint32_extension]: 105
-[protobuf_unittest.optional_sint64_extension]: 106
-[protobuf_unittest.optional_fixed32_extension]: 107
-[protobuf_unittest.optional_fixed64_extension]: 108
-[protobuf_unittest.optional_sfixed32_extension]: 109
-[protobuf_unittest.optional_sfixed64_extension]: 110
-[protobuf_unittest.optional_float_extension]: 111
-[protobuf_unittest.optional_double_extension]: 112
-[protobuf_unittest.optional_bool_extension]: true
-[protobuf_unittest.optional_string_extension]: "115"
-[protobuf_unittest.optional_bytes_extension]: "116"
-[protobuf_unittest.optionalgroup_extension] {
-  a: 117
-}
-[protobuf_unittest.optional_nested_message_extension] {
-  bb: 118
-}
-[protobuf_unittest.optional_foreign_message_extension] {
-  c: 119
-}
-[protobuf_unittest.optional_import_message_extension] {
-  d: 120
-}
-[protobuf_unittest.optional_nested_enum_extension]: BAZ
-[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ
-[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ
-[protobuf_unittest.optional_string_piece_extension]: "124"
-[protobuf_unittest.optional_cord_extension]: "125"
-[protobuf_unittest.repeated_int32_extension]: 201
-[protobuf_unittest.repeated_int32_extension]: 301
-[protobuf_unittest.repeated_int64_extension]: 202
-[protobuf_unittest.repeated_int64_extension]: 302
-[protobuf_unittest.repeated_uint32_extension]: 203
-[protobuf_unittest.repeated_uint32_extension]: 303
-[protobuf_unittest.repeated_uint64_extension]: 204
-[protobuf_unittest.repeated_uint64_extension]: 304
-[protobuf_unittest.repeated_sint32_extension]: 205
-[protobuf_unittest.repeated_sint32_extension]: 305
-[protobuf_unittest.repeated_sint64_extension]: 206
-[protobuf_unittest.repeated_sint64_extension]: 306
-[protobuf_unittest.repeated_fixed32_extension]: 207
-[protobuf_unittest.repeated_fixed32_extension]: 307
-[protobuf_unittest.repeated_fixed64_extension]: 208
-[protobuf_unittest.repeated_fixed64_extension]: 308
-[protobuf_unittest.repeated_sfixed32_extension]: 209
-[protobuf_unittest.repeated_sfixed32_extension]: 309
-[protobuf_unittest.repeated_sfixed64_extension]: 210
-[protobuf_unittest.repeated_sfixed64_extension]: 310
-[protobuf_unittest.repeated_float_extension]: 211
-[protobuf_unittest.repeated_float_extension]: 311
-[protobuf_unittest.repeated_double_extension]: 212
-[protobuf_unittest.repeated_double_extension]: 312
-[protobuf_unittest.repeated_bool_extension]: true
-[protobuf_unittest.repeated_bool_extension]: false
-[protobuf_unittest.repeated_string_extension]: "215"
-[protobuf_unittest.repeated_string_extension]: "315"
-[protobuf_unittest.repeated_bytes_extension]: "216"
-[protobuf_unittest.repeated_bytes_extension]: "316"
-[protobuf_unittest.repeatedgroup_extension] {
-  a: 217
-}
-[protobuf_unittest.repeatedgroup_extension] {
-  a: 317
-}
-[protobuf_unittest.repeated_nested_message_extension] {
-  bb: 218
-}
-[protobuf_unittest.repeated_nested_message_extension] {
-  bb: 318
-}
-[protobuf_unittest.repeated_foreign_message_extension] {
-  c: 219
-}
-[protobuf_unittest.repeated_foreign_message_extension] {
-  c: 319
-}
-[protobuf_unittest.repeated_import_message_extension] {
-  d: 220
-}
-[protobuf_unittest.repeated_import_message_extension] {
-  d: 320
-}
-[protobuf_unittest.repeated_nested_enum_extension]: BAR
-[protobuf_unittest.repeated_nested_enum_extension]: BAZ
-[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR
-[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ
-[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR
-[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ
-[protobuf_unittest.repeated_string_piece_extension]: "224"
-[protobuf_unittest.repeated_string_piece_extension]: "324"
-[protobuf_unittest.repeated_cord_extension]: "225"
-[protobuf_unittest.repeated_cord_extension]: "325"
-[protobuf_unittest.default_int32_extension]: 401
-[protobuf_unittest.default_int64_extension]: 402
-[protobuf_unittest.default_uint32_extension]: 403
-[protobuf_unittest.default_uint64_extension]: 404
-[protobuf_unittest.default_sint32_extension]: 405
-[protobuf_unittest.default_sint64_extension]: 406
-[protobuf_unittest.default_fixed32_extension]: 407
-[protobuf_unittest.default_fixed64_extension]: 408
-[protobuf_unittest.default_sfixed32_extension]: 409
-[protobuf_unittest.default_sfixed64_extension]: 410
-[protobuf_unittest.default_float_extension]: 411
-[protobuf_unittest.default_double_extension]: 412
-[protobuf_unittest.default_bool_extension]: false
-[protobuf_unittest.default_string_extension]: "415"
-[protobuf_unittest.default_bytes_extension]: "416"
-[protobuf_unittest.default_nested_enum_extension]: FOO
-[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO
-[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO
-[protobuf_unittest.default_string_piece_extension]: "424"
-[protobuf_unittest.default_cord_extension]: "425"
+[protobuf_unittest.optional_int32_extension]: 101
+[protobuf_unittest.optional_int64_extension]: 102
+[protobuf_unittest.optional_uint32_extension]: 103
+[protobuf_unittest.optional_uint64_extension]: 104
+[protobuf_unittest.optional_sint32_extension]: 105
+[protobuf_unittest.optional_sint64_extension]: 106
+[protobuf_unittest.optional_fixed32_extension]: 107
+[protobuf_unittest.optional_fixed64_extension]: 108
+[protobuf_unittest.optional_sfixed32_extension]: 109
+[protobuf_unittest.optional_sfixed64_extension]: 110
+[protobuf_unittest.optional_float_extension]: 111
+[protobuf_unittest.optional_double_extension]: 112
+[protobuf_unittest.optional_bool_extension]: true
+[protobuf_unittest.optional_string_extension]: "115"
+[protobuf_unittest.optional_bytes_extension]: "116"
+[protobuf_unittest.optionalgroup_extension] {
+  a: 117
+}
+[protobuf_unittest.optional_nested_message_extension] {
+  bb: 118
+}
+[protobuf_unittest.optional_foreign_message_extension] {
+  c: 119
+}
+[protobuf_unittest.optional_import_message_extension] {
+  d: 120
+}
+[protobuf_unittest.optional_nested_enum_extension]: BAZ
+[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.optional_string_piece_extension]: "124"
+[protobuf_unittest.optional_cord_extension]: "125"
+[protobuf_unittest.repeated_int32_extension]: 201
+[protobuf_unittest.repeated_int32_extension]: 301
+[protobuf_unittest.repeated_int64_extension]: 202
+[protobuf_unittest.repeated_int64_extension]: 302
+[protobuf_unittest.repeated_uint32_extension]: 203
+[protobuf_unittest.repeated_uint32_extension]: 303
+[protobuf_unittest.repeated_uint64_extension]: 204
+[protobuf_unittest.repeated_uint64_extension]: 304
+[protobuf_unittest.repeated_sint32_extension]: 205
+[protobuf_unittest.repeated_sint32_extension]: 305
+[protobuf_unittest.repeated_sint64_extension]: 206
+[protobuf_unittest.repeated_sint64_extension]: 306
+[protobuf_unittest.repeated_fixed32_extension]: 207
+[protobuf_unittest.repeated_fixed32_extension]: 307
+[protobuf_unittest.repeated_fixed64_extension]: 208
+[protobuf_unittest.repeated_fixed64_extension]: 308
+[protobuf_unittest.repeated_sfixed32_extension]: 209
+[protobuf_unittest.repeated_sfixed32_extension]: 309
+[protobuf_unittest.repeated_sfixed64_extension]: 210
+[protobuf_unittest.repeated_sfixed64_extension]: 310
+[protobuf_unittest.repeated_float_extension]: 211
+[protobuf_unittest.repeated_float_extension]: 311
+[protobuf_unittest.repeated_double_extension]: 212
+[protobuf_unittest.repeated_double_extension]: 312
+[protobuf_unittest.repeated_bool_extension]: true
+[protobuf_unittest.repeated_bool_extension]: false
+[protobuf_unittest.repeated_string_extension]: "215"
+[protobuf_unittest.repeated_string_extension]: "315"
+[protobuf_unittest.repeated_bytes_extension]: "216"
+[protobuf_unittest.repeated_bytes_extension]: "316"
+[protobuf_unittest.repeatedgroup_extension] {
+  a: 217
+}
+[protobuf_unittest.repeatedgroup_extension] {
+  a: 317
+}
+[protobuf_unittest.repeated_nested_message_extension] {
+  bb: 218
+}
+[protobuf_unittest.repeated_nested_message_extension] {
+  bb: 318
+}
+[protobuf_unittest.repeated_foreign_message_extension] {
+  c: 219
+}
+[protobuf_unittest.repeated_foreign_message_extension] {
+  c: 319
+}
+[protobuf_unittest.repeated_import_message_extension] {
+  d: 220
+}
+[protobuf_unittest.repeated_import_message_extension] {
+  d: 320
+}
+[protobuf_unittest.repeated_nested_enum_extension]: BAR
+[protobuf_unittest.repeated_nested_enum_extension]: BAZ
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.repeated_string_piece_extension]: "224"
+[protobuf_unittest.repeated_string_piece_extension]: "324"
+[protobuf_unittest.repeated_cord_extension]: "225"
+[protobuf_unittest.repeated_cord_extension]: "325"
+[protobuf_unittest.default_int32_extension]: 401
+[protobuf_unittest.default_int64_extension]: 402
+[protobuf_unittest.default_uint32_extension]: 403
+[protobuf_unittest.default_uint64_extension]: 404
+[protobuf_unittest.default_sint32_extension]: 405
+[protobuf_unittest.default_sint64_extension]: 406
+[protobuf_unittest.default_fixed32_extension]: 407
+[protobuf_unittest.default_fixed64_extension]: 408
+[protobuf_unittest.default_sfixed32_extension]: 409
+[protobuf_unittest.default_sfixed64_extension]: 410
+[protobuf_unittest.default_float_extension]: 411
+[protobuf_unittest.default_double_extension]: 412
+[protobuf_unittest.default_bool_extension]: false
+[protobuf_unittest.default_string_extension]: "415"
+[protobuf_unittest.default_bytes_extension]: "416"
+[protobuf_unittest.default_nested_enum_extension]: FOO
+[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO
+[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO
+[protobuf_unittest.default_string_piece_extension]: "424"
+[protobuf_unittest.default_cord_extension]: "425"

+ 16 - 16
todo.txt

@@ -1,16 +1,16 @@
-Current task list (not in order)
-
-- Remove multifile support
-- Docs
-- Clean up protogen code
-- Avoid using reflection for messages which don't need it (is this
-  possible?)
-- Bring service generation into line with Java
-- Build protoc as a dll and use directly from protogen
-- Check copyright is everywhere
-- Work out how to unit test Silverlight code
-- Reformat code
-- Change generated format
-- Add regions to copyright
-- Build and publish binaries
-- Work out why the Compact Framework 3.5 build fails under VS2010
+Current task list (not in order)
+
+- Remove multifile support
+- Docs
+- Clean up protogen code
+- Avoid using reflection for messages which don't need it (is this
+  possible?)
+- Bring service generation into line with Java
+- Build protoc as a dll and use directly from protogen
+- Check copyright is everywhere
+- Work out how to unit test Silverlight code
+- Reformat code
+- Change generated format
+- Add regions to copyright
+- Build and publish binaries
+- Work out why the Compact Framework 3.5 build fails under VS2010