浏览代码

reformatted all code to .NET standard formatting

csharptest 14 年之前
父节点
当前提交
71f662c33e
共有 100 个文件被更改,包括 34832 次插入27661 次删除
  1. 135 120
      src/AddressBook/AddPerson.cs
  2. 103 90
      src/AddressBook/ListPeople.cs
  3. 98 88
      src/AddressBook/Program.cs
  4. 39 35
      src/AddressBook/Properties/AssemblyInfo.cs
  5. 35 35
      src/AddressBook/SampleUsage.cs
  6. 168 144
      src/ProtoBench/Program.cs
  7. 42 39
      src/ProtoBench/Properties/AssemblyInfo.cs
  8. 87 75
      src/ProtoDump/Program.cs
  9. 40 36
      src/ProtoDump/Properties/AssemblyInfo.cs
  10. 5 3
      src/ProtoDump/app.config
  11. 149 125
      src/ProtoGen.Test/DependencyResolutionTest.cs
  12. 40 36
      src/ProtoGen.Test/Properties/AssemblyInfo.cs
  13. 59 54
      src/ProtoGen.Test/TempFile.cs
  14. 677 610
      src/ProtoGen.Test/TestPreprocessing.cs
  15. 55 49
      src/ProtoGen/DependencyResolutionException.cs
  16. 106 86
      src/ProtoGen/DescriptorUtil.cs
  17. 143 126
      src/ProtoGen/EnumFieldGenerator.cs
  18. 61 54
      src/ProtoGen/EnumGenerator.cs
  19. 177 135
      src/ProtoGen/ExtensionGenerator.cs
  20. 316 268
      src/ProtoGen/FieldGeneratorBase.cs
  21. 246 209
      src/ProtoGen/Generator.cs
  22. 329 284
      src/ProtoGen/GeneratorOptions.cs
  23. 45 42
      src/ProtoGen/Helpers.cs
  24. 53 49
      src/ProtoGen/IFieldSourceGenerator.cs
  25. 43 39
      src/ProtoGen/ISourceGenerator.cs
  26. 77 70
      src/ProtoGen/InvalidOptionsException.cs
  27. 161 142
      src/ProtoGen/MessageFieldGenerator.cs
  28. 732 617
      src/ProtoGen/MessageGenerator.cs
  29. 134 119
      src/ProtoGen/PrimitiveFieldGenerator.cs
  30. 77 71
      src/ProtoGen/Program.cs
  31. 186 153
      src/ProtoGen/ProgramPreprocess.cs
  32. 40 37
      src/ProtoGen/Properties/AssemblyInfo.cs
  33. 219 194
      src/ProtoGen/RepeatedEnumFieldGenerator.cs
  34. 170 153
      src/ProtoGen/RepeatedMessageFieldGenerator.cs
  35. 216 187
      src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs
  36. 184 168
      src/ProtoGen/ServiceGenerator.cs
  37. 239 197
      src/ProtoGen/ServiceInterfaceGenerator.cs
  38. 156 131
      src/ProtoGen/SourceGeneratorBase.cs
  39. 152 79
      src/ProtoGen/SourceGenerators.cs
  40. 285 241
      src/ProtoGen/UmbrellaClassGenerator.cs
  41. 5 3
      src/ProtoGen/app.config
  42. 304 260
      src/ProtoMunge/Program.cs
  43. 40 36
      src/ProtoMunge/Properties/AssemblyInfo.cs
  44. 5 3
      src/ProtoMunge/app.config
  45. 476 419
      src/ProtocolBuffers.Test/AbstractMessageTest.cs
  46. 131 117
      src/ProtocolBuffers.Test/ByteStringTest.cs
  47. 127 104
      src/ProtocolBuffers.Test/CSharpOptionsTest.cs
  48. 526 459
      src/ProtocolBuffers.Test/CodedInputStreamTest.cs
  49. 292 270
      src/ProtocolBuffers.Test/CodedOutputStreamTest.cs
  50. 110 100
      src/ProtocolBuffers.Test/Collections/PopsicleListTest.cs
  51. 72 65
      src/ProtocolBuffers.Test/Descriptors/MessageDescriptorTest.cs
  52. 350 325
      src/ProtocolBuffers.Test/DescriptorsTest.cs
  53. 237 215
      src/ProtocolBuffers.Test/DynamicMessageTest.cs
  54. 202 192
      src/ProtocolBuffers.Test/ExtendableMessageTest.cs
  55. 538 465
      src/ProtocolBuffers.Test/GeneratedMessageTest.cs
  56. 91 83
      src/ProtocolBuffers.Test/MessageStreamIteratorTest.cs
  57. 79 70
      src/ProtocolBuffers.Test/MessageStreamWriterTest.cs
  58. 380 329
      src/ProtocolBuffers.Test/MessageTest.cs
  59. 87 77
      src/ProtocolBuffers.Test/MessageUtilTest.cs
  60. 71 65
      src/ProtocolBuffers.Test/NameHelpersTest.cs
  61. 45 40
      src/ProtocolBuffers.Test/Properties/AssemblyInfo.cs
  62. 990 936
      src/ProtocolBuffers.Test/ReflectionTester.cs
  63. 216 198
      src/ProtocolBuffers.Test/ServiceTest.cs
  64. 89 71
      src/ProtocolBuffers.Test/TestRpcGenerator.cs
  65. 1705 1620
      src/ProtocolBuffers.Test/TestUtil.cs
  66. 571 536
      src/ProtocolBuffers.Test/TextFormatTest.cs
  67. 433 400
      src/ProtocolBuffers.Test/UnknownFieldSetTest.cs
  68. 316 297
      src/ProtocolBuffers.Test/WireFormatTest.cs
  69. 254 214
      src/ProtocolBuffers/AbstractBuilder.cs
  70. 266 232
      src/ProtocolBuffers/AbstractBuilderLite.cs
  71. 303 245
      src/ProtocolBuffers/AbstractMessage.cs
  72. 142 133
      src/ProtocolBuffers/AbstractMessageLite.cs
  73. 241 213
      src/ProtocolBuffers/ByteString.cs
  74. 1155 985
      src/ProtocolBuffers/CodedInputStream.cs
  75. 1423 1146
      src/ProtocolBuffers/CodedOutputStream.cs
  76. 122 108
      src/ProtocolBuffers/Collections/Dictionaries.cs
  77. 74 63
      src/ProtocolBuffers/Collections/Enumerables.cs
  78. 50 48
      src/ProtocolBuffers/Collections/IPopsicleList.cs
  79. 110 99
      src/ProtocolBuffers/Collections/Lists.cs
  80. 150 132
      src/ProtocolBuffers/Collections/PopsicleList.cs
  81. 146 128
      src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs
  82. 60 51
      src/ProtocolBuffers/Delegates.cs
  83. 2209 1451
      src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
  84. 10670 6956
      src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
  85. 52 52
      src/ProtocolBuffers/DescriptorProtos/IDescriptorProto.cs
  86. 65 45
      src/ProtocolBuffers/DescriptorProtos/PartialClasses.cs
  87. 115 103
      src/ProtocolBuffers/Descriptors/DescriptorBase.cs
  88. 352 296
      src/ProtocolBuffers/Descriptors/DescriptorPool.cs
  89. 64 59
      src/ProtocolBuffers/Descriptors/DescriptorUtil.cs
  90. 90 86
      src/ProtocolBuffers/Descriptors/DescriptorValidationException.cs
  91. 121 109
      src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
  92. 63 59
      src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs
  93. 666 521
      src/ProtocolBuffers/Descriptors/FieldDescriptor.cs
  94. 88 77
      src/ProtocolBuffers/Descriptors/FieldMappingAttribute.cs
  95. 60 58
      src/ProtocolBuffers/Descriptors/FieldType.cs
  96. 495 431
      src/ProtocolBuffers/Descriptors/FileDescriptor.cs
  97. 55 53
      src/ProtocolBuffers/Descriptors/IDescriptor.cs
  98. 64 61
      src/ProtocolBuffers/Descriptors/IndexedDescriptorBase.cs
  99. 52 50
      src/ProtocolBuffers/Descriptors/MappedType.cs
  100. 288 252
      src/ProtocolBuffers/Descriptors/MessageDescriptor.cs

+ 135 - 120
src/AddressBook/AddPerson.cs

@@ -1,121 +1,136 @@
-#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;
-
-namespace Google.ProtocolBuffers.Examples.AddressBook
-{
-  class AddPerson {
-    
-    /// <summary>
-    /// Builds a person based on user input
-    /// </summary>
-    static Person PromptForAddress(TextReader input, TextWriter output) {
-      Person.Builder person = Person.CreateBuilder();
-
-      output.Write("Enter person ID: ");
-      person.Id = int.Parse(input.ReadLine());
-
-      output.Write("Enter name: ");
-      person.Name = input.ReadLine();
-
-      output.Write("Enter email address (blank for none): ");
-      string email = input.ReadLine();
-      if (email.Length > 0) {
-        person.Email = email;
-      }
-
-      while (true) {
-        output.Write("Enter a phone number (or leave blank to finish): ");
-        string number = input.ReadLine();
-        if (number.Length == 0) {
-          break;
-        }
-
-        Person.Types.PhoneNumber.Builder phoneNumber =
-            Person.Types.PhoneNumber.CreateBuilder().SetNumber(number);
-
-        output.Write("Is this a mobile, home, or work phone? ");
-        String type = input.ReadLine();
-        switch (type) {
-          case "mobile":
-            phoneNumber.Type = Person.Types.PhoneType.MOBILE;
-            break;
-          case "home":
-            phoneNumber.Type = Person.Types.PhoneType.HOME;
-            break;
-          case "work":
-            phoneNumber.Type = Person.Types.PhoneType.WORK;
-            break;
-          default:
-            output.Write("Unknown phone type. Using default.");
-            break;
-        }
-
-        person.AddPhone(phoneNumber);
-      }
-      return person.Build();
-    }
-
-    /// <summary>
-    /// Entry point - loads an existing addressbook or creates a new one,
-    /// then writes it back to the file.
-    /// </summary>
-    public static int Main(string[] args) {
-      if (args.Length != 1) {
-        Console.Error.WriteLine("Usage:  AddPerson ADDRESS_BOOK_FILE");
-        return -1;
-      }
-
-      AddressBook.Builder addressBook = AddressBook.CreateBuilder();
-
-      if (File.Exists(args[0])) {
-        using (Stream file = File.OpenRead(args[0])) {
-          addressBook.MergeFrom(file);
-        }
-      } else {
-        Console.WriteLine("{0}: File not found. Creating a new file.", args[0]);
-      }
-
-      // Add an address.
-      addressBook.AddPerson(PromptForAddress(Console.In, Console.Out));
-
-      // Write the new address book back to disk.
-      using (Stream output = File.OpenWrite(args[0])) {
-        addressBook.Build().WriteTo(output);
-      }
-      return 0;
-    }
-  }
+#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;
+
+namespace Google.ProtocolBuffers.Examples.AddressBook
+{
+    internal class AddPerson
+    {
+        /// <summary>
+        /// Builds a person based on user input
+        /// </summary>
+        private static Person PromptForAddress(TextReader input, TextWriter output)
+        {
+            Person.Builder person = Person.CreateBuilder();
+
+            output.Write("Enter person ID: ");
+            person.Id = int.Parse(input.ReadLine());
+
+            output.Write("Enter name: ");
+            person.Name = input.ReadLine();
+
+            output.Write("Enter email address (blank for none): ");
+            string email = input.ReadLine();
+            if (email.Length > 0)
+            {
+                person.Email = email;
+            }
+
+            while (true)
+            {
+                output.Write("Enter a phone number (or leave blank to finish): ");
+                string number = input.ReadLine();
+                if (number.Length == 0)
+                {
+                    break;
+                }
+
+                Person.Types.PhoneNumber.Builder phoneNumber =
+                    Person.Types.PhoneNumber.CreateBuilder().SetNumber(number);
+
+                output.Write("Is this a mobile, home, or work phone? ");
+                String type = input.ReadLine();
+                switch (type)
+                {
+                    case "mobile":
+                        phoneNumber.Type = Person.Types.PhoneType.MOBILE;
+                        break;
+                    case "home":
+                        phoneNumber.Type = Person.Types.PhoneType.HOME;
+                        break;
+                    case "work":
+                        phoneNumber.Type = Person.Types.PhoneType.WORK;
+                        break;
+                    default:
+                        output.Write("Unknown phone type. Using default.");
+                        break;
+                }
+
+                person.AddPhone(phoneNumber);
+            }
+            return person.Build();
+        }
+
+        /// <summary>
+        /// Entry point - loads an existing addressbook or creates a new one,
+        /// then writes it back to the file.
+        /// </summary>
+        public static int Main(string[] args)
+        {
+            if (args.Length != 1)
+            {
+                Console.Error.WriteLine("Usage:  AddPerson ADDRESS_BOOK_FILE");
+                return -1;
+            }
+
+            AddressBook.Builder addressBook = AddressBook.CreateBuilder();
+
+            if (File.Exists(args[0]))
+            {
+                using (Stream file = File.OpenRead(args[0]))
+                {
+                    addressBook.MergeFrom(file);
+                }
+            }
+            else
+            {
+                Console.WriteLine("{0}: File not found. Creating a new file.", args[0]);
+            }
+
+            // Add an address.
+            addressBook.AddPerson(PromptForAddress(Console.In, Console.Out));
+
+            // Write the new address book back to disk.
+            using (Stream output = File.OpenWrite(args[0]))
+            {
+                addressBook.Build().WriteTo(output);
+            }
+            return 0;
+        }
+    }
 }

+ 103 - 90
src/AddressBook/ListPeople.cs

@@ -1,90 +1,103 @@
-#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;
-
-namespace Google.ProtocolBuffers.Examples.AddressBook {
-  class ListPeople {
-    /// <summary>
-    /// Iterates though all people in the AddressBook and prints info about them.
-    /// </summary>
-    static void Print(AddressBook addressBook) {
-      foreach (Person person in addressBook.PersonList) {
-        Console.WriteLine("Person ID: {0}", person.Id);
-        Console.WriteLine("  Name: {0}", person.Name);
-        if (person.HasEmail) {
-          Console.WriteLine("  E-mail address: {0}", person.Email);
-        }
-
-        foreach (Person.Types.PhoneNumber phoneNumber in person.PhoneList) {
-          switch (phoneNumber.Type) {
-            case Person.Types.PhoneType.MOBILE:
-              Console.Write("  Mobile phone #: ");
-              break;
-            case Person.Types.PhoneType.HOME:
-              Console.Write("  Home phone #: ");
-              break;
-            case Person.Types.PhoneType.WORK:
-              Console.Write("  Work phone #: ");
-              break;
-          }
-          Console.WriteLine(phoneNumber.Number);
-        }
-      }
-    }
-
-    /// <summary>
-    /// Entry point - loads the addressbook and then displays it.
-    /// </summary>
-    public static int Main(string[] args) {
-      if (args.Length != 1) {
-        Console.Error.WriteLine("Usage:  ListPeople ADDRESS_BOOK_FILE");
-        return 1;
-      }
-
-      if (!File.Exists(args[0])) {
-        Console.WriteLine("{0} doesn't exist. Add a person to create the file first.", args[0]);
-        return 0;
-      }
-
-      // Read the existing address book.
-      using (Stream stream = File.OpenRead(args[0])) {
-        AddressBook addressBook = AddressBook.ParseFrom(stream);
-        Print(addressBook);
-      }
-      return 0;
-    }
-  }
-}
+#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;
+
+namespace Google.ProtocolBuffers.Examples.AddressBook
+{
+    internal class ListPeople
+    {
+        /// <summary>
+        /// Iterates though all people in the AddressBook and prints info about them.
+        /// </summary>
+        private static void Print(AddressBook addressBook)
+        {
+            foreach (Person person in addressBook.PersonList)
+            {
+                Console.WriteLine("Person ID: {0}", person.Id);
+                Console.WriteLine("  Name: {0}", person.Name);
+                if (person.HasEmail)
+                {
+                    Console.WriteLine("  E-mail address: {0}", person.Email);
+                }
+
+                foreach (Person.Types.PhoneNumber phoneNumber in person.PhoneList)
+                {
+                    switch (phoneNumber.Type)
+                    {
+                        case Person.Types.PhoneType.MOBILE:
+                            Console.Write("  Mobile phone #: ");
+                            break;
+                        case Person.Types.PhoneType.HOME:
+                            Console.Write("  Home phone #: ");
+                            break;
+                        case Person.Types.PhoneType.WORK:
+                            Console.Write("  Work phone #: ");
+                            break;
+                    }
+                    Console.WriteLine(phoneNumber.Number);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Entry point - loads the addressbook and then displays it.
+        /// </summary>
+        public static int Main(string[] args)
+        {
+            if (args.Length != 1)
+            {
+                Console.Error.WriteLine("Usage:  ListPeople ADDRESS_BOOK_FILE");
+                return 1;
+            }
+
+            if (!File.Exists(args[0]))
+            {
+                Console.WriteLine("{0} doesn't exist. Add a person to create the file first.", args[0]);
+                return 0;
+            }
+
+            // Read the existing address book.
+            using (Stream stream = File.OpenRead(args[0]))
+            {
+                AddressBook addressBook = AddressBook.ParseFrom(stream);
+                Print(addressBook);
+            }
+            return 0;
+        }
+    }
+}

+ 98 - 88
src/AddressBook/Program.cs

@@ -1,89 +1,99 @@
-#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.Examples.AddressBook
-{
-  /// <summary>
-  /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour
-  /// to individual actions. Each action has its own Main method, so that it can be used as an
-  /// invidual complete program.
-  /// </summary>
-  class Program {
-    static int Main(string[] args) {
-      if (args.Length > 1) {
-        Console.Error.WriteLine("Usage: AddressBook [file]");
-        Console.Error.WriteLine("If the filename isn't specified, \"addressbook.data\" is used instead.");
-        return 1;
-      }
-      string addressBookFile = args.Length > 0 ? args[0] : "addressbook.data";
-
-      bool stopping = false;
-      while (!stopping) {
-        Console.WriteLine("Options:");
-        Console.WriteLine("  L: List contents");
-        Console.WriteLine("  A: Add new person");
-        Console.WriteLine("  Q: Quit");
-        Console.Write("Action? ");
-        Console.Out.Flush();
-        char choice = Console.ReadKey().KeyChar;
-        Console.WriteLine();
-        try {
-          switch (choice) {
-            case 'A':
-            case 'a':
-              AddPerson.Main(new string[] { addressBookFile });
-              break;
-            case 'L':
-            case 'l':
-              ListPeople.Main(new string[] { addressBookFile });
-              break;
-            case 'Q':
-            case 'q':
-              stopping = true;
-              break;
-            default:
-              Console.WriteLine("Unknown option: {0}", choice);
-              break;
-          }
-        } catch (Exception e) {
-          Console.WriteLine("Exception executing action: {0}", e);
-        }
-        Console.WriteLine();
-      } 
-      return 0;
-    }
-  }
+#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.Examples.AddressBook
+{
+    /// <summary>
+    /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour
+    /// to individual actions. Each action has its own Main method, so that it can be used as an
+    /// invidual complete program.
+    /// </summary>
+    internal class Program
+    {
+        private static int Main(string[] args)
+        {
+            if (args.Length > 1)
+            {
+                Console.Error.WriteLine("Usage: AddressBook [file]");
+                Console.Error.WriteLine("If the filename isn't specified, \"addressbook.data\" is used instead.");
+                return 1;
+            }
+            string addressBookFile = args.Length > 0 ? args[0] : "addressbook.data";
+
+            bool stopping = false;
+            while (!stopping)
+            {
+                Console.WriteLine("Options:");
+                Console.WriteLine("  L: List contents");
+                Console.WriteLine("  A: Add new person");
+                Console.WriteLine("  Q: Quit");
+                Console.Write("Action? ");
+                Console.Out.Flush();
+                char choice = Console.ReadKey().KeyChar;
+                Console.WriteLine();
+                try
+                {
+                    switch (choice)
+                    {
+                        case 'A':
+                        case 'a':
+                            AddPerson.Main(new string[] {addressBookFile});
+                            break;
+                        case 'L':
+                        case 'l':
+                            ListPeople.Main(new string[] {addressBookFile});
+                            break;
+                        case 'Q':
+                        case 'q':
+                            stopping = true;
+                            break;
+                        default:
+                            Console.WriteLine("Unknown option: {0}", choice);
+                            break;
+                    }
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine("Exception executing action: {0}", e);
+                }
+                Console.WriteLine();
+            }
+            return 0;
+        }
+    }
 }

+ 39 - 35
src/AddressBook/Properties/AssemblyInfo.cs

@@ -1,35 +1,39 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("AddressBook")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("AddressBook")]
-[assembly: AssemblyCopyright("Copyright ©  2008")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("57123e6e-28d1-4b9e-80a5-5e720df8035a")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyFileVersion("2.3.0.277")]
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("AddressBook")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("AddressBook")]
+[assembly: AssemblyCopyright("Copyright ©  2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("57123e6e-28d1-4b9e-80a5-5e720df8035a")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("2.3.0.277")]
+
+[assembly: AssemblyVersion("2.3.0.277")]
+[assembly: AssemblyFileVersion("2.3.0.277")]

+ 35 - 35
src/AddressBook/SampleUsage.cs

@@ -3,42 +3,42 @@ using System.IO;
 
 namespace Google.ProtocolBuffers.Examples.AddressBook
 {
-    class SampleUsage
-{
-    static void Main()
+    internal class SampleUsage
     {
-        byte[] bytes;
-        //Create a builder to start building a message
-        Person.Builder newContact = Person.CreateBuilder();
-        //Set the primitive properties
-        newContact.SetId(1)
-                  .SetName("Foo")
-                  .SetEmail("foo@bar");
-        //Now add an item to a list (repeating) field
-        newContact.AddPhone(
-            //Create the child message inline
-            Person.Types.PhoneNumber.CreateBuilder().SetNumber("555-1212").Build()
-            );
-        //Now build the final message:
-        Person person = newContact.Build();
-        //The builder is no longer valid (at least not now, scheduled for 2.4):
-        newContact = null;
-        using(MemoryStream stream = new MemoryStream())
+        private static void Main()
         {
-            //Save the person to a stream
-            person.WriteTo(stream);
-            bytes = stream.ToArray();
-        }
-        //Create another builder, merge the byte[], and build the message:
-        Person copy = Person.CreateBuilder().MergeFrom(bytes).Build();
+            byte[] bytes;
+            //Create a builder to start building a message
+            Person.Builder newContact = Person.CreateBuilder();
+            //Set the primitive properties
+            newContact.SetId(1)
+                .SetName("Foo")
+                .SetEmail("foo@bar");
+            //Now add an item to a list (repeating) field
+            newContact.AddPhone(
+                //Create the child message inline
+                Person.Types.PhoneNumber.CreateBuilder().SetNumber("555-1212").Build()
+                );
+            //Now build the final message:
+            Person person = newContact.Build();
+            //The builder is no longer valid (at least not now, scheduled for 2.4):
+            newContact = null;
+            using (MemoryStream stream = new MemoryStream())
+            {
+                //Save the person to a stream
+                person.WriteTo(stream);
+                bytes = stream.ToArray();
+            }
+            //Create another builder, merge the byte[], and build the message:
+            Person copy = Person.CreateBuilder().MergeFrom(bytes).Build();
 
-        //A more streamlined approach might look like this:
-        bytes = AddressBook.CreateBuilder().AddPerson(copy).Build().ToByteArray();
-        //And read the address book back again
-        AddressBook restored = AddressBook.CreateBuilder().MergeFrom(bytes).Build();
-        //The message performs a deep-comparison on equality:
-        if(restored.PersonCount != 1 || !person.Equals(restored.PersonList[0]))
-            throw new ApplicationException("There is a bad person in here!");
+            //A more streamlined approach might look like this:
+            bytes = AddressBook.CreateBuilder().AddPerson(copy).Build().ToByteArray();
+            //And read the address book back again
+            AddressBook restored = AddressBook.CreateBuilder().MergeFrom(bytes).Build();
+            //The message performs a deep-comparison on equality:
+            if (restored.PersonCount != 1 || !person.Equals(restored.PersonList[0]))
+                throw new ApplicationException("There is a bad person in here!");
+        }
     }
-}
-}
+}

+ 168 - 144
src/ProtoBench/Program.cs

@@ -1,145 +1,169 @@
-#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.Diagnostics;
-using System.IO;
-
-namespace Google.ProtocolBuffers.ProtoBench
-{
-  /// <summary>
-  /// Simple benchmarking of arbitrary messages.
-  /// </summary>
-  public sealed class Program {
-
-    private static readonly TimeSpan MinSampleTime = TimeSpan.FromSeconds(2);
-    private static readonly TimeSpan TargetTime = TimeSpan.FromSeconds(30);
-
-    // Avoid a .NET 3.5 dependency
-    delegate void Action();
-
-    public static int Main(string[] args) {
-      if (args.Length < 2 || (args.Length % 2) != 0) {
-        Console.Error.WriteLine("Usage: ProtoBench <descriptor type name> <input data>");
-        Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,");
-        Console.Error.WriteLine("including assembly - e.g. Google.ProtocolBuffers.BenchmarkProtos.Message1,ProtoBench");
-        Console.Error.WriteLine("(You can specify multiple pairs of descriptor type name and input data.)");
-        return 1;
-      }
-      bool success = true;
-      for (int i = 0; i < args.Length; i += 2) {
-        success &= RunTest(args[i], args[i + 1]);
-      }
-      return success ? 0 : 1;
-    }
-
-    /// <summary>
-    /// Runs a single test. Error messages are displayed to Console.Error, and the return value indicates
-    /// general success/failure.
-    /// </summary>
-    public static bool RunTest(string typeName, string file) {
-      Console.WriteLine("Benchmarking {0} with file {1}", typeName, file);
-      IMessage defaultMessage;
-      try {
-        defaultMessage = MessageUtil.GetDefaultMessage(typeName);
-      } catch (ArgumentException e) {
-        Console.Error.WriteLine(e.Message);
-        return false;
-      }
-      try {
-        byte[] inputData = File.ReadAllBytes(file);
-        MemoryStream inputStream = new MemoryStream(inputData);
-        ByteString inputString = ByteString.CopyFrom(inputData);
-        IMessage sampleMessage = defaultMessage.WeakCreateBuilderForType().WeakMergeFrom(inputString).WeakBuild();
-        Benchmark("Serialize to byte string", inputData.Length, () => sampleMessage.ToByteString());
-        Benchmark("Serialize to byte array", inputData.Length, () => sampleMessage.ToByteArray());
-        Benchmark("Serialize to memory stream", inputData.Length, () => sampleMessage.WriteTo(new MemoryStream()));
-        Benchmark("Deserialize from byte string", inputData.Length,
-          () => defaultMessage.WeakCreateBuilderForType()
-                              .WeakMergeFrom(inputString)
-                              .WeakBuild()
-        );
-        Benchmark("Deserialize from byte array", inputData.Length, 
-          () => defaultMessage.WeakCreateBuilderForType()
-                              .WeakMergeFrom(CodedInputStream.CreateInstance(inputData))
-                              .WeakBuild()
-        );
-        Benchmark("Deserialize from memory stream", inputData.Length, () => {
-          inputStream.Position = 0;
-          defaultMessage.WeakCreateBuilderForType()
-            .WeakMergeFrom(CodedInputStream.CreateInstance(inputStream))
-            .WeakBuild();
-        });
-        Console.WriteLine();
-        return true;
-      } catch (Exception e) {
-        Console.Error.WriteLine("Error: {0}", e.Message);
-        Console.Error.WriteLine();
-        Console.Error.WriteLine("Detailed exception information: {0}", e);
-        return false;
-      }
-    }
-
-    private static void Benchmark(string name, long dataSize, Action action) {
-      // Make sure it's JITted
-      action();
-      // Run it progressively more times until we've got a reasonable sample
-
-      int iterations = 1;
-      TimeSpan elapsed = TimeAction(action, iterations);
-      while (elapsed < MinSampleTime) {
-        iterations *= 2;
-        elapsed = TimeAction(action, iterations);
-      }
-      // Upscale the sample to the target time. Do this in floating point arithmetic
-      // to avoid overflow issues.
-      iterations = (int) ((TargetTime.Ticks / (double)elapsed.Ticks) * iterations);
-      elapsed = TimeAction(action, iterations);
-      Console.WriteLine("{0}: {1} iterations in {2:f3}s; {3:f3}MB/s",
-                        name, iterations, elapsed.TotalSeconds,
-                        (iterations * dataSize) / (elapsed.TotalSeconds * 1024 * 1024));
-    }
-
-    private static TimeSpan TimeAction(Action action, int iterations) {
-      GC.Collect();
-      GC.WaitForPendingFinalizers();
-      Stopwatch sw = Stopwatch.StartNew();
-      for (int i = 0; i < iterations; i++) {
-        action();
-      }
-      sw.Stop();
-      return sw.Elapsed;
-    }
-  }
+#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.Diagnostics;
+using System.IO;
+
+namespace Google.ProtocolBuffers.ProtoBench
+{
+    /// <summary>
+    /// Simple benchmarking of arbitrary messages.
+    /// </summary>
+    public sealed class Program
+    {
+        private static readonly TimeSpan MinSampleTime = TimeSpan.FromSeconds(2);
+        private static readonly TimeSpan TargetTime = TimeSpan.FromSeconds(30);
+
+        // Avoid a .NET 3.5 dependency
+        private delegate void Action();
+
+        public static int Main(string[] args)
+        {
+            if (args.Length < 2 || (args.Length%2) != 0)
+            {
+                Console.Error.WriteLine("Usage: ProtoBench <descriptor type name> <input data>");
+                Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,");
+                Console.Error.WriteLine(
+                    "including assembly - e.g. Google.ProtocolBuffers.BenchmarkProtos.Message1,ProtoBench");
+                Console.Error.WriteLine("(You can specify multiple pairs of descriptor type name and input data.)");
+                return 1;
+            }
+            bool success = true;
+            for (int i = 0; i < args.Length; i += 2)
+            {
+                success &= RunTest(args[i], args[i + 1]);
+            }
+            return success ? 0 : 1;
+        }
+
+        /// <summary>
+        /// Runs a single test. Error messages are displayed to Console.Error, and the return value indicates
+        /// general success/failure.
+        /// </summary>
+        public static bool RunTest(string typeName, string file)
+        {
+            Console.WriteLine("Benchmarking {0} with file {1}", typeName, file);
+            IMessage defaultMessage;
+            try
+            {
+                defaultMessage = MessageUtil.GetDefaultMessage(typeName);
+            }
+            catch (ArgumentException e)
+            {
+                Console.Error.WriteLine(e.Message);
+                return false;
+            }
+            try
+            {
+                byte[] inputData = File.ReadAllBytes(file);
+                MemoryStream inputStream = new MemoryStream(inputData);
+                ByteString inputString = ByteString.CopyFrom(inputData);
+                IMessage sampleMessage =
+                    defaultMessage.WeakCreateBuilderForType().WeakMergeFrom(inputString).WeakBuild();
+                Benchmark("Serialize to byte string", inputData.Length, () => sampleMessage.ToByteString());
+                Benchmark("Serialize to byte array", inputData.Length, () => sampleMessage.ToByteArray());
+                Benchmark("Serialize to memory stream", inputData.Length,
+                          () => sampleMessage.WriteTo(new MemoryStream()));
+                Benchmark("Deserialize from byte string", inputData.Length,
+                          () => defaultMessage.WeakCreateBuilderForType()
+                                    .WeakMergeFrom(inputString)
+                                    .WeakBuild()
+                    );
+                Benchmark("Deserialize from byte array", inputData.Length,
+                          () => defaultMessage.WeakCreateBuilderForType()
+                                    .WeakMergeFrom(CodedInputStream.CreateInstance(inputData))
+                                    .WeakBuild()
+                    );
+                Benchmark("Deserialize from memory stream", inputData.Length, () =>
+                                                                                  {
+                                                                                      inputStream.Position = 0;
+                                                                                      defaultMessage.
+                                                                                          WeakCreateBuilderForType()
+                                                                                          .WeakMergeFrom(
+                                                                                              CodedInputStream.
+                                                                                                  CreateInstance(
+                                                                                                      inputStream))
+                                                                                          .WeakBuild();
+                                                                                  });
+                Console.WriteLine();
+                return true;
+            }
+            catch (Exception e)
+            {
+                Console.Error.WriteLine("Error: {0}", e.Message);
+                Console.Error.WriteLine();
+                Console.Error.WriteLine("Detailed exception information: {0}", e);
+                return false;
+            }
+        }
+
+        private static void Benchmark(string name, long dataSize, Action action)
+        {
+            // Make sure it's JITted
+            action();
+            // Run it progressively more times until we've got a reasonable sample
+
+            int iterations = 1;
+            TimeSpan elapsed = TimeAction(action, iterations);
+            while (elapsed < MinSampleTime)
+            {
+                iterations *= 2;
+                elapsed = TimeAction(action, iterations);
+            }
+            // Upscale the sample to the target time. Do this in floating point arithmetic
+            // to avoid overflow issues.
+            iterations = (int) ((TargetTime.Ticks/(double) elapsed.Ticks)*iterations);
+            elapsed = TimeAction(action, iterations);
+            Console.WriteLine("{0}: {1} iterations in {2:f3}s; {3:f3}MB/s",
+                              name, iterations, elapsed.TotalSeconds,
+                              (iterations*dataSize)/(elapsed.TotalSeconds*1024*1024));
+        }
+
+        private static TimeSpan TimeAction(Action action, int iterations)
+        {
+            GC.Collect();
+            GC.WaitForPendingFinalizers();
+            Stopwatch sw = Stopwatch.StartNew();
+            for (int i = 0; i < iterations; i++)
+            {
+                action();
+            }
+            sw.Stop();
+            return sw.Elapsed;
+        }
+    }
 }

+ 42 - 39
src/ProtoBench/Properties/AssemblyInfo.cs

@@ -1,39 +1,42 @@
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ProtoBench")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ProtoBench")]
-[assembly: AssemblyCopyright("Copyright ©  2009")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-[assembly: CLSCompliant(true)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("0f515d09-9a6c-49ec-8500-14a5303ebadf")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyFileVersion("2.3.0.277")]
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("ProtoBench")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ProtoBench")]
+[assembly: AssemblyCopyright("Copyright ©  2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+[assembly: CLSCompliant(true)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("0f515d09-9a6c-49ec-8500-14a5303ebadf")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("2.3.0.277")]
+
+[assembly: AssemblyVersion("2.3.0.277")]
+[assembly: AssemblyFileVersion("2.3.0.277")]

+ 87 - 75
src/ProtoDump/Program.cs

@@ -1,76 +1,88 @@
-#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;
-
-namespace Google.ProtocolBuffers.ProtoDump
-{
-  /// <summary>
-  /// Small utility to load a binary message and dump it in text form
-  /// </summary>
-  class Program {
-    static int Main(string[] args) {
-      if (args.Length != 2) {
-        Console.Error.WriteLine("Usage: ProtoDump <descriptor type name> <input data>");
-        Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,");
-        Console.Error.WriteLine("including assembly e.g. ProjectNamespace.Message,Company.Project");
-        return 1;
-      }
-      IMessage defaultMessage;
-      try {
-        defaultMessage = MessageUtil.GetDefaultMessage(args[0]);
-      } catch (ArgumentException e) {
-        Console.Error.WriteLine(e.Message);
-        return 1;
-      }
-      try {
-        IBuilder builder = defaultMessage.WeakCreateBuilderForType();
-        if (builder == null) {
-          Console.Error.WriteLine("Unable to create builder");
-          return 1;
-        }
-        byte[] inputData = File.ReadAllBytes(args[1]);
-        builder.WeakMergeFrom(ByteString.CopyFrom(inputData));
-        Console.WriteLine(TextFormat.PrintToString(builder.WeakBuild()));
-        return 0;
-      } catch (Exception e) {
-        Console.Error.WriteLine("Error: {0}", e.Message);
-        Console.Error.WriteLine();
-        Console.Error.WriteLine("Detailed exception information: {0}", e);
-        return 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.IO;
+
+namespace Google.ProtocolBuffers.ProtoDump
+{
+    /// <summary>
+    /// Small utility to load a binary message and dump it in text form
+    /// </summary>
+    internal class Program
+    {
+        private static int Main(string[] args)
+        {
+            if (args.Length != 2)
+            {
+                Console.Error.WriteLine("Usage: ProtoDump <descriptor type name> <input data>");
+                Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,");
+                Console.Error.WriteLine("including assembly e.g. ProjectNamespace.Message,Company.Project");
+                return 1;
+            }
+            IMessage defaultMessage;
+            try
+            {
+                defaultMessage = MessageUtil.GetDefaultMessage(args[0]);
+            }
+            catch (ArgumentException e)
+            {
+                Console.Error.WriteLine(e.Message);
+                return 1;
+            }
+            try
+            {
+                IBuilder builder = defaultMessage.WeakCreateBuilderForType();
+                if (builder == null)
+                {
+                    Console.Error.WriteLine("Unable to create builder");
+                    return 1;
+                }
+                byte[] inputData = File.ReadAllBytes(args[1]);
+                builder.WeakMergeFrom(ByteString.CopyFrom(inputData));
+                Console.WriteLine(TextFormat.PrintToString(builder.WeakBuild()));
+                return 0;
+            }
+            catch (Exception e)
+            {
+                Console.Error.WriteLine("Error: {0}", e.Message);
+                Console.Error.WriteLine();
+                Console.Error.WriteLine("Detailed exception information: {0}", e);
+                return 1;
+            }
+        }
+    }
 }

+ 40 - 36
src/ProtoDump/Properties/AssemblyInfo.cs

@@ -1,36 +1,40 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ProtoDump")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ProtoDump")]
-[assembly: AssemblyCopyright("Copyright ©  2009")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("fed7572b-d747-4704-a6da-6c3c61088346")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyFileVersion("2.3.0.277")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("ProtoDump")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ProtoDump")]
+[assembly: AssemblyCopyright("Copyright ©  2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("fed7572b-d747-4704-a6da-6c3c61088346")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("2.3.0.277")]
+
+[assembly: AssemblyVersion("2.3.0.277")]
+[assembly: AssemblyFileVersion("2.3.0.277")]

+ 5 - 3
src/ProtoDump/app.config

@@ -1,3 +1,5 @@
-<?xml version="1.0"?>
-<configuration>
-	<startup/></configuration>
+<?xml version="1.0"?>
+
+<configuration>
+  <startup />
+</configuration>

+ 149 - 125
src/ProtoGen.Test/DependencyResolutionTest.cs

@@ -1,126 +1,150 @@
-#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.Collections.Generic;
-using Google.ProtocolBuffers.DescriptorProtos;
-using Google.ProtocolBuffers.Descriptors;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  /// <summary>
-  /// Tests for the dependency resolution in Generator.
-  /// </summary>
-  [TestFixture]
-  public class DependencyResolutionTest {
-
-    [Test]
-    public void TwoDistinctFiles() {
-      FileDescriptorProto first = new FileDescriptorProto.Builder { Name="First" }.Build();
-      FileDescriptorProto second = new FileDescriptorProto.Builder { Name="Second" }.Build();
-      FileDescriptorSet set = new FileDescriptorSet { FileList = { first, second } };
-
-      IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
-      Assert.AreEqual(2, converted.Count);
-      Assert.AreEqual("First", converted[0].Name);
-      Assert.AreEqual(0, converted[0].Dependencies.Count);
-      Assert.AreEqual("Second", converted[1].Name);
-      Assert.AreEqual(0, converted[1].Dependencies.Count);
-    }
-
-    [Test]
-    public void FirstDependsOnSecond() {
-      FileDescriptorProto first = new FileDescriptorProto.Builder { Name = "First", DependencyList = {"Second"} }.Build();
-      FileDescriptorProto second = new FileDescriptorProto.Builder { Name = "Second" }.Build();
-      FileDescriptorSet set = new FileDescriptorSet { FileList = { first, second } };
-      IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
-      Assert.AreEqual(2, converted.Count);
-      Assert.AreEqual("First", converted[0].Name);
-      Assert.AreEqual(1, converted[0].Dependencies.Count);
-      Assert.AreEqual(converted[1], converted[0].Dependencies[0]);
-      Assert.AreEqual("Second", converted[1].Name);
-      Assert.AreEqual(0, converted[1].Dependencies.Count);
-    }
-
-    [Test]
-    public void SecondDependsOnFirst() {
-      FileDescriptorProto first = new FileDescriptorProto.Builder { Name = "First" }.Build();
-      FileDescriptorProto second = new FileDescriptorProto.Builder { Name = "Second", DependencyList = {"First"} }.Build();
-      FileDescriptorSet set = new FileDescriptorSet { FileList = { first, second } };
-      IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
-      Assert.AreEqual(2, converted.Count);
-      Assert.AreEqual("First", converted[0].Name);
-      Assert.AreEqual(0, converted[0].Dependencies.Count);
-      Assert.AreEqual("Second", converted[1].Name);
-      Assert.AreEqual(1, converted[1].Dependencies.Count);
-      Assert.AreEqual(converted[0], converted[1].Dependencies[0]);
-    }
-
-    [Test]
-    public void CircularDependency() {
-      FileDescriptorProto first = new FileDescriptorProto.Builder { Name = "First", DependencyList = { "Second" } }.Build();
-      FileDescriptorProto second = new FileDescriptorProto.Builder { Name = "Second", DependencyList = { "First" } }.Build();
-      FileDescriptorSet set = new FileDescriptorSet { FileList = { first, second } };
-      try {
-        Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
-        Assert.Fail("Expected exception");
-      } catch (DependencyResolutionException) {
-        // Expected
-      }
-    }
-
-    [Test]
-    public void MissingDependency() {
-      FileDescriptorProto first = new FileDescriptorProto.Builder { Name = "First", DependencyList = { "Second" } }.Build();
-      FileDescriptorSet set = new FileDescriptorSet { FileList = { first } };
-      try {
-        Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
-        Assert.Fail("Expected exception");
-      } catch (DependencyResolutionException) {
-        // Expected
-      }
-    }
-
-    [Test]
-    public void SelfDependency() {
-      FileDescriptorProto first = new FileDescriptorProto.Builder { Name = "First", DependencyList = { "First" } }.Build();
-      FileDescriptorSet set = new FileDescriptorSet { FileList = { first } };
-      try {
-        Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
-        Assert.Fail("Expected exception");
-      } catch (DependencyResolutionException) {
-        // Expected
-      }
-    }
-  }
+#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.Collections.Generic;
+using Google.ProtocolBuffers.DescriptorProtos;
+using Google.ProtocolBuffers.Descriptors;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// Tests for the dependency resolution in Generator.
+    /// </summary>
+    [TestFixture]
+    public class DependencyResolutionTest
+    {
+        [Test]
+        public void TwoDistinctFiles()
+        {
+            FileDescriptorProto first = new FileDescriptorProto.Builder {Name = "First"}.Build();
+            FileDescriptorProto second = new FileDescriptorProto.Builder {Name = "Second"}.Build();
+            FileDescriptorSet set = new FileDescriptorSet {FileList = {first, second}};
+
+            IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
+            Assert.AreEqual(2, converted.Count);
+            Assert.AreEqual("First", converted[0].Name);
+            Assert.AreEqual(0, converted[0].Dependencies.Count);
+            Assert.AreEqual("Second", converted[1].Name);
+            Assert.AreEqual(0, converted[1].Dependencies.Count);
+        }
+
+        [Test]
+        public void FirstDependsOnSecond()
+        {
+            FileDescriptorProto first =
+                new FileDescriptorProto.Builder {Name = "First", DependencyList = {"Second"}}.Build();
+            FileDescriptorProto second = new FileDescriptorProto.Builder {Name = "Second"}.Build();
+            FileDescriptorSet set = new FileDescriptorSet {FileList = {first, second}};
+            IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
+            Assert.AreEqual(2, converted.Count);
+            Assert.AreEqual("First", converted[0].Name);
+            Assert.AreEqual(1, converted[0].Dependencies.Count);
+            Assert.AreEqual(converted[1], converted[0].Dependencies[0]);
+            Assert.AreEqual("Second", converted[1].Name);
+            Assert.AreEqual(0, converted[1].Dependencies.Count);
+        }
+
+        [Test]
+        public void SecondDependsOnFirst()
+        {
+            FileDescriptorProto first = new FileDescriptorProto.Builder {Name = "First"}.Build();
+            FileDescriptorProto second =
+                new FileDescriptorProto.Builder {Name = "Second", DependencyList = {"First"}}.Build();
+            FileDescriptorSet set = new FileDescriptorSet {FileList = {first, second}};
+            IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
+            Assert.AreEqual(2, converted.Count);
+            Assert.AreEqual("First", converted[0].Name);
+            Assert.AreEqual(0, converted[0].Dependencies.Count);
+            Assert.AreEqual("Second", converted[1].Name);
+            Assert.AreEqual(1, converted[1].Dependencies.Count);
+            Assert.AreEqual(converted[0], converted[1].Dependencies[0]);
+        }
+
+        [Test]
+        public void CircularDependency()
+        {
+            FileDescriptorProto first =
+                new FileDescriptorProto.Builder {Name = "First", DependencyList = {"Second"}}.Build();
+            FileDescriptorProto second =
+                new FileDescriptorProto.Builder {Name = "Second", DependencyList = {"First"}}.Build();
+            FileDescriptorSet set = new FileDescriptorSet {FileList = {first, second}};
+            try
+            {
+                Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
+                Assert.Fail("Expected exception");
+            }
+            catch (DependencyResolutionException)
+            {
+                // Expected
+            }
+        }
+
+        [Test]
+        public void MissingDependency()
+        {
+            FileDescriptorProto first =
+                new FileDescriptorProto.Builder {Name = "First", DependencyList = {"Second"}}.Build();
+            FileDescriptorSet set = new FileDescriptorSet {FileList = {first}};
+            try
+            {
+                Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
+                Assert.Fail("Expected exception");
+            }
+            catch (DependencyResolutionException)
+            {
+                // Expected
+            }
+        }
+
+        [Test]
+        public void SelfDependency()
+        {
+            FileDescriptorProto first =
+                new FileDescriptorProto.Builder {Name = "First", DependencyList = {"First"}}.Build();
+            FileDescriptorSet set = new FileDescriptorSet {FileList = {first}};
+            try
+            {
+                Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
+                Assert.Fail("Expected exception");
+            }
+            catch (DependencyResolutionException)
+            {
+                // Expected
+            }
+        }
+    }
 }

+ 40 - 36
src/ProtoGen.Test/Properties/AssemblyInfo.cs

@@ -1,36 +1,40 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ProtoGen.Test")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ProtoGen.Test")]
-[assembly: AssemblyCopyright("Copyright ©  2008")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("40720ee3-2d15-4271-8c42-8f9cfd01b52f")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyFileVersion("2.3.0.277")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("ProtoGen.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ProtoGen.Test")]
+[assembly: AssemblyCopyright("Copyright ©  2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("40720ee3-2d15-4271-8c42-8f9cfd01b52f")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("2.3.0.277")]
+
+[assembly: AssemblyVersion("2.3.0.277")]
+[assembly: AssemblyFileVersion("2.3.0.277")]

+ 59 - 54
src/ProtoGen.Test/TempFile.cs

@@ -1,54 +1,59 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Google.ProtocolBuffers.ProtoGen
-{
-    class ProtoFile : TempFile
-    {
-        public ProtoFile(string filename, string contents)
-            : base(filename, contents)
-        {
-        }
-    }
-    class TempFile : IDisposable
-    {
-        private string tempFile;
-
-        public static TempFile Attach(string path) 
-        {
-            return new TempFile(path, null);
-        }
-
-        protected TempFile(string filename, string contents) {
-            tempFile = filename;
-            if (contents != null)
-            {
-                File.WriteAllText(tempFile, contents, new UTF8Encoding(false));
-            }
-        }
-
-        public TempFile(string contents)
-            : this(Path.GetTempFileName(), contents)
-        {
-        }
-
-        public string TempPath { get { return tempFile; } }
-
-        public void ChangeExtension(string ext)
-        {
-            string newFile = Path.ChangeExtension(tempFile, ext);
-            File.Move(tempFile, newFile);
-            tempFile = newFile;
-        }
-
-        public void Dispose()
-        {
-            if (File.Exists(tempFile))
-            {
-                File.Delete(tempFile);
-            }
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class ProtoFile : TempFile
+    {
+        public ProtoFile(string filename, string contents)
+            : base(filename, contents)
+        {
+        }
+    }
+
+    internal class TempFile : IDisposable
+    {
+        private string tempFile;
+
+        public static TempFile Attach(string path)
+        {
+            return new TempFile(path, null);
+        }
+
+        protected TempFile(string filename, string contents)
+        {
+            tempFile = filename;
+            if (contents != null)
+            {
+                File.WriteAllText(tempFile, contents, new UTF8Encoding(false));
+            }
+        }
+
+        public TempFile(string contents)
+            : this(Path.GetTempFileName(), contents)
+        {
+        }
+
+        public string TempPath
+        {
+            get { return tempFile; }
+        }
+
+        public void ChangeExtension(string ext)
+        {
+            string newFile = Path.ChangeExtension(tempFile, ext);
+            File.Move(tempFile, newFile);
+            tempFile = newFile;
+        }
+
+        public void Dispose()
+        {
+            if (File.Exists(tempFile))
+            {
+                File.Delete(tempFile);
+            }
+        }
+    }
+}

+ 677 - 610
src/ProtoGen.Test/TestPreprocessing.cs

@@ -1,610 +1,677 @@
-#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.Diagnostics;
-using System.IO;
-using System.Reflection;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers.ProtoGen
-{
-    [TestFixture]
-    [Category("Preprocessor")]
-    public partial class TestPreprocessing
-    {
-        private static readonly string TempPath = Path.Combine(Path.GetTempPath(), "proto-gen-test");
-        private const string DefaultProto = @"
-package nunit.simple;
-// Test a very simple message.
-message MyMessage {
-  optional string name = 1;
-}";
-
-        #region TestFixture SetUp/TearDown
-        private static readonly string OriginalWorkingDirectory = Environment.CurrentDirectory;
-        [TestFixtureSetUp]
-        public virtual void Setup()
-        {
-            Teardown();
-            Directory.CreateDirectory(TempPath);
-            Environment.CurrentDirectory = TempPath;
-        }
-
-        [TestFixtureTearDown]
-        public virtual void Teardown()
-        {
-            Environment.CurrentDirectory = OriginalWorkingDirectory;
-            if (Directory.Exists(TempPath))
-            {
-                Directory.Delete(TempPath, true);
-            }
-        }
-        #endregion
-        #region Helper Methods RunProtoGen / RunCsc
-        void RunProtoGen(int expect, params string[] args)
-        {
-            TextWriter tout = Console.Out, terr = Console.Error;
-            StringWriter temp = new StringWriter();
-            Console.SetOut(temp);
-            Console.SetError(temp);
-            try
-            {
-                Assert.AreEqual(expect, ProgramPreprocess.Run(args), "ProtoGen Failed: {0}", temp);
-            }
-            finally
-            {
-                Console.SetOut(tout);
-                Console.SetError(terr);
-            }
-        }
-
-        private Assembly RunCsc(int expect, params string[] sources)
-        {
-            using (TempFile tempDll = new TempFile(String.Empty))
-            {
-                tempDll.ChangeExtension(".dll");
-                List<string> args = new List<string>();
-                args.Add("/nologo");
-                args.Add("/target:library");
-                args.Add("/debug-");
-                args.Add(String.Format(@"""/out:{0}""", tempDll.TempPath));
-                args.Add("/r:System.dll");
-                args.Add(String.Format(@"""/r:{0}""", typeof (Google.ProtocolBuffers.DescriptorProtos.DescriptorProto).Assembly.Location));
-                args.AddRange(sources);
-
-                string exe = Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), "csc.exe");
-                ProcessStartInfo psi = new ProcessStartInfo(exe);
-                psi.CreateNoWindow = true;
-                psi.UseShellExecute = false;
-                psi.RedirectStandardOutput = true;
-                psi.RedirectStandardError = true;
-                psi.Arguments = string.Join(" ", args.ToArray());
-                Process p = Process.Start(psi);
-                p.WaitForExit();
-                string errorText = p.StandardOutput.ReadToEnd() + p.StandardError.ReadToEnd();
-                Assert.AreEqual(expect, p.ExitCode, "CSC.exe Failed: {0}", errorText);
-
-                Assembly asm = null;
-                if (p.ExitCode == 0)
-                {
-                    byte[] allbytes = File.ReadAllBytes(tempDll.TempPath);
-                    asm = Assembly.Load(allbytes);
-
-                    foreach (Type t in asm.GetTypes())
-                    {
-                        Debug.WriteLine(t.FullName, asm.FullName);
-                    }
-                }
-                return asm;
-            }
-        }
-        #endregion
-
-        // *******************************************************************
-        // The following tests excercise options for protogen.exe
-        // *******************************************************************
-
-        [Test]
-        public void TestProtoFile()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(0, proto.TempPath);
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithConflictingType()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", @"
-package nunit.simple;
-// Test a very simple message.
-message " + test + @" {
-  optional string name = 1;
-} "))
-            {
-                RunProtoGen(0, proto.TempPath);
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple." + test, true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple.Proto." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithNamespace()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(0, proto.TempPath, "-namespace:MyNewNamespace");
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("MyNewNamespace.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("MyNewNamespace." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithUmbrellaClassName()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach("MyUmbrellaClassname.cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(0, proto.TempPath, "/umbrella_classname=MyUmbrellaClassname");
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple.MyUmbrellaClassname", true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithNestedClass()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(0, proto.TempPath, "-nest_classes:true");
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple." + test + "+MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithExpandedNsDirectories()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(@"nunit\simple\" + test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(0, proto.TempPath, "-expand_namespace_directories:true");
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileDisablingClsComplianceFlags()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", @"
-package nunit.simple;
-// Test a very simple message.
-message MyMessage {
-  optional uint32 name = 1;
-} "))
-            {
-                //CS3021: Warning as Error: xx does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute
-                RunProtoGen(0, proto.TempPath);
-                RunCsc(1, source.TempPath, "/warnaserror+");
-                //Now we know it fails, make it pass by turning off cls_compliance generation
-                RunProtoGen(0, proto.TempPath, "-cls_compliance:false");
-                Assembly a = RunCsc(0, source.TempPath, "/warnaserror+");
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithNewExtension()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".Generated.cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(0, proto.TempPath, "-file_extension:.Generated.cs");
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithUmbrellaNamespace()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(0, proto.TempPath, "-umbrella_namespace:MyUmbrella.Namespace");
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple.MyUmbrella.Namespace." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithIgnoredUmbrellaNamespaceDueToNesting()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(0, proto.TempPath, "-nest_classes:true", "-umbrella_namespace:MyUmbrella.Namespace");
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple." + test + "+MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithExplicitEmptyUmbrellaNamespace()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", @"
-package nunit.simple;
-// Test a very simple message.
-message " + test + @" {
-  optional string name = 1;
-} "))
-            {
-                //Forces the umbrella class to not use a namespace even if a collision with a type is detected.
-                RunProtoGen(0, proto.TempPath, "-umbrella_namespace:");
-                //error CS0441: 'nunit.simple.TestProtoFileWithExplicitEmptyUmbrellaNamespace': a class cannot be both static and sealed
-                RunCsc(1, source.TempPath);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithNewOutputFolder()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(@"generated-code\" + test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                RunProtoGen(1, proto.TempPath, "-output_directory:generated-code");
-                Directory.CreateDirectory("generated-code");
-                RunProtoGen(0, proto.TempPath, "-output_directory:generated-code");
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileAndIgnoreGoogleProtobuf()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", @"
-import ""google/protobuf/csharp_options.proto"";
-option (google.protobuf.csharp_file_options).namespace = ""MyNewNamespace"";
-" + DefaultProto))
-            {
-                string google = Path.Combine(TempPath, "google\\protobuf");
-                Directory.CreateDirectory(google);
-                foreach (string file in Directory.GetFiles(Path.Combine(OriginalWorkingDirectory, "google\\protobuf")))
-                {
-                    File.Copy(file, Path.Combine(google, Path.GetFileName(file)));
-                }
-
-                Assert.AreEqual(0, Directory.GetFiles(TempPath, "*.cs").Length);
-                RunProtoGen(0, proto.TempPath, "-ignore_google_protobuf:true");
-                Assert.AreEqual(1, Directory.GetFiles(TempPath, "*.cs").Length);
-
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("MyNewNamespace.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("MyNewNamespace." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithoutIgnoreGoogleProtobuf()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", @"
-import ""google/protobuf/csharp_options.proto"";
-option (google.protobuf.csharp_file_options).namespace = ""MyNewNamespace"";
-" + DefaultProto))
-            {
-                string google = Path.Combine(TempPath, "google\\protobuf");
-                Directory.CreateDirectory(google);
-                foreach (string file in Directory.GetFiles(Path.Combine(OriginalWorkingDirectory, "google\\protobuf")))
-                {
-                    File.Copy(file, Path.Combine(google, Path.GetFileName(file)));
-                }
-
-                Assert.AreEqual(0, Directory.GetFiles(TempPath, "*.cs").Length);
-                //Without the option this fails due to being unable to resolve google/protobuf descriptors
-                RunProtoGen(1, proto.TempPath, "-ignore_google_protobuf:false");
-            }
-        }
-
-        // *******************************************************************
-        // The following tests excercise options for protoc.exe
-        // *******************************************************************
-
-        [Test]
-        public void TestProtoFileWithIncludeImports()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", @"
-import ""google/protobuf/csharp_options.proto"";
-option (google.protobuf.csharp_file_options).namespace = ""MyNewNamespace"";
-
-package nunit.simple;
-// Test a very simple message.
-message MyMessage {
-  optional string name = 1;
-} "))
-            {
-                string google = Path.Combine(TempPath, "google\\protobuf");
-                Directory.CreateDirectory(google);
-                foreach (string file in Directory.GetFiles(Path.Combine(OriginalWorkingDirectory, "google\\protobuf")))
-                {
-                    File.Copy(file, Path.Combine(google, Path.GetFileName(file)));
-                }
-
-                Assert.AreEqual(0, Directory.GetFiles(TempPath, "*.cs").Length);
-                //if you specify the protoc option --include_imports this should build three source files
-                RunProtoGen(0, proto.TempPath, "--include_imports");
-                Assert.AreEqual(3, Directory.GetFiles(TempPath, "*.cs").Length);
-
-                //you can (and should) simply omit the inclusion of the extra source files in your project
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("MyNewNamespace.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("MyNewNamespace." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileWithIncludeImportsAndIgnoreGoogleProtobuf()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", @"
-import ""google/protobuf/csharp_options.proto"";
-option (google.protobuf.csharp_file_options).namespace = ""MyNewNamespace"";
-
-package nunit.simple;
-// Test a very simple message.
-message MyMessage {
-  optional string name = 1;
-} "))
-            {
-                string google = Path.Combine(TempPath, "google\\protobuf");
-                Directory.CreateDirectory(google);
-                foreach (string file in Directory.GetFiles(Path.Combine(OriginalWorkingDirectory, "google\\protobuf")))
-                    File.Copy(file, Path.Combine(google, Path.GetFileName(file)));
-
-                Assert.AreEqual(0, Directory.GetFiles(TempPath, "*.cs").Length);
-                //Even with --include_imports, if you provide -ignore_google_protobuf:true you only get the one source file
-                RunProtoGen(0, proto.TempPath, "-ignore_google_protobuf:true", "--include_imports");
-                Assert.AreEqual(1, Directory.GetFiles(TempPath, "*.cs").Length);
-
-                //you can (and should) simply omit the inclusion of the extra source files in your project
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("MyNewNamespace.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("MyNewNamespace." + test, true, true);
-            }
-        }
-        [Test]
-        public void TestProtoFileKeepingTheProtoBuffer()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile protobuf = TempFile.Attach(test + ".pb"))
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", @"
-package nunit.simple;
-// Test a very simple message.
-message MyMessage {
-  optional string name = 1;
-} "))
-            {
-                RunProtoGen(0, proto.TempPath, "--descriptor_set_out=" + protobuf.TempPath);
-                Assert.IsTrue(File.Exists(protobuf.TempPath), "Missing: " + protobuf.TempPath);
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-        //Seems the --proto_path or -I option is non-functional for me.  Maybe others have luck?
-        [Test, Ignore("http://code.google.com/p/protobuf/issues/detail?id=40")]
-        public void TestProtoFileInDifferentDirectory()
-        {
-            string test = new StackFrame(false).GetMethod().Name;
-            Setup();
-            using (TempFile source = TempFile.Attach(test + ".cs"))
-            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
-            {
-                Environment.CurrentDirectory = OriginalWorkingDirectory;
-                RunProtoGen(0, proto.TempPath, "--proto_path=" + TempPath);
-                Assembly a = RunCsc(0, source.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple." + test, true, true);
-            }
-        }
-
-        // *******************************************************************
-        // Handling of mutliple input files
-        // *******************************************************************
-
-        [Test]
-        public void TestMultipleProtoFiles()
-        {
-            Setup();
-            using (TempFile source1 = TempFile.Attach("MyMessage.cs"))
-            using (ProtoFile proto1 = new ProtoFile("MyMessage.proto", @"
-package nunit.simple;
-// Test a very simple message.
-message MyMessage {
-  optional string name = 1;
-}"))
-            using (TempFile source2 = TempFile.Attach("MyMessageList.cs"))
-            using (ProtoFile proto2 = new ProtoFile("MyMessageList.proto", @"
-package nunit.simple;
-import ""MyMessage.proto"";
-// Test a very simple message.
-message MyMessageList {
-  repeated MyMessage messages = 1;
-}"))
-            {
-                RunProtoGen(0, proto1.TempPath, proto2.TempPath);
-                Assembly a = RunCsc(0, source1.TempPath, source2.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t1 = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t1), "Expect an IMessage");
-                //assert that the message type is in the expected namespace
-                Type t2 = a.GetType("nunit.simple.MyMessageList", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t2), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple.Proto.MyMessage", true, true);
-                a.GetType("nunit.simple.Proto.MyMessageList", true, true);
-            }
-        }
-        [Test]
-        public void TestOneProtoFileWithBufferFile()
-        {
-            Setup();
-            using (TempFile source1 = TempFile.Attach("MyMessage.cs"))
-            using (TempFile protobuf = TempFile.Attach("MyMessage.pb"))
-            using (ProtoFile proto1 = new ProtoFile("MyMessage.proto", @"
-package nunit.simple;
-// Test a very simple message.
-message MyMessage {
-  optional string name = 1;
-}"))
-            using (TempFile source2 = TempFile.Attach("MyMessageList.cs"))
-            using (ProtoFile proto2 = new ProtoFile("MyMessageList.proto", @"
-package nunit.simple;
-import ""MyMessage.proto"";
-// Test a very simple message.
-message MyMessageList {
-  repeated MyMessage messages = 1;
-}"))
-            {
-                //build the proto buffer for MyMessage
-                RunProtoGen(0, proto1.TempPath, "--descriptor_set_out=" + protobuf.TempPath);
-                //build the MyMessageList proto-buffer and generate code by including MyMessage.pb
-                RunProtoGen(0, proto2.TempPath, protobuf.TempPath);
-                Assembly a = RunCsc(0, source1.TempPath, source2.TempPath);
-                //assert that the message type is in the expected namespace
-                Type t1 = a.GetType("nunit.simple.MyMessage", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t1), "Expect an IMessage");
-                //assert that the message type is in the expected namespace
-                Type t2 = a.GetType("nunit.simple.MyMessageList", true, true);
-                Assert.IsTrue(typeof(IMessage).IsAssignableFrom(t2), "Expect an IMessage");
-                //assert that we can find the static descriptor type
-                a.GetType("nunit.simple.Proto.MyMessage", true, true);
-                a.GetType("nunit.simple.Proto.MyMessageList", 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.Diagnostics;
+using System.IO;
+using System.Reflection;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    [TestFixture]
+    [Category("Preprocessor")]
+    public partial class TestPreprocessing
+    {
+        private static readonly string TempPath = Path.Combine(Path.GetTempPath(), "proto-gen-test");
+
+        private const string DefaultProto =
+            @"
+package nunit.simple;
+// Test a very simple message.
+message MyMessage {
+  optional string name = 1;
+}";
+
+        #region TestFixture SetUp/TearDown
+
+        private static readonly string OriginalWorkingDirectory = Environment.CurrentDirectory;
+
+        [TestFixtureSetUp]
+        public virtual void Setup()
+        {
+            Teardown();
+            Directory.CreateDirectory(TempPath);
+            Environment.CurrentDirectory = TempPath;
+        }
+
+        [TestFixtureTearDown]
+        public virtual void Teardown()
+        {
+            Environment.CurrentDirectory = OriginalWorkingDirectory;
+            if (Directory.Exists(TempPath))
+            {
+                Directory.Delete(TempPath, true);
+            }
+        }
+
+        #endregion
+
+        #region Helper Methods RunProtoGen / RunCsc
+
+        private void RunProtoGen(int expect, params string[] args)
+        {
+            TextWriter tout = Console.Out, terr = Console.Error;
+            StringWriter temp = new StringWriter();
+            Console.SetOut(temp);
+            Console.SetError(temp);
+            try
+            {
+                Assert.AreEqual(expect, ProgramPreprocess.Run(args), "ProtoGen Failed: {0}", temp);
+            }
+            finally
+            {
+                Console.SetOut(tout);
+                Console.SetError(terr);
+            }
+        }
+
+        private Assembly RunCsc(int expect, params string[] sources)
+        {
+            using (TempFile tempDll = new TempFile(String.Empty))
+            {
+                tempDll.ChangeExtension(".dll");
+                List<string> args = new List<string>();
+                args.Add("/nologo");
+                args.Add("/target:library");
+                args.Add("/debug-");
+                args.Add(String.Format(@"""/out:{0}""", tempDll.TempPath));
+                args.Add("/r:System.dll");
+                args.Add(String.Format(@"""/r:{0}""",
+                                       typeof (Google.ProtocolBuffers.DescriptorProtos.DescriptorProto).Assembly.
+                                           Location));
+                args.AddRange(sources);
+
+                string exe = Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(),
+                                          "csc.exe");
+                ProcessStartInfo psi = new ProcessStartInfo(exe);
+                psi.CreateNoWindow = true;
+                psi.UseShellExecute = false;
+                psi.RedirectStandardOutput = true;
+                psi.RedirectStandardError = true;
+                psi.Arguments = string.Join(" ", args.ToArray());
+                Process p = Process.Start(psi);
+                p.WaitForExit();
+                string errorText = p.StandardOutput.ReadToEnd() + p.StandardError.ReadToEnd();
+                Assert.AreEqual(expect, p.ExitCode, "CSC.exe Failed: {0}", errorText);
+
+                Assembly asm = null;
+                if (p.ExitCode == 0)
+                {
+                    byte[] allbytes = File.ReadAllBytes(tempDll.TempPath);
+                    asm = Assembly.Load(allbytes);
+
+                    foreach (Type t in asm.GetTypes())
+                    {
+                        Debug.WriteLine(t.FullName, asm.FullName);
+                    }
+                }
+                return asm;
+            }
+        }
+
+        #endregion
+
+        // *******************************************************************
+        // The following tests excercise options for protogen.exe
+        // *******************************************************************
+
+        [Test]
+        public void TestProtoFile()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(0, proto.TempPath);
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithConflictingType()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (
+                ProtoFile proto = new ProtoFile(test + ".proto",
+                                                @"
+package nunit.simple;
+// Test a very simple message.
+message " +
+                                                test + @" {
+  optional string name = 1;
+} "))
+            {
+                RunProtoGen(0, proto.TempPath);
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple." + test, true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple.Proto." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithNamespace()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(0, proto.TempPath, "-namespace:MyNewNamespace");
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("MyNewNamespace.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("MyNewNamespace." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithUmbrellaClassName()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach("MyUmbrellaClassname.cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(0, proto.TempPath, "/umbrella_classname=MyUmbrellaClassname");
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple.MyUmbrellaClassname", true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithNestedClass()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(0, proto.TempPath, "-nest_classes:true");
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple." + test + "+MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithExpandedNsDirectories()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(@"nunit\simple\" + test + ".cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(0, proto.TempPath, "-expand_namespace_directories:true");
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileDisablingClsComplianceFlags()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (
+                ProtoFile proto = new ProtoFile(test + ".proto",
+                                                @"
+package nunit.simple;
+// Test a very simple message.
+message MyMessage {
+  optional uint32 name = 1;
+} ")
+                )
+            {
+                //CS3021: Warning as Error: xx does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute
+                RunProtoGen(0, proto.TempPath);
+                RunCsc(1, source.TempPath, "/warnaserror+");
+                //Now we know it fails, make it pass by turning off cls_compliance generation
+                RunProtoGen(0, proto.TempPath, "-cls_compliance:false");
+                Assembly a = RunCsc(0, source.TempPath, "/warnaserror+");
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithNewExtension()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".Generated.cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(0, proto.TempPath, "-file_extension:.Generated.cs");
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithUmbrellaNamespace()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(0, proto.TempPath, "-umbrella_namespace:MyUmbrella.Namespace");
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple.MyUmbrella.Namespace." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithIgnoredUmbrellaNamespaceDueToNesting()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(0, proto.TempPath, "-nest_classes:true", "-umbrella_namespace:MyUmbrella.Namespace");
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple." + test + "+MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithExplicitEmptyUmbrellaNamespace()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (
+                ProtoFile proto = new ProtoFile(test + ".proto",
+                                                @"
+package nunit.simple;
+// Test a very simple message.
+message " +
+                                                test + @" {
+  optional string name = 1;
+} "))
+            {
+                //Forces the umbrella class to not use a namespace even if a collision with a type is detected.
+                RunProtoGen(0, proto.TempPath, "-umbrella_namespace:");
+                //error CS0441: 'nunit.simple.TestProtoFileWithExplicitEmptyUmbrellaNamespace': a class cannot be both static and sealed
+                RunCsc(1, source.TempPath);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithNewOutputFolder()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(@"generated-code\" + test + ".cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                RunProtoGen(1, proto.TempPath, "-output_directory:generated-code");
+                Directory.CreateDirectory("generated-code");
+                RunProtoGen(0, proto.TempPath, "-output_directory:generated-code");
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileAndIgnoreGoogleProtobuf()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (
+                ProtoFile proto = new ProtoFile(test + ".proto",
+                                                @"
+import ""google/protobuf/csharp_options.proto"";
+option (google.protobuf.csharp_file_options).namespace = ""MyNewNamespace"";
+" +
+                                                DefaultProto))
+            {
+                string google = Path.Combine(TempPath, "google\\protobuf");
+                Directory.CreateDirectory(google);
+                foreach (string file in Directory.GetFiles(Path.Combine(OriginalWorkingDirectory, "google\\protobuf")))
+                {
+                    File.Copy(file, Path.Combine(google, Path.GetFileName(file)));
+                }
+
+                Assert.AreEqual(0, Directory.GetFiles(TempPath, "*.cs").Length);
+                RunProtoGen(0, proto.TempPath, "-ignore_google_protobuf:true");
+                Assert.AreEqual(1, Directory.GetFiles(TempPath, "*.cs").Length);
+
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("MyNewNamespace.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("MyNewNamespace." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithoutIgnoreGoogleProtobuf()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (
+                ProtoFile proto = new ProtoFile(test + ".proto",
+                                                @"
+import ""google/protobuf/csharp_options.proto"";
+option (google.protobuf.csharp_file_options).namespace = ""MyNewNamespace"";
+" +
+                                                DefaultProto))
+            {
+                string google = Path.Combine(TempPath, "google\\protobuf");
+                Directory.CreateDirectory(google);
+                foreach (string file in Directory.GetFiles(Path.Combine(OriginalWorkingDirectory, "google\\protobuf")))
+                {
+                    File.Copy(file, Path.Combine(google, Path.GetFileName(file)));
+                }
+
+                Assert.AreEqual(0, Directory.GetFiles(TempPath, "*.cs").Length);
+                //Without the option this fails due to being unable to resolve google/protobuf descriptors
+                RunProtoGen(1, proto.TempPath, "-ignore_google_protobuf:false");
+            }
+        }
+
+        // *******************************************************************
+        // The following tests excercise options for protoc.exe
+        // *******************************************************************
+
+        [Test]
+        public void TestProtoFileWithIncludeImports()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (
+                ProtoFile proto = new ProtoFile(test + ".proto",
+                                                @"
+import ""google/protobuf/csharp_options.proto"";
+option (google.protobuf.csharp_file_options).namespace = ""MyNewNamespace"";
+
+package nunit.simple;
+// Test a very simple message.
+message MyMessage {
+  optional string name = 1;
+} ")
+                )
+            {
+                string google = Path.Combine(TempPath, "google\\protobuf");
+                Directory.CreateDirectory(google);
+                foreach (string file in Directory.GetFiles(Path.Combine(OriginalWorkingDirectory, "google\\protobuf")))
+                {
+                    File.Copy(file, Path.Combine(google, Path.GetFileName(file)));
+                }
+
+                Assert.AreEqual(0, Directory.GetFiles(TempPath, "*.cs").Length);
+                //if you specify the protoc option --include_imports this should build three source files
+                RunProtoGen(0, proto.TempPath, "--include_imports");
+                Assert.AreEqual(3, Directory.GetFiles(TempPath, "*.cs").Length);
+
+                //you can (and should) simply omit the inclusion of the extra source files in your project
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("MyNewNamespace.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("MyNewNamespace." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileWithIncludeImportsAndIgnoreGoogleProtobuf()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (
+                ProtoFile proto = new ProtoFile(test + ".proto",
+                                                @"
+import ""google/protobuf/csharp_options.proto"";
+option (google.protobuf.csharp_file_options).namespace = ""MyNewNamespace"";
+
+package nunit.simple;
+// Test a very simple message.
+message MyMessage {
+  optional string name = 1;
+} ")
+                )
+            {
+                string google = Path.Combine(TempPath, "google\\protobuf");
+                Directory.CreateDirectory(google);
+                foreach (string file in Directory.GetFiles(Path.Combine(OriginalWorkingDirectory, "google\\protobuf")))
+                    File.Copy(file, Path.Combine(google, Path.GetFileName(file)));
+
+                Assert.AreEqual(0, Directory.GetFiles(TempPath, "*.cs").Length);
+                //Even with --include_imports, if you provide -ignore_google_protobuf:true you only get the one source file
+                RunProtoGen(0, proto.TempPath, "-ignore_google_protobuf:true", "--include_imports");
+                Assert.AreEqual(1, Directory.GetFiles(TempPath, "*.cs").Length);
+
+                //you can (and should) simply omit the inclusion of the extra source files in your project
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("MyNewNamespace.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("MyNewNamespace." + test, true, true);
+            }
+        }
+
+        [Test]
+        public void TestProtoFileKeepingTheProtoBuffer()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile protobuf = TempFile.Attach(test + ".pb"))
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (
+                ProtoFile proto = new ProtoFile(test + ".proto",
+                                                @"
+package nunit.simple;
+// Test a very simple message.
+message MyMessage {
+  optional string name = 1;
+} ")
+                )
+            {
+                RunProtoGen(0, proto.TempPath, "--descriptor_set_out=" + protobuf.TempPath);
+                Assert.IsTrue(File.Exists(protobuf.TempPath), "Missing: " + protobuf.TempPath);
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        //Seems the --proto_path or -I option is non-functional for me.  Maybe others have luck?
+        [Test, Ignore("http://code.google.com/p/protobuf/issues/detail?id=40")]
+        public void TestProtoFileInDifferentDirectory()
+        {
+            string test = new StackFrame(false).GetMethod().Name;
+            Setup();
+            using (TempFile source = TempFile.Attach(test + ".cs"))
+            using (ProtoFile proto = new ProtoFile(test + ".proto", DefaultProto))
+            {
+                Environment.CurrentDirectory = OriginalWorkingDirectory;
+                RunProtoGen(0, proto.TempPath, "--proto_path=" + TempPath);
+                Assembly a = RunCsc(0, source.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple." + test, true, true);
+            }
+        }
+
+        // *******************************************************************
+        // Handling of mutliple input files
+        // *******************************************************************
+
+        [Test]
+        public void TestMultipleProtoFiles()
+        {
+            Setup();
+            using (TempFile source1 = TempFile.Attach("MyMessage.cs"))
+            using (
+                ProtoFile proto1 = new ProtoFile("MyMessage.proto",
+                                                 @"
+package nunit.simple;
+// Test a very simple message.
+message MyMessage {
+  optional string name = 1;
+}")
+                )
+            using (TempFile source2 = TempFile.Attach("MyMessageList.cs"))
+            using (
+                ProtoFile proto2 = new ProtoFile("MyMessageList.proto",
+                                                 @"
+package nunit.simple;
+import ""MyMessage.proto"";
+// Test a very simple message.
+message MyMessageList {
+  repeated MyMessage messages = 1;
+}")
+                )
+            {
+                RunProtoGen(0, proto1.TempPath, proto2.TempPath);
+                Assembly a = RunCsc(0, source1.TempPath, source2.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t1 = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t1), "Expect an IMessage");
+                //assert that the message type is in the expected namespace
+                Type t2 = a.GetType("nunit.simple.MyMessageList", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t2), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple.Proto.MyMessage", true, true);
+                a.GetType("nunit.simple.Proto.MyMessageList", true, true);
+            }
+        }
+
+        [Test]
+        public void TestOneProtoFileWithBufferFile()
+        {
+            Setup();
+            using (TempFile source1 = TempFile.Attach("MyMessage.cs"))
+            using (TempFile protobuf = TempFile.Attach("MyMessage.pb"))
+            using (
+                ProtoFile proto1 = new ProtoFile("MyMessage.proto",
+                                                 @"
+package nunit.simple;
+// Test a very simple message.
+message MyMessage {
+  optional string name = 1;
+}")
+                )
+            using (TempFile source2 = TempFile.Attach("MyMessageList.cs"))
+            using (
+                ProtoFile proto2 = new ProtoFile("MyMessageList.proto",
+                                                 @"
+package nunit.simple;
+import ""MyMessage.proto"";
+// Test a very simple message.
+message MyMessageList {
+  repeated MyMessage messages = 1;
+}")
+                )
+            {
+                //build the proto buffer for MyMessage
+                RunProtoGen(0, proto1.TempPath, "--descriptor_set_out=" + protobuf.TempPath);
+                //build the MyMessageList proto-buffer and generate code by including MyMessage.pb
+                RunProtoGen(0, proto2.TempPath, protobuf.TempPath);
+                Assembly a = RunCsc(0, source1.TempPath, source2.TempPath);
+                //assert that the message type is in the expected namespace
+                Type t1 = a.GetType("nunit.simple.MyMessage", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t1), "Expect an IMessage");
+                //assert that the message type is in the expected namespace
+                Type t2 = a.GetType("nunit.simple.MyMessageList", true, true);
+                Assert.IsTrue(typeof (IMessage).IsAssignableFrom(t2), "Expect an IMessage");
+                //assert that we can find the static descriptor type
+                a.GetType("nunit.simple.Proto.MyMessage", true, true);
+                a.GetType("nunit.simple.Proto.MyMessageList", true, true);
+            }
+        }
+    }
+}

+ 55 - 49
src/ProtoGen/DependencyResolutionException.cs

@@ -1,49 +1,55 @@
-#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.ProtoGen {
-  /// <summary>
-  /// Exception thrown when dependencies within a descriptor set can't be resolved.
-  /// </summary>
-  public sealed class DependencyResolutionException : Exception {
-    public DependencyResolutionException(string message) : base(message) {
-    }
-
-    public DependencyResolutionException(string format, params object[] args) 
-        : base(string.Format(format, args)) {
-    }
-  }
-}
+#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.ProtoGen
+{
+    /// <summary>
+    /// Exception thrown when dependencies within a descriptor set can't be resolved.
+    /// </summary>
+    public sealed class DependencyResolutionException : Exception
+    {
+        public DependencyResolutionException(string message) : base(message)
+        {
+        }
+
+        public DependencyResolutionException(string format, params object[] args)
+            : base(string.Format(format, args))
+        {
+        }
+    }
+}

+ 106 - 86
src/ProtoGen/DescriptorUtil.cs

@@ -1,86 +1,106 @@
-#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 Google.ProtocolBuffers.DescriptorProtos;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  /// <summary>
-  /// Utility class for determining namespaces etc.
-  /// </summary>
-  internal static class DescriptorUtil {
-
-    internal static string GetFullUmbrellaClassName(IDescriptor descriptor) {
-      CSharpFileOptions options = descriptor.File.CSharpOptions;
-      string result = options.Namespace;
-      if (result != "") {
-        result += '.';
-      }
-      result += GetQualifiedUmbrellaClassName(options);
-      return "global::" + result;
-    }
-
-    /// <summary>
-    /// Evaluates the options and returns the qualified name of the umbrella class
-    /// relative to the descriptor type's namespace.  Basically concatenates the
-    /// UmbrellaNamespace + UmbrellaClassname fields.
-    /// </summary>
-    internal static string GetQualifiedUmbrellaClassName(CSharpFileOptions options) {
-      string fullName = options.UmbrellaClassname;
-      if (!options.NestClasses && options.UmbrellaNamespace != "") {
-        fullName = String.Format("{0}.{1}", options.UmbrellaNamespace, options.UmbrellaClassname);
-      }
-      return fullName;
-    }
-
-    internal static string GetMappedTypeName(MappedType type) {
-      switch(type) {
-        case MappedType.Int32:      return "int";
-        case MappedType.Int64:      return "long";
-        case MappedType.UInt32:     return "uint";
-        case MappedType.UInt64:     return "ulong";
-        case MappedType.Single:     return "float";
-        case MappedType.Double:     return "double";
-        case MappedType.Boolean:    return "bool";
-        case MappedType.String:     return "string";
-        case MappedType.ByteString: return "pb::ByteString";
-        case MappedType.Enum:       return null;
-        case MappedType.Message:    return null;
-        default:
-          throw new ArgumentOutOfRangeException("Unknown mapped type " + type);
-      }
-    }
-  }
-}
+#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 Google.ProtocolBuffers.DescriptorProtos;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// Utility class for determining namespaces etc.
+    /// </summary>
+    internal static class DescriptorUtil
+    {
+        internal static string GetFullUmbrellaClassName(IDescriptor descriptor)
+        {
+            CSharpFileOptions options = descriptor.File.CSharpOptions;
+            string result = options.Namespace;
+            if (result != "")
+            {
+                result += '.';
+            }
+            result += GetQualifiedUmbrellaClassName(options);
+            return "global::" + result;
+        }
+
+        /// <summary>
+        /// Evaluates the options and returns the qualified name of the umbrella class
+        /// relative to the descriptor type's namespace.  Basically concatenates the
+        /// UmbrellaNamespace + UmbrellaClassname fields.
+        /// </summary>
+        internal static string GetQualifiedUmbrellaClassName(CSharpFileOptions options)
+        {
+            string fullName = options.UmbrellaClassname;
+            if (!options.NestClasses && options.UmbrellaNamespace != "")
+            {
+                fullName = String.Format("{0}.{1}", options.UmbrellaNamespace, options.UmbrellaClassname);
+            }
+            return fullName;
+        }
+
+        internal static string GetMappedTypeName(MappedType type)
+        {
+            switch (type)
+            {
+                case MappedType.Int32:
+                    return "int";
+                case MappedType.Int64:
+                    return "long";
+                case MappedType.UInt32:
+                    return "uint";
+                case MappedType.UInt64:
+                    return "ulong";
+                case MappedType.Single:
+                    return "float";
+                case MappedType.Double:
+                    return "double";
+                case MappedType.Boolean:
+                    return "bool";
+                case MappedType.String:
+                    return "string";
+                case MappedType.ByteString:
+                    return "pb::ByteString";
+                case MappedType.Enum:
+                    return null;
+                case MappedType.Message:
+                    return null;
+                default:
+                    throw new ArgumentOutOfRangeException("Unknown mapped type " + type);
+            }
+        }
+    }
+}

+ 143 - 126
src/ProtoGen/EnumFieldGenerator.cs

@@ -1,126 +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 Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class EnumFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator {
-    internal EnumFieldGenerator(FieldDescriptor descriptor)
-        : base(descriptor) {
-    }
-
-    public void GenerateMembers(TextGenerator writer) {
-      writer.WriteLine("private bool has{0};", PropertyName);
-      writer.WriteLine("private {0} {1}_ = {2};", TypeName, Name, DefaultValue);
-      writer.WriteLine("public bool Has{0} {{", PropertyName);
-      writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return {0}_; }}", Name);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuilderMembers(TextGenerator writer) {
-      writer.WriteLine("public bool Has{0} {{", PropertyName);
-      writer.WriteLine(" get {{ return result.Has{0}; }}", PropertyName);
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
-      writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
-      writer.WriteLine("  result.has{0} = true;", PropertyName);
-      writer.WriteLine("  result.{0}_ = value;", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
-      writer.WriteLine("  result.has{0} = false;", PropertyName);
-      writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-    }
-
-    public void GenerateMergingCode(TextGenerator writer) {
-      writer.WriteLine("if (other.Has{0}) {{", PropertyName);
-      writer.WriteLine("  {0} = other.{0};", PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuildingCode(TextGenerator writer) {
-      // Nothing to do here for enum types
-    }
-
-    public void GenerateParsingCode(TextGenerator writer) {
-      // TODO(jonskeet): Make a more efficient way of doing this
-      writer.WriteLine("int rawValue = input.ReadEnum();");
-      writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);
-      if (!UseLiteRuntime) {
-        writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
-        writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
-        writer.WriteLine("  }");
-        writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);
-      }
-      writer.WriteLine("} else {");
-      writer.WriteLine("  {0} = ({1}) rawValue;", PropertyName, TypeName);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateSerializationCode(TextGenerator writer) {
-      writer.WriteLine("if (Has{0}) {{", PropertyName);
-      writer.WriteLine("  output.WriteEnum({0}, (int) {1});", Number, PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateSerializedSizeCode(TextGenerator writer) {
-      writer.WriteLine("if (Has{0}) {{", PropertyName);
-      writer.WriteLine("  size += pb::CodedOutputStream.ComputeEnumSize({0}, (int) {1});", Number, PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public override void WriteHash(TextGenerator writer) {
-      writer.WriteLine("if (has{0}) hash ^= {1}_.GetHashCode();", PropertyName, Name);
-    }
-
-    public override void WriteEquals(TextGenerator writer) {
-      writer.WriteLine("if (has{0} != other.has{0} || (has{0} && !{1}_.Equals(other.{1}_))) return false;", PropertyName, Name);
-    }
-
-    public override void WriteToString(TextGenerator writer) {
-      writer.WriteLine("PrintField(\"{0}\", has{1}, {2}_, writer);", Descriptor.Name, PropertyName, Name);
-    }
-  }
-}
+#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.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class EnumFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
+    {
+        internal EnumFieldGenerator(FieldDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        public void GenerateMembers(TextGenerator writer)
+        {
+            writer.WriteLine("private bool has{0};", PropertyName);
+            writer.WriteLine("private {0} {1}_ = {2};", TypeName, Name, DefaultValue);
+            writer.WriteLine("public bool Has{0} {{", PropertyName);
+            writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return {0}_; }}", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuilderMembers(TextGenerator writer)
+        {
+            writer.WriteLine("public bool Has{0} {{", PropertyName);
+            writer.WriteLine(" get {{ return result.Has{0}; }}", PropertyName);
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
+            writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
+            writer.WriteLine("  result.has{0} = true;", PropertyName);
+            writer.WriteLine("  result.{0}_ = value;", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  result.has{0} = false;", PropertyName);
+            writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+        }
+
+        public void GenerateMergingCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (other.Has{0}) {{", PropertyName);
+            writer.WriteLine("  {0} = other.{0};", PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuildingCode(TextGenerator writer)
+        {
+            // Nothing to do here for enum types
+        }
+
+        public void GenerateParsingCode(TextGenerator writer)
+        {
+            // TODO(jonskeet): Make a more efficient way of doing this
+            writer.WriteLine("int rawValue = input.ReadEnum();");
+            writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);
+            if (!UseLiteRuntime)
+            {
+                writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
+                writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
+                writer.WriteLine("  }");
+                writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);
+            }
+            writer.WriteLine("} else {");
+            writer.WriteLine("  {0} = ({1}) rawValue;", PropertyName, TypeName);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateSerializationCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (Has{0}) {{", PropertyName);
+            writer.WriteLine("  output.WriteEnum({0}, (int) {1});", Number, PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateSerializedSizeCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (Has{0}) {{", PropertyName);
+            writer.WriteLine("  size += pb::CodedOutputStream.ComputeEnumSize({0}, (int) {1});", Number, PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public override void WriteHash(TextGenerator writer)
+        {
+            writer.WriteLine("if (has{0}) hash ^= {1}_.GetHashCode();", PropertyName, Name);
+        }
+
+        public override void WriteEquals(TextGenerator writer)
+        {
+            writer.WriteLine("if (has{0} != other.has{0} || (has{0} && !{1}_.Equals(other.{1}_))) return false;",
+                             PropertyName, Name);
+        }
+
+        public override void WriteToString(TextGenerator writer)
+        {
+            writer.WriteLine("PrintField(\"{0}\", has{1}, {2}_, writer);", Descriptor.Name, PropertyName, Name);
+        }
+    }
+}

+ 61 - 54
src/ProtoGen/EnumGenerator.cs

@@ -1,54 +1,61 @@
-#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.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class EnumGenerator : SourceGeneratorBase<EnumDescriptor>, ISourceGenerator {
-    internal EnumGenerator(EnumDescriptor descriptor) : base(descriptor) {
-    }
-
-    // TODO(jonskeet): Write out enum descriptors? Can be retrieved from file...
-    public void Generate(TextGenerator writer) {
-      writer.WriteLine("{0} enum {1} {{", ClassAccessLevel, Descriptor.Name);
-      writer.Indent();
-      foreach (EnumValueDescriptor value in Descriptor.Values) {
-        writer.WriteLine("{0} = {1},", value.Name, value.Number);
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-    }
-  }
-}
+#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.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class EnumGenerator : SourceGeneratorBase<EnumDescriptor>, ISourceGenerator
+    {
+        internal EnumGenerator(EnumDescriptor descriptor) : base(descriptor)
+        {
+        }
+
+        // TODO(jonskeet): Write out enum descriptors? Can be retrieved from file...
+        public void Generate(TextGenerator writer)
+        {
+            writer.WriteLine("{0} enum {1} {{", ClassAccessLevel, Descriptor.Name);
+            writer.Indent();
+            foreach (EnumValueDescriptor value in Descriptor.Values)
+            {
+                writer.WriteLine("{0} = {1},", value.Name, value.Number);
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+        }
+    }
+}

+ 177 - 135
src/ProtoGen/ExtensionGenerator.cs

@@ -1,135 +1,177 @@
-#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 Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class ExtensionGenerator : FieldGeneratorBase, ISourceGenerator {
-
-    private readonly string extends;
-    private readonly string scope;
-    private readonly string type;
-    private readonly string name;
-
-    internal ExtensionGenerator(FieldDescriptor descriptor)
-      : base(descriptor) {
-      if (Descriptor.ExtensionScope != null) {
-        scope = GetClassName(Descriptor.ExtensionScope);
-      } else {
-        scope = DescriptorUtil.GetFullUmbrellaClassName(Descriptor.File);
-      }
-      switch (Descriptor.MappedType) {
-        case MappedType.Message:
-          type = GetClassName(Descriptor.MessageType);
-          break;
-        case MappedType.Enum:
-          type = GetClassName(Descriptor.EnumType);
-          break;
-        default:
-          type = DescriptorUtil.GetMappedTypeName(Descriptor.MappedType);
-          break;
-      }
-      extends = GetClassName(Descriptor.ContainingType);
-      name = Descriptor.CSharpOptions.PropertyName;
-    }
-
-    public void Generate(TextGenerator writer) {
-      writer.WriteLine("public const int {0} = {1};", GetFieldConstantName(Descriptor), Descriptor.FieldNumber);
-
-      if (UseLiteRuntime) {
-        if (Descriptor.MappedType == MappedType.Message && Descriptor.MessageType.Options.MessageSetWireFormat) {
-          throw new ArgumentException("option message_set_wire_format = true; is not supported in Lite runtime extensions.");
-        }
-        if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance) {
-          writer.WriteLine("[global::System.CLSCompliant(false)]");
-        }
-        writer.WriteLine("{0} static pb::{4}<{1}, {2}> {3};", ClassAccessLevel, extends, type, name,
-          Descriptor.IsRepeated ? "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite");
-      } else if (Descriptor.IsRepeated) {
-        if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance) {
-          writer.WriteLine("[global::System.CLSCompliant(false)]");
-        }
-        writer.WriteLine("{0} static pb::GeneratedExtensionBase<scg::IList<{1}>> {2};", ClassAccessLevel, type, name);
-      } else {
-        if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance) {
-          writer.WriteLine("[global::System.CLSCompliant(false)]");
-        }
-        writer.WriteLine("{0} static pb::GeneratedExtensionBase<{1}> {2};", ClassAccessLevel, type, name);
-      }
-    }
-
-    internal void GenerateStaticVariableInitializers(TextGenerator writer) {
-      if (UseLiteRuntime) {
-        writer.WriteLine("{0}.{1} = ", scope, name);
-        writer.Indent();
-        writer.WriteLine("new pb::{0}<{1}, {2}>(", Descriptor.IsRepeated ? "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite", extends, type);
-        writer.Indent();
-        writer.WriteLine("\"{0}\",", Descriptor.FullName);
-        writer.WriteLine("{0}.DefaultInstance,", extends);
-        if(!Descriptor.IsRepeated)
-          writer.WriteLine("{0},", Descriptor.HasDefaultValue ? DefaultValue : IsNullableType ? "null" : "default(" + type + ")");
-        writer.WriteLine("{0},", (Descriptor.MappedType == MappedType.Message) ? type + ".DefaultInstance" : "null");
-        writer.WriteLine("{0},", (Descriptor.MappedType == MappedType.Enum) ? "new EnumLiteMap<" + type + ">()" : "null");
-        writer.WriteLine("{0}.{1}FieldNumber,", scope, name);
-        writer.Write("pbd::FieldType.{0}", Descriptor.FieldType);
-        if (Descriptor.IsRepeated) {
-          writer.WriteLine(",");
-          writer.Write(Descriptor.IsPacked ? "true" : "false");
-        }
-        writer.Outdent();
-        writer.WriteLine(");");
-        writer.Outdent();
-      } else if (Descriptor.IsRepeated) {
-        writer.WriteLine("{0}.{1} = pb::GeneratedRepeatExtension<{2}>.CreateInstance({0}.Descriptor.Extensions[{3}]);", scope, name, type, Descriptor.Index);
-      } else {
-        writer.WriteLine("{0}.{1} = pb::GeneratedSingleExtension<{2}>.CreateInstance({0}.Descriptor.Extensions[{3}]);", scope, name, type, Descriptor.Index);
-      }
-    }
-
-    internal void GenerateExtensionRegistrationCode(TextGenerator writer) {
-      writer.WriteLine("registry.Add({0}.{1});", scope, name);
-    }
-
-    public override void WriteHash(TextGenerator writer) {
-    }
-
-    public override void WriteEquals(TextGenerator writer) {
-    }
-
-    public override void WriteToString(TextGenerator writer) {
-    }
-  }
-}
+#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 Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class ExtensionGenerator : FieldGeneratorBase, ISourceGenerator
+    {
+        private readonly string extends;
+        private readonly string scope;
+        private readonly string type;
+        private readonly string name;
+
+        internal ExtensionGenerator(FieldDescriptor descriptor)
+            : base(descriptor)
+        {
+            if (Descriptor.ExtensionScope != null)
+            {
+                scope = GetClassName(Descriptor.ExtensionScope);
+            }
+            else
+            {
+                scope = DescriptorUtil.GetFullUmbrellaClassName(Descriptor.File);
+            }
+            switch (Descriptor.MappedType)
+            {
+                case MappedType.Message:
+                    type = GetClassName(Descriptor.MessageType);
+                    break;
+                case MappedType.Enum:
+                    type = GetClassName(Descriptor.EnumType);
+                    break;
+                default:
+                    type = DescriptorUtil.GetMappedTypeName(Descriptor.MappedType);
+                    break;
+            }
+            extends = GetClassName(Descriptor.ContainingType);
+            name = Descriptor.CSharpOptions.PropertyName;
+        }
+
+        public void Generate(TextGenerator writer)
+        {
+            writer.WriteLine("public const int {0} = {1};", GetFieldConstantName(Descriptor), Descriptor.FieldNumber);
+
+            if (UseLiteRuntime)
+            {
+                if (Descriptor.MappedType == MappedType.Message && Descriptor.MessageType.Options.MessageSetWireFormat)
+                {
+                    throw new ArgumentException(
+                        "option message_set_wire_format = true; is not supported in Lite runtime extensions.");
+                }
+                if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance)
+                {
+                    writer.WriteLine("[global::System.CLSCompliant(false)]");
+                }
+                writer.WriteLine("{0} static pb::{4}<{1}, {2}> {3};", ClassAccessLevel, extends, type, name,
+                                 Descriptor.IsRepeated ? "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite");
+            }
+            else if (Descriptor.IsRepeated)
+            {
+                if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance)
+                {
+                    writer.WriteLine("[global::System.CLSCompliant(false)]");
+                }
+                writer.WriteLine("{0} static pb::GeneratedExtensionBase<scg::IList<{1}>> {2};", ClassAccessLevel, type,
+                                 name);
+            }
+            else
+            {
+                if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance)
+                {
+                    writer.WriteLine("[global::System.CLSCompliant(false)]");
+                }
+                writer.WriteLine("{0} static pb::GeneratedExtensionBase<{1}> {2};", ClassAccessLevel, type, name);
+            }
+        }
+
+        internal void GenerateStaticVariableInitializers(TextGenerator writer)
+        {
+            if (UseLiteRuntime)
+            {
+                writer.WriteLine("{0}.{1} = ", scope, name);
+                writer.Indent();
+                writer.WriteLine("new pb::{0}<{1}, {2}>(",
+                                 Descriptor.IsRepeated ? "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite",
+                                 extends, type);
+                writer.Indent();
+                writer.WriteLine("\"{0}\",", Descriptor.FullName);
+                writer.WriteLine("{0}.DefaultInstance,", extends);
+                if (!Descriptor.IsRepeated)
+                    writer.WriteLine("{0},",
+                                     Descriptor.HasDefaultValue
+                                         ? DefaultValue
+                                         : IsNullableType ? "null" : "default(" + type + ")");
+                writer.WriteLine("{0},",
+                                 (Descriptor.MappedType == MappedType.Message) ? type + ".DefaultInstance" : "null");
+                writer.WriteLine("{0},",
+                                 (Descriptor.MappedType == MappedType.Enum) ? "new EnumLiteMap<" + type + ">()" : "null");
+                writer.WriteLine("{0}.{1}FieldNumber,", scope, name);
+                writer.Write("pbd::FieldType.{0}", Descriptor.FieldType);
+                if (Descriptor.IsRepeated)
+                {
+                    writer.WriteLine(",");
+                    writer.Write(Descriptor.IsPacked ? "true" : "false");
+                }
+                writer.Outdent();
+                writer.WriteLine(");");
+                writer.Outdent();
+            }
+            else if (Descriptor.IsRepeated)
+            {
+                writer.WriteLine(
+                    "{0}.{1} = pb::GeneratedRepeatExtension<{2}>.CreateInstance({0}.Descriptor.Extensions[{3}]);", scope,
+                    name, type, Descriptor.Index);
+            }
+            else
+            {
+                writer.WriteLine(
+                    "{0}.{1} = pb::GeneratedSingleExtension<{2}>.CreateInstance({0}.Descriptor.Extensions[{3}]);", scope,
+                    name, type, Descriptor.Index);
+            }
+        }
+
+        internal void GenerateExtensionRegistrationCode(TextGenerator writer)
+        {
+            writer.WriteLine("registry.Add({0}.{1});", scope, name);
+        }
+
+        public override void WriteHash(TextGenerator writer)
+        {
+        }
+
+        public override void WriteEquals(TextGenerator writer)
+        {
+        }
+
+        public override void WriteToString(TextGenerator writer)
+        {
+        }
+    }
+}

+ 316 - 268
src/ProtoGen/FieldGeneratorBase.cs

@@ -1,268 +1,316 @@
-#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 Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal abstract class FieldGeneratorBase : SourceGeneratorBase<FieldDescriptor> {
-    protected FieldGeneratorBase(FieldDescriptor descriptor)
-        : base(descriptor) {
-    }
-
-    public abstract void WriteHash(TextGenerator writer);
-    public abstract void WriteEquals(TextGenerator writer);
-    public abstract void WriteToString(TextGenerator writer);
-
-    private static bool AllPrintableAscii(string text) {
-      foreach (char c in text) {
-        if (c < 0x20 || c > 0x7e) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /// <remarks>Copy exists in ExtensionGenerator.cs</remarks>
-    protected string DefaultValue {
-      get {
-        string suffix = "";
-        switch (Descriptor.FieldType) {
-          case FieldType.Float:  suffix = "F"; break;
-          case FieldType.Double: suffix = "D"; break;
-          case FieldType.Int64:  suffix = "L"; break;
-          case FieldType.UInt64: suffix = "UL"; break;
-        }
-        switch (Descriptor.FieldType) {
-          case FieldType.Float:
-          case FieldType.Double:
-          case FieldType.Int32:
-          case FieldType.Int64:
-          case FieldType.SInt32:
-          case FieldType.SInt64:
-          case FieldType.SFixed32:
-          case FieldType.SFixed64:
-          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.
-            IConvertible value = (IConvertible) Descriptor.DefaultValue;
-            //a few things that must be handled explicitly
-            if (Descriptor.FieldType == FieldType.Double && value is double) {
-              if (double.IsNaN((double) value))
-                return "double.NaN";
-              if (double.IsPositiveInfinity((double) value))
-                return "double.PositiveInfinity";
-              if (double.IsNegativeInfinity((double) value))
-                return "double.NegativeInfinity";
-            }
-            else if (Descriptor.FieldType == FieldType.Float && value is float) {
-              if (float.IsNaN((float)value))
-                return "float.NaN";
-              if (float.IsPositiveInfinity((float)value))
-                return "float.PositiveInfinity";
-              if (float.IsNegativeInfinity((float)value))
-                return "float.NegativeInfinity";
-            }
-            return value.ToString(CultureInfo.InvariantCulture) + suffix;
-          }
-          case FieldType.Bool:
-            return (bool) Descriptor.DefaultValue ? "true" : "false";
-
-          case FieldType.Bytes:
-            if (!Descriptor.HasDefaultValue) {
-              return "pb::ByteString.Empty";
-            }
-            if (UseLiteRuntime && Descriptor.DefaultValue is ByteString) {
-              string temp = Convert.ToBase64String(((ByteString)Descriptor.DefaultValue).ToByteArray());
-              return String.Format("ByteString.FromBase64(\"{0}\")", temp);
-            }
-            return string.Format("(pb::ByteString) {0}.Descriptor.Fields[{1}].DefaultValue", GetClassName(Descriptor.ContainingType), Descriptor.Index);
-          case FieldType.String:
-            if (AllPrintableAscii(Descriptor.Proto.DefaultValue)) {
-              // All chars are ASCII and printable.  In this case we only
-              // need to escape quotes and backslashes.
-              return "\"" + Descriptor.Proto.DefaultValue
-                  .Replace("\\", "\\\\")
-                  .Replace("'", "\\'")
-                  .Replace("\"", "\\\"")
-                  + "\"";
-            }
-            if (UseLiteRuntime && Descriptor.DefaultValue is String) {
-              string temp = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes((String)Descriptor.DefaultValue));
-              return String.Format("ByteString.FromBase64(\"{0}\").ToStringUtf8()", temp);
-            }
-            return string.Format("(string) {0}.Descriptor.Fields[{1}].DefaultValue", GetClassName(Descriptor.ContainingType), Descriptor.Index);
-          case FieldType.Enum:
-            return TypeName + "." + ((EnumValueDescriptor) Descriptor.DefaultValue).Name;
-          case FieldType.Message:
-          case FieldType.Group:
-            return TypeName + ".DefaultInstance";
-          default:
-            throw new InvalidOperationException("Invalid field descriptor type");
-        }
-      }
-    }
-
-    protected string PropertyName {
-      get {
-        return Descriptor.CSharpOptions.PropertyName;
-      }
-    }
-
-    protected string Name {
-      get { return NameHelpers.UnderscoresToCamelCase(GetFieldName(Descriptor)); }
-    }
-
-    protected int Number {
-      get { return Descriptor.FieldNumber; }
-    }
-
-    protected void AddNullCheck(TextGenerator writer) {
-      AddNullCheck(writer, "value");
-    }
-
-    protected void AddNullCheck(TextGenerator writer, string name) {
-      if (IsNullableType) {
-        writer.WriteLine("  pb::ThrowHelper.ThrowIfNull({0}, \"{0}\");", name);
-      }
-    }
-
-    protected void AddClsComplianceCheck(TextGenerator writer) {
-      if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance) {
-        writer.WriteLine("[global::System.CLSCompliant(false)]");
-      }
-    }
-
-    /// <summary>
-    /// For encodings with fixed sizes, returns that size in bytes.  Otherwise
-    /// returns -1. TODO(jonskeet): Make this less ugly.
-    /// </summary>
-    protected int FixedSize {
-      get {
-        switch (Descriptor.FieldType) {
-          case FieldType.UInt32:
-          case FieldType.UInt64:
-          case FieldType.Int32:
-          case FieldType.Int64:
-          case FieldType.SInt32:
-          case FieldType.SInt64:
-          case FieldType.Enum:
-          case FieldType.Bytes:
-          case FieldType.String:
-          case FieldType.Message:
-          case FieldType.Group:
-            return -1;
-          case FieldType.Float:
-            return WireFormat.FloatSize;
-          case FieldType.SFixed32:
-            return WireFormat.SFixed32Size;
-          case FieldType.Fixed32:
-            return WireFormat.Fixed32Size;
-          case FieldType.Double:
-            return WireFormat.DoubleSize;
-          case FieldType.SFixed64:
-            return WireFormat.SFixed64Size;
-          case FieldType.Fixed64:
-            return WireFormat.Fixed64Size;
-          case FieldType.Bool:
-            return WireFormat.BoolSize;
-          default:
-            throw new InvalidOperationException("Invalid field descriptor type");
-        }
-      }
-    }
-
-    protected bool IsNullableType {
-      get {
-        switch (Descriptor.FieldType) {
-          case FieldType.Float:
-          case FieldType.Double:
-          case FieldType.Int32:
-          case FieldType.Int64:
-          case FieldType.SInt32:
-          case FieldType.SInt64:
-          case FieldType.SFixed32:
-          case FieldType.SFixed64:
-          case FieldType.UInt32:
-          case FieldType.UInt64:
-          case FieldType.Fixed32:
-          case FieldType.Fixed64:
-          case FieldType.Bool:
-          case FieldType.Enum:
-            return false;
-          case FieldType.Bytes:
-          case FieldType.String:
-          case FieldType.Message:
-          case FieldType.Group:
-            return true;
-          default:
-            throw new InvalidOperationException("Invalid field descriptor type");
-        }
-      }
-    }
-
-    protected string TypeName {
-      get {
-        switch (Descriptor.FieldType) {
-          case FieldType.Enum:
-            return GetClassName(Descriptor.EnumType);
-          case FieldType.Message:
-          case FieldType.Group:
-            return GetClassName(Descriptor.MessageType);
-          default:
-            return DescriptorUtil.GetMappedTypeName(Descriptor.MappedType);
-        }
-      }
-    }
-
-    protected string MessageOrGroup {
-      get { return Descriptor.FieldType == FieldType.Group ? "Group" : "Message"; }
-    }
-
-    /// <summary>
-    /// Returns the type name as used in CodedInputStream method names: SFixed32, UInt32 etc.
-    /// </summary>
-    protected string CapitalizedTypeName {
-      get {
-        // Our enum names match perfectly. How serendipitous.
-        return Descriptor.FieldType.ToString();
-      }
-    }
-  }
-}
+#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 Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal abstract class FieldGeneratorBase : SourceGeneratorBase<FieldDescriptor>
+    {
+        protected FieldGeneratorBase(FieldDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        public abstract void WriteHash(TextGenerator writer);
+        public abstract void WriteEquals(TextGenerator writer);
+        public abstract void WriteToString(TextGenerator writer);
+
+        private static bool AllPrintableAscii(string text)
+        {
+            foreach (char c in text)
+            {
+                if (c < 0x20 || c > 0x7e)
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /// <remarks>Copy exists in ExtensionGenerator.cs</remarks>
+        protected string DefaultValue
+        {
+            get
+            {
+                string suffix = "";
+                switch (Descriptor.FieldType)
+                {
+                    case FieldType.Float:
+                        suffix = "F";
+                        break;
+                    case FieldType.Double:
+                        suffix = "D";
+                        break;
+                    case FieldType.Int64:
+                        suffix = "L";
+                        break;
+                    case FieldType.UInt64:
+                        suffix = "UL";
+                        break;
+                }
+                switch (Descriptor.FieldType)
+                {
+                    case FieldType.Float:
+                    case FieldType.Double:
+                    case FieldType.Int32:
+                    case FieldType.Int64:
+                    case FieldType.SInt32:
+                    case FieldType.SInt64:
+                    case FieldType.SFixed32:
+                    case FieldType.SFixed64:
+                    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.
+                            IConvertible value = (IConvertible) Descriptor.DefaultValue;
+                            //a few things that must be handled explicitly
+                            if (Descriptor.FieldType == FieldType.Double && value is double)
+                            {
+                                if (double.IsNaN((double) value))
+                                    return "double.NaN";
+                                if (double.IsPositiveInfinity((double) value))
+                                    return "double.PositiveInfinity";
+                                if (double.IsNegativeInfinity((double) value))
+                                    return "double.NegativeInfinity";
+                            }
+                            else if (Descriptor.FieldType == FieldType.Float && value is float)
+                            {
+                                if (float.IsNaN((float) value))
+                                    return "float.NaN";
+                                if (float.IsPositiveInfinity((float) value))
+                                    return "float.PositiveInfinity";
+                                if (float.IsNegativeInfinity((float) value))
+                                    return "float.NegativeInfinity";
+                            }
+                            return value.ToString(CultureInfo.InvariantCulture) + suffix;
+                        }
+                    case FieldType.Bool:
+                        return (bool) Descriptor.DefaultValue ? "true" : "false";
+
+                    case FieldType.Bytes:
+                        if (!Descriptor.HasDefaultValue)
+                        {
+                            return "pb::ByteString.Empty";
+                        }
+                        if (UseLiteRuntime && Descriptor.DefaultValue is ByteString)
+                        {
+                            string temp = Convert.ToBase64String(((ByteString) Descriptor.DefaultValue).ToByteArray());
+                            return String.Format("ByteString.FromBase64(\"{0}\")", temp);
+                        }
+                        return string.Format("(pb::ByteString) {0}.Descriptor.Fields[{1}].DefaultValue",
+                                             GetClassName(Descriptor.ContainingType), Descriptor.Index);
+                    case FieldType.String:
+                        if (AllPrintableAscii(Descriptor.Proto.DefaultValue))
+                        {
+                            // All chars are ASCII and printable.  In this case we only
+                            // need to escape quotes and backslashes.
+                            return "\"" + Descriptor.Proto.DefaultValue
+                                              .Replace("\\", "\\\\")
+                                              .Replace("'", "\\'")
+                                              .Replace("\"", "\\\"")
+                                   + "\"";
+                        }
+                        if (UseLiteRuntime && Descriptor.DefaultValue is String)
+                        {
+                            string temp =
+                                Convert.ToBase64String(
+                                    System.Text.Encoding.UTF8.GetBytes((String) Descriptor.DefaultValue));
+                            return String.Format("ByteString.FromBase64(\"{0}\").ToStringUtf8()", temp);
+                        }
+                        return string.Format("(string) {0}.Descriptor.Fields[{1}].DefaultValue",
+                                             GetClassName(Descriptor.ContainingType), Descriptor.Index);
+                    case FieldType.Enum:
+                        return TypeName + "." + ((EnumValueDescriptor) Descriptor.DefaultValue).Name;
+                    case FieldType.Message:
+                    case FieldType.Group:
+                        return TypeName + ".DefaultInstance";
+                    default:
+                        throw new InvalidOperationException("Invalid field descriptor type");
+                }
+            }
+        }
+
+        protected string PropertyName
+        {
+            get { return Descriptor.CSharpOptions.PropertyName; }
+        }
+
+        protected string Name
+        {
+            get { return NameHelpers.UnderscoresToCamelCase(GetFieldName(Descriptor)); }
+        }
+
+        protected int Number
+        {
+            get { return Descriptor.FieldNumber; }
+        }
+
+        protected void AddNullCheck(TextGenerator writer)
+        {
+            AddNullCheck(writer, "value");
+        }
+
+        protected void AddNullCheck(TextGenerator writer, string name)
+        {
+            if (IsNullableType)
+            {
+                writer.WriteLine("  pb::ThrowHelper.ThrowIfNull({0}, \"{0}\");", name);
+            }
+        }
+
+        protected void AddClsComplianceCheck(TextGenerator writer)
+        {
+            if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance)
+            {
+                writer.WriteLine("[global::System.CLSCompliant(false)]");
+            }
+        }
+
+        /// <summary>
+        /// For encodings with fixed sizes, returns that size in bytes.  Otherwise
+        /// returns -1. TODO(jonskeet): Make this less ugly.
+        /// </summary>
+        protected int FixedSize
+        {
+            get
+            {
+                switch (Descriptor.FieldType)
+                {
+                    case FieldType.UInt32:
+                    case FieldType.UInt64:
+                    case FieldType.Int32:
+                    case FieldType.Int64:
+                    case FieldType.SInt32:
+                    case FieldType.SInt64:
+                    case FieldType.Enum:
+                    case FieldType.Bytes:
+                    case FieldType.String:
+                    case FieldType.Message:
+                    case FieldType.Group:
+                        return -1;
+                    case FieldType.Float:
+                        return WireFormat.FloatSize;
+                    case FieldType.SFixed32:
+                        return WireFormat.SFixed32Size;
+                    case FieldType.Fixed32:
+                        return WireFormat.Fixed32Size;
+                    case FieldType.Double:
+                        return WireFormat.DoubleSize;
+                    case FieldType.SFixed64:
+                        return WireFormat.SFixed64Size;
+                    case FieldType.Fixed64:
+                        return WireFormat.Fixed64Size;
+                    case FieldType.Bool:
+                        return WireFormat.BoolSize;
+                    default:
+                        throw new InvalidOperationException("Invalid field descriptor type");
+                }
+            }
+        }
+
+        protected bool IsNullableType
+        {
+            get
+            {
+                switch (Descriptor.FieldType)
+                {
+                    case FieldType.Float:
+                    case FieldType.Double:
+                    case FieldType.Int32:
+                    case FieldType.Int64:
+                    case FieldType.SInt32:
+                    case FieldType.SInt64:
+                    case FieldType.SFixed32:
+                    case FieldType.SFixed64:
+                    case FieldType.UInt32:
+                    case FieldType.UInt64:
+                    case FieldType.Fixed32:
+                    case FieldType.Fixed64:
+                    case FieldType.Bool:
+                    case FieldType.Enum:
+                        return false;
+                    case FieldType.Bytes:
+                    case FieldType.String:
+                    case FieldType.Message:
+                    case FieldType.Group:
+                        return true;
+                    default:
+                        throw new InvalidOperationException("Invalid field descriptor type");
+                }
+            }
+        }
+
+        protected string TypeName
+        {
+            get
+            {
+                switch (Descriptor.FieldType)
+                {
+                    case FieldType.Enum:
+                        return GetClassName(Descriptor.EnumType);
+                    case FieldType.Message:
+                    case FieldType.Group:
+                        return GetClassName(Descriptor.MessageType);
+                    default:
+                        return DescriptorUtil.GetMappedTypeName(Descriptor.MappedType);
+                }
+            }
+        }
+
+        protected string MessageOrGroup
+        {
+            get { return Descriptor.FieldType == FieldType.Group ? "Group" : "Message"; }
+        }
+
+        /// <summary>
+        /// Returns the type name as used in CodedInputStream method names: SFixed32, UInt32 etc.
+        /// </summary>
+        protected string CapitalizedTypeName
+        {
+            get
+            {
+                // Our enum names match perfectly. How serendipitous.
+                return Descriptor.FieldType.ToString();
+            }
+        }
+    }
+}

+ 246 - 209
src/ProtoGen/Generator.cs

@@ -1,209 +1,246 @@
-#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.Collections.Generic;
-using System.Text;
-using Google.ProtocolBuffers.DescriptorProtos;
-using System.IO;
-using Google.ProtocolBuffers.Descriptors;
-using Google.ProtocolBuffers.Collections;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  /// <summary>
-  /// Code generator for protocol buffers. Only C# is supported at the moment.
-  /// </summary>
-  public sealed class Generator {
-
-    private readonly GeneratorOptions options;
-
-    private Generator(GeneratorOptions options) {
-      options.Validate();
-      this.options = options;
-    }
-
-    /// <summary>
-    /// Returns a generator configured with the specified options.
-    /// </summary>
-    public static Generator CreateGenerator(GeneratorOptions options) {
-      return new Generator(options);
-    }
-
-    public void Generate() {        
-      List<FileDescriptorSet> descriptorProtos = new List<FileDescriptorSet>();
-      foreach (string inputFile in options.InputFiles) {
-        ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
-        CSharpOptions.RegisterAllExtensions(extensionRegistry);
-        using (Stream inputStream = File.OpenRead(inputFile)) {
-            descriptorProtos.Add(FileDescriptorSet.ParseFrom(inputStream, extensionRegistry));
-        }
-      }
-      
-      IList<FileDescriptor> descriptors = ConvertDescriptors(options.FileOptions, descriptorProtos.ToArray());
-
-      // Combine with options from command line
-      foreach (FileDescriptor descriptor in descriptors) {
-        descriptor.ConfigureWithDefaultOptions(options.FileOptions);
-      }
-
-      foreach (FileDescriptor descriptor in descriptors) {
-        // Optionally exclude descriptors in google.protobuf
-        if (descriptor.CSharpOptions.IgnoreGoogleProtobuf && descriptor.Package == "google.protobuf") {
-          continue;
-        }
-        Generate(descriptor);
-      }
-    }
-
-    /// <summary>
-    /// Generates code for a particular file. All dependencies must
-    /// already have been resolved.
-    /// </summary>
-    private void Generate(FileDescriptor descriptor) {
-      UmbrellaClassGenerator ucg = new UmbrellaClassGenerator(descriptor);
-      using (TextWriter textWriter = File.CreateText(GetOutputFile(descriptor))) {
-        TextGenerator writer = new TextGenerator(textWriter, options.LineBreak);
-        ucg.Generate(writer);
-      }
-    }
-
-    private string GetOutputFile(FileDescriptor descriptor) {
-      CSharpFileOptions fileOptions = descriptor.CSharpOptions;
-
-      string filename = descriptor.CSharpOptions.UmbrellaClassname + descriptor.CSharpOptions.FileExtension;
-
-      string outputDirectory = descriptor.CSharpOptions.OutputDirectory;
-      if (fileOptions.ExpandNamespaceDirectories) {
-        string package = fileOptions.Namespace;
-        if (!string.IsNullOrEmpty(package)) {
-          string[] bits = package.Split('.');
-          foreach (string bit in bits) {
-            outputDirectory = Path.Combine(outputDirectory, bit);
-          }
-        }
-      }
-      
-      // As the directory can be explicitly specified in options, we need to make sure it exists
-      Directory.CreateDirectory(outputDirectory);
-      return Path.Combine(outputDirectory, filename);
-    }
-
-    /// <summary>
-    /// Resolves any dependencies and converts FileDescriptorProtos into FileDescriptors.
-    /// The list returned is in the same order as the protos are listed in the descriptor set.
-    /// Note: this method is internal rather than private to allow testing.
-    /// </summary>
-    /// <exception cref="DependencyResolutionException">Not all dependencies could be resolved.</exception>
-    public static IList<FileDescriptor> ConvertDescriptors(CSharpFileOptions options, params FileDescriptorSet[] descriptorProtos) {
-      // Simple strategy: Keep going through the list of protos to convert, only doing ones where
-      // we've already converted all the dependencies, until we get to a stalemate
-      List<FileDescriptorProto> fileList = new List<FileDescriptorProto>();
-      foreach (FileDescriptorSet set in descriptorProtos)
-        fileList.AddRange(set.FileList);
-
-      FileDescriptor[] converted = new FileDescriptor[fileList.Count];
-
-      Dictionary<string, FileDescriptor> convertedMap = new Dictionary<string, FileDescriptor>();
-
-      int totalConverted = 0;
-
-      bool madeProgress = true;
-      while (madeProgress && totalConverted < converted.Length) {
-        madeProgress = false;
-        for (int i = 0; i < converted.Length; i++) {
-          if (converted[i] != null) {
-            // Already done this one
-            continue;
-          }
-          FileDescriptorProto candidate = fileList[i];
-          FileDescriptor[] dependencies = new FileDescriptor[candidate.DependencyList.Count];
-
-            
-          CSharpFileOptions.Builder builder = options.ToBuilder();
-          if (candidate.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions)) {
-            builder.MergeFrom(candidate.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions));
-          }
-          CSharpFileOptions localOptions = builder.Build();
-
-          bool foundAllDependencies = true;
-          for (int j = 0; j < dependencies.Length; j++) {
-            if (!convertedMap.TryGetValue(candidate.DependencyList[j], out dependencies[j])) {
-              // We can auto-magically resolve these since we already have their description
-              // This way if the file is only referencing options it does not need to be built with the
-              // --include_imports definition.
-              if (localOptions.IgnoreGoogleProtobuf && (candidate.DependencyList[j] == "google/protobuf/csharp_options.proto")) {
-                dependencies[j] = CSharpOptions.Descriptor;
-                continue;
-              }
-              if (localOptions.IgnoreGoogleProtobuf && (candidate.DependencyList[j] == "google/protobuf/descriptor.proto")) {
-                dependencies[j] = DescriptorProtoFile.Descriptor;
-                continue;
-              }
-              foundAllDependencies = false;
-              break;
-            }
-          }
-          if (!foundAllDependencies) {
-            continue;
-          }
-          madeProgress = true;
-          totalConverted++;
-          converted[i] = FileDescriptor.BuildFrom(candidate, dependencies);
-          convertedMap[candidate.Name] = converted[i];
-        }
-      }
-      if (!madeProgress) {
-        StringBuilder remaining = new StringBuilder();
-        for (int i = 0; i < converted.Length; i++) {
-          if (converted[i] == null) {
-            if (remaining.Length != 0) {
-              remaining.Append(", ");
-            }
-            FileDescriptorProto failure = fileList[i];
-            remaining.Append(failure.Name);
-            remaining.Append(":");
-            foreach (string dependency in failure.DependencyList) {
-              if (!convertedMap.ContainsKey(dependency)) {
-                remaining.Append(" ");
-                remaining.Append(dependency);
-              }
-            }
-            remaining.Append(";");
-          }
-        }
-        throw new DependencyResolutionException("Unable to resolve all dependencies: " + remaining);
-      }
-      return Lists.AsReadOnly(converted);
-    }
-  }
-}
+#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.Collections.Generic;
+using System.Text;
+using Google.ProtocolBuffers.DescriptorProtos;
+using System.IO;
+using Google.ProtocolBuffers.Descriptors;
+using Google.ProtocolBuffers.Collections;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// Code generator for protocol buffers. Only C# is supported at the moment.
+    /// </summary>
+    public sealed class Generator
+    {
+        private readonly GeneratorOptions options;
+
+        private Generator(GeneratorOptions options)
+        {
+            options.Validate();
+            this.options = options;
+        }
+
+        /// <summary>
+        /// Returns a generator configured with the specified options.
+        /// </summary>
+        public static Generator CreateGenerator(GeneratorOptions options)
+        {
+            return new Generator(options);
+        }
+
+        public void Generate()
+        {
+            List<FileDescriptorSet> descriptorProtos = new List<FileDescriptorSet>();
+            foreach (string inputFile in options.InputFiles)
+            {
+                ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
+                CSharpOptions.RegisterAllExtensions(extensionRegistry);
+                using (Stream inputStream = File.OpenRead(inputFile))
+                {
+                    descriptorProtos.Add(FileDescriptorSet.ParseFrom(inputStream, extensionRegistry));
+                }
+            }
+
+            IList<FileDescriptor> descriptors = ConvertDescriptors(options.FileOptions, descriptorProtos.ToArray());
+
+            // Combine with options from command line
+            foreach (FileDescriptor descriptor in descriptors)
+            {
+                descriptor.ConfigureWithDefaultOptions(options.FileOptions);
+            }
+
+            foreach (FileDescriptor descriptor in descriptors)
+            {
+                // Optionally exclude descriptors in google.protobuf
+                if (descriptor.CSharpOptions.IgnoreGoogleProtobuf && descriptor.Package == "google.protobuf")
+                {
+                    continue;
+                }
+                Generate(descriptor);
+            }
+        }
+
+        /// <summary>
+        /// Generates code for a particular file. All dependencies must
+        /// already have been resolved.
+        /// </summary>
+        private void Generate(FileDescriptor descriptor)
+        {
+            UmbrellaClassGenerator ucg = new UmbrellaClassGenerator(descriptor);
+            using (TextWriter textWriter = File.CreateText(GetOutputFile(descriptor)))
+            {
+                TextGenerator writer = new TextGenerator(textWriter, options.LineBreak);
+                ucg.Generate(writer);
+            }
+        }
+
+        private string GetOutputFile(FileDescriptor descriptor)
+        {
+            CSharpFileOptions fileOptions = descriptor.CSharpOptions;
+
+            string filename = descriptor.CSharpOptions.UmbrellaClassname + descriptor.CSharpOptions.FileExtension;
+
+            string outputDirectory = descriptor.CSharpOptions.OutputDirectory;
+            if (fileOptions.ExpandNamespaceDirectories)
+            {
+                string package = fileOptions.Namespace;
+                if (!string.IsNullOrEmpty(package))
+                {
+                    string[] bits = package.Split('.');
+                    foreach (string bit in bits)
+                    {
+                        outputDirectory = Path.Combine(outputDirectory, bit);
+                    }
+                }
+            }
+
+            // As the directory can be explicitly specified in options, we need to make sure it exists
+            Directory.CreateDirectory(outputDirectory);
+            return Path.Combine(outputDirectory, filename);
+        }
+
+        /// <summary>
+        /// Resolves any dependencies and converts FileDescriptorProtos into FileDescriptors.
+        /// The list returned is in the same order as the protos are listed in the descriptor set.
+        /// Note: this method is internal rather than private to allow testing.
+        /// </summary>
+        /// <exception cref="DependencyResolutionException">Not all dependencies could be resolved.</exception>
+        public static IList<FileDescriptor> ConvertDescriptors(CSharpFileOptions options,
+                                                               params FileDescriptorSet[] descriptorProtos)
+        {
+            // Simple strategy: Keep going through the list of protos to convert, only doing ones where
+            // we've already converted all the dependencies, until we get to a stalemate
+            List<FileDescriptorProto> fileList = new List<FileDescriptorProto>();
+            foreach (FileDescriptorSet set in descriptorProtos)
+                fileList.AddRange(set.FileList);
+
+            FileDescriptor[] converted = new FileDescriptor[fileList.Count];
+
+            Dictionary<string, FileDescriptor> convertedMap = new Dictionary<string, FileDescriptor>();
+
+            int totalConverted = 0;
+
+            bool madeProgress = true;
+            while (madeProgress && totalConverted < converted.Length)
+            {
+                madeProgress = false;
+                for (int i = 0; i < converted.Length; i++)
+                {
+                    if (converted[i] != null)
+                    {
+                        // Already done this one
+                        continue;
+                    }
+                    FileDescriptorProto candidate = fileList[i];
+                    FileDescriptor[] dependencies = new FileDescriptor[candidate.DependencyList.Count];
+
+
+                    CSharpFileOptions.Builder builder = options.ToBuilder();
+                    if (candidate.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions))
+                    {
+                        builder.MergeFrom(
+                            candidate.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions));
+                    }
+                    CSharpFileOptions localOptions = builder.Build();
+
+                    bool foundAllDependencies = true;
+                    for (int j = 0; j < dependencies.Length; j++)
+                    {
+                        if (!convertedMap.TryGetValue(candidate.DependencyList[j], out dependencies[j]))
+                        {
+                            // We can auto-magically resolve these since we already have their description
+                            // This way if the file is only referencing options it does not need to be built with the
+                            // --include_imports definition.
+                            if (localOptions.IgnoreGoogleProtobuf &&
+                                (candidate.DependencyList[j] == "google/protobuf/csharp_options.proto"))
+                            {
+                                dependencies[j] = CSharpOptions.Descriptor;
+                                continue;
+                            }
+                            if (localOptions.IgnoreGoogleProtobuf &&
+                                (candidate.DependencyList[j] == "google/protobuf/descriptor.proto"))
+                            {
+                                dependencies[j] = DescriptorProtoFile.Descriptor;
+                                continue;
+                            }
+                            foundAllDependencies = false;
+                            break;
+                        }
+                    }
+                    if (!foundAllDependencies)
+                    {
+                        continue;
+                    }
+                    madeProgress = true;
+                    totalConverted++;
+                    converted[i] = FileDescriptor.BuildFrom(candidate, dependencies);
+                    convertedMap[candidate.Name] = converted[i];
+                }
+            }
+            if (!madeProgress)
+            {
+                StringBuilder remaining = new StringBuilder();
+                for (int i = 0; i < converted.Length; i++)
+                {
+                    if (converted[i] == null)
+                    {
+                        if (remaining.Length != 0)
+                        {
+                            remaining.Append(", ");
+                        }
+                        FileDescriptorProto failure = fileList[i];
+                        remaining.Append(failure.Name);
+                        remaining.Append(":");
+                        foreach (string dependency in failure.DependencyList)
+                        {
+                            if (!convertedMap.ContainsKey(dependency))
+                            {
+                                remaining.Append(" ");
+                                remaining.Append(dependency);
+                            }
+                        }
+                        remaining.Append(";");
+                    }
+                }
+                throw new DependencyResolutionException("Unable to resolve all dependencies: " + remaining);
+            }
+            return Lists.AsReadOnly(converted);
+        }
+    }
+}

+ 329 - 284
src/ProtoGen/GeneratorOptions.cs

@@ -1,285 +1,330 @@
-#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 System.Text.RegularExpressions;
-using Google.ProtocolBuffers.DescriptorProtos;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  /// <summary>
-  /// All the configuration required for the generator - where to generate
-  /// output files, the location of input files etc. While this isn't immutable
-  /// in practice, the contents shouldn't be changed after being passed to
-  /// the generator.
-  /// </summary>
-  public sealed class GeneratorOptions {
-
-    private static Dictionary<string, string> LineBreaks = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) {
-      { "Windows", "\r\n" },
-      { "Unix", "\n" },
-      { "Default", Environment.NewLine }
-    };
-
-    public IList<string> InputFiles { get; set; }
-
-    public GeneratorOptions() {
-      LineBreak = Environment.NewLine;
-    }
-
-      /// <summary>
-    /// Attempts to validate the options, but doesn't throw an exception if they're invalid.
-    /// Instead, when this method returns false, the output variable will contain a collection
-    /// of reasons for the validation failure.
-    /// </summary>
-    /// <param name="reasons">Variable to receive a list of reasons in case of validation failure.</param>
-    /// <returns>true if the options are valid; false otherwise</returns>
-    public bool TryValidate(out IList<string> reasons) {
-      List<string> tmpReasons = new List<string>();
-
-      ParseArguments(tmpReasons);
-
-      // Output directory validation
-      if (string.IsNullOrEmpty(FileOptions.OutputDirectory)) {
-        tmpReasons.Add("No output directory specified");
-      }
-      else {
-        if (!Directory.Exists(FileOptions.OutputDirectory)) {
-          tmpReasons.Add("Specified output directory (" + FileOptions.OutputDirectory + " doesn't exist.");
-        }
-      }
-
-      // Input file validation (just in terms of presence)
-      if (InputFiles == null || InputFiles.Count == 0) {
-        tmpReasons.Add("No input files specified");
-      }
-      else {
-        foreach (string input in InputFiles) {
-          FileInfo fi = new FileInfo(input);
-          if (!fi.Exists) {
-            tmpReasons.Add("Input file " + input + " doesn't exist.");
-          }
-        }
-      }
-
-      if (tmpReasons.Count != 0) {
-        reasons = tmpReasons;
-        return false;
-      }
-
-      reasons = null;
-      return true;
-    }
-
-    /// <summary>
-    /// Validates that all the options have been set and are valid,
-    /// throwing an exception if they haven't.
-    /// </summary>
-    /// <exception cref="InvalidOptionsException">The options are invalid.</exception>
-    public void Validate() {
-      IList<string> reasons;
-      if (!TryValidate(out reasons)) {
-        throw new InvalidOptionsException(reasons);
-      }
-    }
-
-    // Raw arguments, used to provide defaults for proto file options
-    public IList<string> Arguments { get; set; }
-
-    [Obsolete("Please use GeneratorOptions.FileOptions.OutputDirectory instead")]
-    public string OutputDirectory {
-      get { return FileOptions.OutputDirectory; }
-      set {
-        CSharpFileOptions.Builder bld = FileOptions.ToBuilder();
-        bld.OutputDirectory = value;
-        FileOptions = bld.Build();
-      }
-    }
-
-    private static readonly Regex ArgMatch = new Regex(@"^[-/](?<name>[\w_]+?)[:=](?<value>.*)$");
-    private CSharpFileOptions fileOptions;
-
-    public CSharpFileOptions FileOptions {
-      get { return fileOptions ?? (fileOptions = CSharpFileOptions.DefaultInstance); }
-      set { fileOptions = value; }
-    }
-
-    public string LineBreak { get; set; }
-
-    private void ParseArguments(IList<string> tmpReasons) {
-      bool doHelp = Arguments.Count == 0;
-
-      InputFiles = new List<string>();
-      CSharpFileOptions.Builder builder = FileOptions.ToBuilder();
-      Dictionary<string, FieldDescriptor> fields =
-        new Dictionary<string, FieldDescriptor>(StringComparer.OrdinalIgnoreCase);
-      foreach (FieldDescriptor fld in builder.DescriptorForType.Fields) {
-        fields.Add(fld.Name, fld);
-      }
-
-      foreach (string argument in Arguments) {
-        if (StringComparer.OrdinalIgnoreCase.Equals("-help", argument) ||
-            StringComparer.OrdinalIgnoreCase.Equals("/help", argument) ||
-            StringComparer.OrdinalIgnoreCase.Equals("-?", argument) ||
-            StringComparer.OrdinalIgnoreCase.Equals("/?", argument)) {
-          doHelp = true;
-          break;
-        }
-
-        Match m = ArgMatch.Match(argument);
-        if (m.Success) {
-          FieldDescriptor fld;
-          string name = m.Groups["name"].Value;
-          string value = m.Groups["value"].Value;
-
-          if (fields.TryGetValue(name, out fld)) {
-            object obj;
-            if (TryCoerceType(value, fld, out obj, tmpReasons)) {
-              builder[fld] = obj;
-            }
-          } else if (name == "line_break") {
-            string tmp;
-            if (LineBreaks.TryGetValue(value, out tmp)) {
-              LineBreak = tmp;
-            } else {
-              tmpReasons.Add("Invalid value for 'line_break': " + value + ".");
-            }
-          } else if (!File.Exists(argument)) {
-            doHelp = true;
-            tmpReasons.Add("Unknown argument '" + name + "'.");
-          } else {
-            InputFiles.Add(argument);
-          }
-        }
-        else {
-          InputFiles.Add(argument);
-        }
-      }
-
-      if (doHelp || InputFiles.Count == 0) {
-        tmpReasons.Add("Arguments:");
-        foreach (KeyValuePair<string, FieldDescriptor> field in fields) {
-          tmpReasons.Add(String.Format("-{0}=[{1}]", field.Key, field.Value.FieldType));
-        }
-        tmpReasons.Add("-line_break=[" + string.Join("|", new List<string>(LineBreaks.Keys).ToArray()) + "]");
-        tmpReasons.Add("followed by one or more file paths.");
-      }
-      else {
-        FileOptions = builder.Build();
-      }
-    }
-
-    private static bool TryCoerceType(string text, FieldDescriptor field, out object value, IList<string> tmpReasons) {
-      value = null;
-
-      switch (field.FieldType) {
-        case FieldType.Int32:
-        case FieldType.SInt32:
-        case FieldType.SFixed32:
-          value = Int32.Parse(text);
-          break;
-
-        case FieldType.Int64:
-        case FieldType.SInt64:
-        case FieldType.SFixed64:
-          value = Int64.Parse(text);
-          break;
-
-        case FieldType.UInt32:
-        case FieldType.Fixed32:
-          value = UInt32.Parse(text);
-          break;
-
-        case FieldType.UInt64:
-        case FieldType.Fixed64:
-          value = UInt64.Parse(text);
-          break;
-
-        case FieldType.Float:
-          value = float.Parse(text);
-          break;
-
-        case FieldType.Double:
-          value = Double.Parse(text);
-          break;
-
-        case FieldType.Bool:
-          value = Boolean.Parse(text);
-          break;
-
-        case FieldType.String:
-          value = text;
-          break;
-
-        case FieldType.Enum: {
-          EnumDescriptor enumType = field.EnumType;
-
-          int number;
-          if (int.TryParse(text, out number)) {
-            value = enumType.FindValueByNumber(number);
-            if (value == null) {
-              tmpReasons.Add(
-                "Enum type \"" + enumType.FullName +
-                "\" has no value with number " + number + ".");
-              return false;
-            }
-          }
-          else {
-            value = enumType.FindValueByName(text);
-            if (value == null) {
-              tmpReasons.Add(
-                "Enum type \"" + enumType.FullName +
-                "\" has no value named \"" + text + "\".");
-              return false;
-            }
-          }
-
-          break;
-        }
-
-        case FieldType.Bytes:
-        case FieldType.Message:
-        case FieldType.Group:
-          tmpReasons.Add("Unhandled field type " + field.FieldType.ToString() + ".");
-          return false;
-      }
-
-      return 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.IO;
+using System.Text.RegularExpressions;
+using Google.ProtocolBuffers.DescriptorProtos;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// All the configuration required for the generator - where to generate
+    /// output files, the location of input files etc. While this isn't immutable
+    /// in practice, the contents shouldn't be changed after being passed to
+    /// the generator.
+    /// </summary>
+    public sealed class GeneratorOptions
+    {
+        private static Dictionary<string, string> LineBreaks =
+            new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
+                {
+                    {"Windows", "\r\n"},
+                    {"Unix", "\n"},
+                    {"Default", Environment.NewLine}
+                };
+
+        public IList<string> InputFiles { get; set; }
+
+        public GeneratorOptions()
+        {
+            LineBreak = Environment.NewLine;
+        }
+
+        /// <summary>
+        /// Attempts to validate the options, but doesn't throw an exception if they're invalid.
+        /// Instead, when this method returns false, the output variable will contain a collection
+        /// of reasons for the validation failure.
+        /// </summary>
+        /// <param name="reasons">Variable to receive a list of reasons in case of validation failure.</param>
+        /// <returns>true if the options are valid; false otherwise</returns>
+        public bool TryValidate(out IList<string> reasons)
+        {
+            List<string> tmpReasons = new List<string>();
+
+            ParseArguments(tmpReasons);
+
+            // Output directory validation
+            if (string.IsNullOrEmpty(FileOptions.OutputDirectory))
+            {
+                tmpReasons.Add("No output directory specified");
+            }
+            else
+            {
+                if (!Directory.Exists(FileOptions.OutputDirectory))
+                {
+                    tmpReasons.Add("Specified output directory (" + FileOptions.OutputDirectory + " doesn't exist.");
+                }
+            }
+
+            // Input file validation (just in terms of presence)
+            if (InputFiles == null || InputFiles.Count == 0)
+            {
+                tmpReasons.Add("No input files specified");
+            }
+            else
+            {
+                foreach (string input in InputFiles)
+                {
+                    FileInfo fi = new FileInfo(input);
+                    if (!fi.Exists)
+                    {
+                        tmpReasons.Add("Input file " + input + " doesn't exist.");
+                    }
+                }
+            }
+
+            if (tmpReasons.Count != 0)
+            {
+                reasons = tmpReasons;
+                return false;
+            }
+
+            reasons = null;
+            return true;
+        }
+
+        /// <summary>
+        /// Validates that all the options have been set and are valid,
+        /// throwing an exception if they haven't.
+        /// </summary>
+        /// <exception cref="InvalidOptionsException">The options are invalid.</exception>
+        public void Validate()
+        {
+            IList<string> reasons;
+            if (!TryValidate(out reasons))
+            {
+                throw new InvalidOptionsException(reasons);
+            }
+        }
+
+        // Raw arguments, used to provide defaults for proto file options
+        public IList<string> Arguments { get; set; }
+
+        [Obsolete("Please use GeneratorOptions.FileOptions.OutputDirectory instead")]
+        public string OutputDirectory
+        {
+            get { return FileOptions.OutputDirectory; }
+            set
+            {
+                CSharpFileOptions.Builder bld = FileOptions.ToBuilder();
+                bld.OutputDirectory = value;
+                FileOptions = bld.Build();
+            }
+        }
+
+        private static readonly Regex ArgMatch = new Regex(@"^[-/](?<name>[\w_]+?)[:=](?<value>.*)$");
+        private CSharpFileOptions fileOptions;
+
+        public CSharpFileOptions FileOptions
+        {
+            get { return fileOptions ?? (fileOptions = CSharpFileOptions.DefaultInstance); }
+            set { fileOptions = value; }
+        }
+
+        public string LineBreak { get; set; }
+
+        private void ParseArguments(IList<string> tmpReasons)
+        {
+            bool doHelp = Arguments.Count == 0;
+
+            InputFiles = new List<string>();
+            CSharpFileOptions.Builder builder = FileOptions.ToBuilder();
+            Dictionary<string, FieldDescriptor> fields =
+                new Dictionary<string, FieldDescriptor>(StringComparer.OrdinalIgnoreCase);
+            foreach (FieldDescriptor fld in builder.DescriptorForType.Fields)
+            {
+                fields.Add(fld.Name, fld);
+            }
+
+            foreach (string argument in Arguments)
+            {
+                if (StringComparer.OrdinalIgnoreCase.Equals("-help", argument) ||
+                    StringComparer.OrdinalIgnoreCase.Equals("/help", argument) ||
+                    StringComparer.OrdinalIgnoreCase.Equals("-?", argument) ||
+                    StringComparer.OrdinalIgnoreCase.Equals("/?", argument))
+                {
+                    doHelp = true;
+                    break;
+                }
+
+                Match m = ArgMatch.Match(argument);
+                if (m.Success)
+                {
+                    FieldDescriptor fld;
+                    string name = m.Groups["name"].Value;
+                    string value = m.Groups["value"].Value;
+
+                    if (fields.TryGetValue(name, out fld))
+                    {
+                        object obj;
+                        if (TryCoerceType(value, fld, out obj, tmpReasons))
+                        {
+                            builder[fld] = obj;
+                        }
+                    }
+                    else if (name == "line_break")
+                    {
+                        string tmp;
+                        if (LineBreaks.TryGetValue(value, out tmp))
+                        {
+                            LineBreak = tmp;
+                        }
+                        else
+                        {
+                            tmpReasons.Add("Invalid value for 'line_break': " + value + ".");
+                        }
+                    }
+                    else if (!File.Exists(argument))
+                    {
+                        doHelp = true;
+                        tmpReasons.Add("Unknown argument '" + name + "'.");
+                    }
+                    else
+                    {
+                        InputFiles.Add(argument);
+                    }
+                }
+                else
+                {
+                    InputFiles.Add(argument);
+                }
+            }
+
+            if (doHelp || InputFiles.Count == 0)
+            {
+                tmpReasons.Add("Arguments:");
+                foreach (KeyValuePair<string, FieldDescriptor> field in fields)
+                {
+                    tmpReasons.Add(String.Format("-{0}=[{1}]", field.Key, field.Value.FieldType));
+                }
+                tmpReasons.Add("-line_break=[" + string.Join("|", new List<string>(LineBreaks.Keys).ToArray()) + "]");
+                tmpReasons.Add("followed by one or more file paths.");
+            }
+            else
+            {
+                FileOptions = builder.Build();
+            }
+        }
+
+        private static bool TryCoerceType(string text, FieldDescriptor field, out object value, IList<string> tmpReasons)
+        {
+            value = null;
+
+            switch (field.FieldType)
+            {
+                case FieldType.Int32:
+                case FieldType.SInt32:
+                case FieldType.SFixed32:
+                    value = Int32.Parse(text);
+                    break;
+
+                case FieldType.Int64:
+                case FieldType.SInt64:
+                case FieldType.SFixed64:
+                    value = Int64.Parse(text);
+                    break;
+
+                case FieldType.UInt32:
+                case FieldType.Fixed32:
+                    value = UInt32.Parse(text);
+                    break;
+
+                case FieldType.UInt64:
+                case FieldType.Fixed64:
+                    value = UInt64.Parse(text);
+                    break;
+
+                case FieldType.Float:
+                    value = float.Parse(text);
+                    break;
+
+                case FieldType.Double:
+                    value = Double.Parse(text);
+                    break;
+
+                case FieldType.Bool:
+                    value = Boolean.Parse(text);
+                    break;
+
+                case FieldType.String:
+                    value = text;
+                    break;
+
+                case FieldType.Enum:
+                    {
+                        EnumDescriptor enumType = field.EnumType;
+
+                        int number;
+                        if (int.TryParse(text, out number))
+                        {
+                            value = enumType.FindValueByNumber(number);
+                            if (value == null)
+                            {
+                                tmpReasons.Add(
+                                    "Enum type \"" + enumType.FullName +
+                                    "\" has no value with number " + number + ".");
+                                return false;
+                            }
+                        }
+                        else
+                        {
+                            value = enumType.FindValueByName(text);
+                            if (value == null)
+                            {
+                                tmpReasons.Add(
+                                    "Enum type \"" + enumType.FullName +
+                                    "\" has no value named \"" + text + "\".");
+                                return false;
+                            }
+                        }
+
+                        break;
+                    }
+
+                case FieldType.Bytes:
+                case FieldType.Message:
+                case FieldType.Group:
+                    tmpReasons.Add("Unhandled field type " + field.FieldType.ToString() + ".");
+                    return false;
+            }
+
+            return true;
+        }
+    }
 }

+ 45 - 42
src/ProtoGen/Helpers.cs

@@ -1,42 +1,45 @@
-#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
-
-namespace Google.ProtocolBuffers.ProtoGen {
-
-  /// <summary>
-  /// Helpers to resolve class names etc.
-  /// </summary>
-  internal static class Helpers {
-  }
-}
+#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
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// Helpers to resolve class names etc.
+    /// </summary>
+    internal static class Helpers
+    {
+    }
+}

+ 53 - 49
src/ProtoGen/IFieldSourceGenerator.cs

@@ -1,49 +1,53 @@
-#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
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal interface IFieldSourceGenerator {
-    void GenerateMembers(TextGenerator writer);
-    void GenerateBuilderMembers(TextGenerator writer);
-    void GenerateMergingCode(TextGenerator writer);
-    void GenerateBuildingCode(TextGenerator writer);
-    void GenerateParsingCode(TextGenerator writer);
-    void GenerateSerializationCode(TextGenerator writer);
-    void GenerateSerializedSizeCode(TextGenerator writer);
-
-    void WriteHash(TextGenerator writer);
-    void WriteEquals(TextGenerator writer);
-    void WriteToString(TextGenerator writer);
-  }
-}
+#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
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal interface IFieldSourceGenerator
+    {
+        void GenerateMembers(TextGenerator writer);
+        void GenerateBuilderMembers(TextGenerator writer);
+        void GenerateMergingCode(TextGenerator writer);
+        void GenerateBuildingCode(TextGenerator writer);
+        void GenerateParsingCode(TextGenerator writer);
+        void GenerateSerializationCode(TextGenerator writer);
+        void GenerateSerializedSizeCode(TextGenerator writer);
+
+        void WriteHash(TextGenerator writer);
+        void WriteEquals(TextGenerator writer);
+        void WriteToString(TextGenerator writer);
+    }
+}

+ 43 - 39
src/ProtoGen/ISourceGenerator.cs

@@ -1,39 +1,43 @@
-#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
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal interface ISourceGenerator {
-    void Generate(TextGenerator writer);
-  }
-}
+#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
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal interface ISourceGenerator
+    {
+        void Generate(TextGenerator writer);
+    }
+}

+ 77 - 70
src/ProtoGen/InvalidOptionsException.cs

@@ -1,70 +1,77 @@
-#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.Collections;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  /// <summary>
-  /// Exception thrown to indicate that the options passed were invalid.
-  /// </summary>
-  public sealed class InvalidOptionsException : Exception {
-
-    private readonly IList<string> reasons;
-
-    /// <summary>
-    /// An immutable list of reasons why the options were invalid.
-    /// </summary>
-    public IList<string> Reasons {
-      get { return reasons; }
-    }
-
-    public InvalidOptionsException(IList<string> reasons) 
-        : base(BuildMessage(reasons)) {
-      this.reasons = Lists.AsReadOnly(reasons);
-    }
-
-    private static string BuildMessage(IEnumerable<string> reasons) {
-      StringBuilder builder = new StringBuilder("Invalid options:");
-      builder.AppendLine();
-      foreach (string reason in reasons) {
-        builder.Append("  ");
-        builder.AppendLine(reason);
-      }
-      return builder.ToString();
-    }
-  }
-}
+#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.Collections;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// Exception thrown to indicate that the options passed were invalid.
+    /// </summary>
+    public sealed class InvalidOptionsException : Exception
+    {
+        private readonly IList<string> reasons;
+
+        /// <summary>
+        /// An immutable list of reasons why the options were invalid.
+        /// </summary>
+        public IList<string> Reasons
+        {
+            get { return reasons; }
+        }
+
+        public InvalidOptionsException(IList<string> reasons)
+            : base(BuildMessage(reasons))
+        {
+            this.reasons = Lists.AsReadOnly(reasons);
+        }
+
+        private static string BuildMessage(IEnumerable<string> reasons)
+        {
+            StringBuilder builder = new StringBuilder("Invalid options:");
+            builder.AppendLine();
+            foreach (string reason in reasons)
+            {
+                builder.Append("  ");
+                builder.AppendLine(reason);
+            }
+            return builder.ToString();
+        }
+    }
+}

+ 161 - 142
src/ProtoGen/MessageFieldGenerator.cs

@@ -1,142 +1,161 @@
-#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.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class MessageFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator {
-
-    internal MessageFieldGenerator(FieldDescriptor descriptor)
-      : base(descriptor) {
-    }
-
-    public void GenerateMembers(TextGenerator writer) {
-      writer.WriteLine("private bool has{0};", PropertyName);
-      writer.WriteLine("private {0} {1}_ = {2};", TypeName, Name, DefaultValue);
-      writer.WriteLine("public bool Has{0} {{", PropertyName);
-      writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
-      writer.WriteLine("}");
-      writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return {0}_; }}", Name);
-      writer.WriteLine("}");
-    }
-    
-    public void GenerateBuilderMembers(TextGenerator writer) {
-      writer.WriteLine("public bool Has{0} {{", PropertyName);
-      writer.WriteLine(" get {{ return result.Has{0}; }}", PropertyName);
-      writer.WriteLine("}");
-      writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
-      writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
-      AddNullCheck(writer);
-      writer.WriteLine("  result.has{0} = true;", PropertyName);
-      writer.WriteLine("  result.{0}_ = value;", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Set{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
-      AddNullCheck(writer, "builderForValue");
-      writer.WriteLine("  result.has{0} = true;", PropertyName);
-      writer.WriteLine("  result.{0}_ = builderForValue.Build();", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Merge{0}({1} value) {{", PropertyName, TypeName);
-      AddNullCheck(writer);
-      writer.WriteLine("  if (result.Has{0} &&", PropertyName);
-      writer.WriteLine("      result.{0}_ != {1}) {{", Name, DefaultValue);
-      writer.WriteLine("      result.{0}_ = {1}.CreateBuilder(result.{0}_).MergeFrom(value).BuildPartial();", Name, TypeName);
-      writer.WriteLine("  } else {");
-      writer.WriteLine("    result.{0}_ = value;", Name);
-      writer.WriteLine("  }");
-      writer.WriteLine("  result.has{0} = true;", PropertyName);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
-      writer.WriteLine("  result.has{0} = false;", PropertyName);
-      writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-    }
-
-    public void GenerateMergingCode(TextGenerator writer) {
-      writer.WriteLine("if (other.Has{0}) {{", PropertyName);
-      writer.WriteLine("  Merge{0}(other.{0});", PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuildingCode(TextGenerator writer) {
-      // Nothing to do for singular fields
-    }
-
-    public void GenerateParsingCode(TextGenerator writer) {
-      writer.WriteLine("{0}.Builder subBuilder = {0}.CreateBuilder();", TypeName);
-      writer.WriteLine("if (Has{0}) {{", PropertyName);
-      writer.WriteLine("  subBuilder.MergeFrom({0});", PropertyName);
-      writer.WriteLine("}");
-      if (Descriptor.FieldType == FieldType.Group) {
-        writer.WriteLine("input.ReadGroup({0}, subBuilder, extensionRegistry);", Number);
-      } else {
-        writer.WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");
-      }
-      writer.WriteLine("{0} = subBuilder.BuildPartial();", PropertyName);
-    }
-
-    public void GenerateSerializationCode(TextGenerator writer) {
-      writer.WriteLine("if (Has{0}) {{", PropertyName);
-      writer.WriteLine("  output.Write{0}({1}, {2});", MessageOrGroup, Number, PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateSerializedSizeCode(TextGenerator writer) {
-      writer.WriteLine("if (Has{0}) {{", PropertyName);
-      writer.WriteLine("  size += pb::CodedOutputStream.Compute{0}Size({1}, {2});",
-          MessageOrGroup, Number, PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public override void WriteHash(TextGenerator writer) {
-      writer.WriteLine("if (has{0}) hash ^= {1}_.GetHashCode();", PropertyName, Name);
-    }
-
-    public override void WriteEquals(TextGenerator writer) {
-      writer.WriteLine("if (has{0} != other.has{0} || (has{0} && !{1}_.Equals(other.{1}_))) return false;", PropertyName, Name);
-    }
-
-    public override void WriteToString(TextGenerator writer) {
-      writer.WriteLine("PrintField(\"{2}\", has{0}, {1}_, writer);", PropertyName, Name,
-        Descriptor.FieldType == FieldType.Group ? Descriptor.MessageType.Name : Descriptor.Name);
-    }
-  }
-}
+#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.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class MessageFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
+    {
+        internal MessageFieldGenerator(FieldDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        public void GenerateMembers(TextGenerator writer)
+        {
+            writer.WriteLine("private bool has{0};", PropertyName);
+            writer.WriteLine("private {0} {1}_ = {2};", TypeName, Name, DefaultValue);
+            writer.WriteLine("public bool Has{0} {{", PropertyName);
+            writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
+            writer.WriteLine("}");
+            writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return {0}_; }}", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuilderMembers(TextGenerator writer)
+        {
+            writer.WriteLine("public bool Has{0} {{", PropertyName);
+            writer.WriteLine(" get {{ return result.Has{0}; }}", PropertyName);
+            writer.WriteLine("}");
+            writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
+            writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
+            AddNullCheck(writer);
+            writer.WriteLine("  result.has{0} = true;", PropertyName);
+            writer.WriteLine("  result.{0}_ = value;", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Set{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
+            AddNullCheck(writer, "builderForValue");
+            writer.WriteLine("  result.has{0} = true;", PropertyName);
+            writer.WriteLine("  result.{0}_ = builderForValue.Build();", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Merge{0}({1} value) {{", PropertyName, TypeName);
+            AddNullCheck(writer);
+            writer.WriteLine("  if (result.Has{0} &&", PropertyName);
+            writer.WriteLine("      result.{0}_ != {1}) {{", Name, DefaultValue);
+            writer.WriteLine("      result.{0}_ = {1}.CreateBuilder(result.{0}_).MergeFrom(value).BuildPartial();", Name,
+                             TypeName);
+            writer.WriteLine("  } else {");
+            writer.WriteLine("    result.{0}_ = value;", Name);
+            writer.WriteLine("  }");
+            writer.WriteLine("  result.has{0} = true;", PropertyName);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  result.has{0} = false;", PropertyName);
+            writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+        }
+
+        public void GenerateMergingCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (other.Has{0}) {{", PropertyName);
+            writer.WriteLine("  Merge{0}(other.{0});", PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuildingCode(TextGenerator writer)
+        {
+            // Nothing to do for singular fields
+        }
+
+        public void GenerateParsingCode(TextGenerator writer)
+        {
+            writer.WriteLine("{0}.Builder subBuilder = {0}.CreateBuilder();", TypeName);
+            writer.WriteLine("if (Has{0}) {{", PropertyName);
+            writer.WriteLine("  subBuilder.MergeFrom({0});", PropertyName);
+            writer.WriteLine("}");
+            if (Descriptor.FieldType == FieldType.Group)
+            {
+                writer.WriteLine("input.ReadGroup({0}, subBuilder, extensionRegistry);", Number);
+            }
+            else
+            {
+                writer.WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");
+            }
+            writer.WriteLine("{0} = subBuilder.BuildPartial();", PropertyName);
+        }
+
+        public void GenerateSerializationCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (Has{0}) {{", PropertyName);
+            writer.WriteLine("  output.Write{0}({1}, {2});", MessageOrGroup, Number, PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateSerializedSizeCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (Has{0}) {{", PropertyName);
+            writer.WriteLine("  size += pb::CodedOutputStream.Compute{0}Size({1}, {2});",
+                             MessageOrGroup, Number, PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public override void WriteHash(TextGenerator writer)
+        {
+            writer.WriteLine("if (has{0}) hash ^= {1}_.GetHashCode();", PropertyName, Name);
+        }
+
+        public override void WriteEquals(TextGenerator writer)
+        {
+            writer.WriteLine("if (has{0} != other.has{0} || (has{0} && !{1}_.Equals(other.{1}_))) return false;",
+                             PropertyName, Name);
+        }
+
+        public override void WriteToString(TextGenerator writer)
+        {
+            writer.WriteLine("PrintField(\"{2}\", has{0}, {1}_, writer);", PropertyName, Name,
+                             Descriptor.FieldType == FieldType.Group ? Descriptor.MessageType.Name : Descriptor.Name);
+        }
+    }
+}

+ 732 - 617
src/ProtoGen/MessageGenerator.cs

@@ -1,617 +1,732 @@
-#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.DescriptorProtos;
-using Google.ProtocolBuffers.Descriptors;
-using ExtensionRange = Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class MessageGenerator : SourceGeneratorBase<MessageDescriptor>, ISourceGenerator {
-    internal MessageGenerator(MessageDescriptor descriptor) : base(descriptor) {
-    }
-
-    private string ClassName {
-      get { return Descriptor.Name; }
-    }
-
-    private string FullClassName {
-      get { return GetClassName(Descriptor); }
-    }
-
-    /// <summary>
-    /// Get an identifier that uniquely identifies this type within the file.
-    /// This is used to declare static variables related to this type at the
-    /// outermost file scope.
-    /// </summary>
-    static string GetUniqueFileScopeIdentifier(IDescriptor descriptor) {
-      return "static_" + descriptor.FullName.Replace(".", "_");
-    }
-
-    internal void GenerateStaticVariables(TextGenerator writer) {
-      // Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is
-      // used in the construction of descriptors, we have a tricky bootstrapping
-      // problem.  To help control static initialization order, we make sure all
-      // descriptors and other static data that depends on them are members of
-      // the proto-descriptor class.  This way, they will be initialized in
-      // a deterministic order.
-
-      string identifier = GetUniqueFileScopeIdentifier(Descriptor);
-
-      if (!UseLiteRuntime) {
-        // The descriptor for this type.
-        string access = Descriptor.File.CSharpOptions.NestClasses ? "private" : "internal";
-        writer.WriteLine("{0} static pbd::MessageDescriptor internal__{1}__Descriptor;", access, identifier);
-        writer.WriteLine("{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable;",
-                         access, FullClassName, identifier);
-      }
-      // Generate static members for all nested types.
-      foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
-        new MessageGenerator(nestedMessage).GenerateStaticVariables(writer);
-      }
-    }
-
-    internal void GenerateStaticVariableInitializers(TextGenerator writer) {
-      string identifier = GetUniqueFileScopeIdentifier(Descriptor);
-
-      if (!UseLiteRuntime) {
-        writer.Write("internal__{0}__Descriptor = ", identifier);
-        if (Descriptor.ContainingType == null) {
-          writer.WriteLine("Descriptor.MessageTypes[{0}];", Descriptor.Index);
-        } else {
-          writer.WriteLine("internal__{0}__Descriptor.NestedTypes[{1}];", GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
-        }
-
-        writer.WriteLine("internal__{0}__FieldAccessorTable = ", identifier);
-        writer.WriteLine("    new pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder>(internal__{0}__Descriptor,",
-                         identifier, FullClassName);
-        writer.Print("        new string[] { ");
-        foreach (FieldDescriptor field in Descriptor.Fields) {
-          writer.Write("\"{0}\", ", field.CSharpOptions.PropertyName);
-        }
-        writer.WriteLine("});");
-      }
-
-      // Generate static member initializers for all nested types.
-      foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
-        new MessageGenerator(nestedMessage).GenerateStaticVariableInitializers(writer);
-      }
-
-      foreach (FieldDescriptor extension in Descriptor.Extensions) {
-        new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
-      }
-    }
-
-    public void Generate(TextGenerator writer) {
-      writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message{3}<{1}, {1}.Builder> {{",
-          ClassAccessLevel, ClassName, 
-          Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated",
-          RuntimeSuffix);
-      writer.Indent();
-      // Must call BuildPartial() to make sure all lists are made read-only
-      writer.WriteLine("private static readonly {0} defaultInstance = new Builder().BuildPartial();", ClassName);
-      writer.WriteLine("public static {0} DefaultInstance {{", ClassName);
-      writer.WriteLine("  get { return defaultInstance; }");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
-      writer.WriteLine("  get { return defaultInstance; }");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("protected override {0} ThisMessage {{", ClassName);
-      writer.WriteLine("  get { return this; }");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      if (!UseLiteRuntime) {
-        writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
-        writer.WriteLine("  get {{ return {0}.internal__{1}__Descriptor; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
-                         GetUniqueFileScopeIdentifier(Descriptor));
-        writer.WriteLine("}");
-        writer.WriteLine();
-        writer.WriteLine("protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{", ClassName);
-        writer.WriteLine("  get {{ return {0}.internal__{1}__FieldAccessorTable; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
-                         GetUniqueFileScopeIdentifier(Descriptor));
-        writer.WriteLine("}");
-        writer.WriteLine();
-      }
-
-      // Extensions don't need to go in an extra nested type 
-      WriteChildren(writer, null, Descriptor.Extensions);
-
-      if (Descriptor.EnumTypes.Count + Descriptor.NestedTypes.Count > 0) {
-        writer.WriteLine("#region Nested types");
-        writer.WriteLine("public static class Types {");
-        writer.Indent();
-        WriteChildren(writer, null, Descriptor.EnumTypes);
-        WriteChildren(writer, null, Descriptor.NestedTypes);
-        writer.Outdent();
-        writer.WriteLine("}");
-        writer.WriteLine("#endregion");
-        writer.WriteLine();
-      }
-
-      foreach(FieldDescriptor fieldDescriptor in Descriptor.Fields) {
-        // Rats: we lose the debug comment here :(
-        writer.WriteLine("public const int {0} = {1};", GetFieldConstantName(fieldDescriptor), fieldDescriptor.FieldNumber);
-        SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateMembers(writer);
-        writer.WriteLine();
-      }
-
-      if (OptimizeSpeed) {
-        GenerateIsInitialized(writer);
-        GenerateMessageSerializationMethods(writer);
-      }
-      if (UseLiteRuntime) {
-        GenerateLiteRuntimeMethods(writer);
-      }
-
-      GenerateParseFromMethods(writer);
-      GenerateBuilder(writer);
-
-      // Force the static initialization code for the file to run, since it may
-      // initialize static variables declared in this class.
-      writer.WriteLine("static {0}() {{", ClassName);
-      // We call object.ReferenceEquals() just to make it a valid statement on its own.
-      // Another option would be GetType(), but that causes problems in DescriptorProtoFile,
-      // where the bootstrapping is somewhat recursive - type initializers call
-      // each other, effectively. We temporarily see Descriptor as null.
-      writer.WriteLine("  object.ReferenceEquals({0}.Descriptor, null);", DescriptorUtil.GetFullUmbrellaClassName(Descriptor));
-      writer.WriteLine("}");
-
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-    }
-
-    private void GenerateLiteRuntimeMethods(TextGenerator writer) {
-
-      bool callbase = Descriptor.Proto.ExtensionRangeCount > 0;
-      writer.WriteLine("#region Lite runtime methods");
-      writer.WriteLine("public override int GetHashCode() {");
-      writer.Indent();
-      writer.WriteLine("int hash = GetType().GetHashCode();");
-      foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields) {
-        SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteHash(writer);
-      }
-      if (callbase) writer.WriteLine("hash ^= base.GetHashCode();");
-      writer.WriteLine("return hash;");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-
-      writer.WriteLine("public override bool Equals(object obj) {");
-      writer.Indent();
-      writer.WriteLine("{0} other = obj as {0};", ClassName);
-      writer.WriteLine("if (other == null) return false;");
-      foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields) {
-        SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteEquals(writer);
-      }
-      if (callbase) writer.WriteLine("if (!base.Equals(other)) return false;");
-      writer.WriteLine("return true;");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-      
-      writer.WriteLine("public override void PrintTo(global::System.IO.TextWriter writer) {");
-      writer.Indent();
-      List<FieldDescriptor> sorted = new List<FieldDescriptor>(Descriptor.Fields);
-      sorted.Sort(new Comparison<FieldDescriptor>(delegate(FieldDescriptor a, FieldDescriptor b) { return a.FieldNumber.CompareTo(b.FieldNumber); }));
-      foreach (FieldDescriptor fieldDescriptor in sorted) {
-        SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteToString(writer);
-      }
-      if (callbase) writer.WriteLine("base.PrintTo(writer);");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine("#endregion");
-      writer.WriteLine();
-    }
-
-    private void GenerateMessageSerializationMethods(TextGenerator writer) {
-      List<FieldDescriptor> sortedFields = new List<FieldDescriptor>(Descriptor.Fields);
-      sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber));
-
-      List<ExtensionRange> sortedExtensions = new List<ExtensionRange>(Descriptor.Proto.ExtensionRangeList);
-      sortedExtensions.Sort((r1, r2) => (r1.Start.CompareTo(r2.Start)));
-
-      writer.WriteLine("public override void WriteTo(pb::CodedOutputStream output) {");
-      writer.Indent();
-      // Make sure we've computed the serialized length, so that packed fields are generated correctly.
-      writer.WriteLine("int size = SerializedSize;");
-      if (Descriptor.Proto.ExtensionRangeList.Count > 0) {
-        writer.WriteLine("pb::ExtendableMessage{1}<{0}, {0}.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);",
-          ClassName, RuntimeSuffix);
-      }
-
-      // Merge the fields and the extension ranges, both sorted by field number.
-      for (int i = 0, j = 0; i < Descriptor.Fields.Count || j < sortedExtensions.Count; ) {
-        if (i == Descriptor.Fields.Count) {
-          GenerateSerializeOneExtensionRange(writer, sortedExtensions[j++]);
-        } else if (j == sortedExtensions.Count) {
-          GenerateSerializeOneField(writer, sortedFields[i++]);
-        } else if (sortedFields[i].FieldNumber < sortedExtensions[j].Start) {
-          GenerateSerializeOneField(writer, sortedFields[i++]);
-        } else {
-          GenerateSerializeOneExtensionRange(writer, sortedExtensions[j++]);
-        }
-      }
-
-      if (!UseLiteRuntime) {
-        if (Descriptor.Proto.Options.MessageSetWireFormat) {
-          writer.WriteLine("UnknownFields.WriteAsMessageSetTo(output);");
-        } else {
-          writer.WriteLine("UnknownFields.WriteTo(output);");
-        }
-      }
-
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("private int memoizedSerializedSize = -1;");
-      writer.WriteLine("public override int SerializedSize {");
-      writer.Indent();
-      writer.WriteLine("get {");
-      writer.Indent();
-      writer.WriteLine("int size = memoizedSerializedSize;");
-      writer.WriteLine("if (size != -1) return size;");
-      writer.WriteLine();
-      writer.WriteLine("size = 0;");
-      foreach (FieldDescriptor field in Descriptor.Fields) {
-        SourceGenerators.CreateFieldGenerator(field).GenerateSerializedSizeCode(writer);
-      }
-      if (Descriptor.Proto.ExtensionRangeCount > 0) {
-        writer.WriteLine("size += ExtensionsSerializedSize;");
-      }
-
-      if (!UseLiteRuntime) {
-        if (Descriptor.Options.MessageSetWireFormat) {
-          writer.WriteLine("size += UnknownFields.SerializedSizeAsMessageSet;");
-        } else {
-          writer.WriteLine("size += UnknownFields.SerializedSize;");
-        }
-      }
-      writer.WriteLine("memoizedSerializedSize = size;");
-      writer.WriteLine("return size;");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-    }
-
-    private static void GenerateSerializeOneField(TextGenerator writer, FieldDescriptor fieldDescriptor) {
-      SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateSerializationCode(writer);
-    }
-
-    private static void GenerateSerializeOneExtensionRange(TextGenerator writer, ExtensionRange extensionRange) {
-      writer.WriteLine("extensionWriter.WriteUntil({0}, output);", extensionRange.End);
-    }
-
-    private void GenerateParseFromMethods(TextGenerator writer) {
-      // Note:  These are separate from GenerateMessageSerializationMethods()
-      //   because they need to be generated even for messages that are optimized
-      //   for code size.
-
-      writer.WriteLine("public static {0} ParseFrom(pb::ByteString data) {{", ClassName);
-      writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
-      writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseFrom(byte[] data) {{", ClassName);
-      writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
-      writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseFrom(global::System.IO.Stream input) {{", ClassName);
-      writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
-      writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseDelimitedFrom(global::System.IO.Stream input) {{", ClassName);
-      writer.WriteLine("  return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
-      writer.WriteLine("  return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseFrom(pb::CodedInputStream input) {{", ClassName);
-      writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
-      writer.WriteLine("}");
-      writer.WriteLine("public static {0} ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
-      writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
-      writer.WriteLine("}");
-    }
-
-    /// <summary>
-    /// Returns whether or not the specified message type has any required fields.
-    /// If it doesn't, calls to check for initialization can be optimised.
-    /// TODO(jonskeet): Move this into MessageDescriptor?
-    /// </summary>
-    private static bool HasRequiredFields(MessageDescriptor descriptor, Dictionary<MessageDescriptor,object> alreadySeen) {
-      if (alreadySeen.ContainsKey(descriptor)) {
-        // The type is already in cache.  This means that either:
-        // a. The type has no required fields.
-        // b. We are in the midst of checking if the type has required fields,
-        //    somewhere up the stack.  In this case, we know that if the type
-        //    has any required fields, they'll be found when we return to it,
-        //    and the whole call to HasRequiredFields() will return true.
-        //    Therefore, we don't have to check if this type has required fields
-        //    here.
-        return false;
-      }
-      alreadySeen[descriptor] = descriptor; // Value is irrelevant
-
-      // If the type has extensions, an extension with message type could contain
-      // required fields, so we have to be conservative and assume such an
-      // extension exists.
-      if (descriptor.Extensions.Count > 0) {
-        return true;
-      }
-
-      foreach (FieldDescriptor field in descriptor.Fields) {
-        if (field.IsRequired) {
-          return true;
-        }
-        // Message or group
-        if (field.MappedType == MappedType.Message) {
-          if (HasRequiredFields(field.MessageType, alreadySeen)) {
-            return true;
-          }
-        }
-      }
-      return false;
-    }
-
-    private void GenerateBuilder(TextGenerator writer) {
-      writer.WriteLine("public static Builder CreateBuilder() { return new Builder(); }");
-      writer.WriteLine("public override Builder ToBuilder() { return CreateBuilder(this); }");
-      writer.WriteLine("public override Builder CreateBuilderForType() { return new Builder(); }");
-      writer.WriteLine("public static Builder CreateBuilder({0} prototype) {{", ClassName);
-      writer.WriteLine("  return (Builder) new Builder().MergeFrom(prototype);");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("{0} sealed partial class Builder : pb::{2}Builder{3}<{1}, Builder> {{",
-          ClassAccessLevel, ClassName, Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated", RuntimeSuffix);
-      writer.Indent();
-      writer.WriteLine("protected override Builder ThisBuilder {");
-      writer.WriteLine("  get { return this; }");
-      writer.WriteLine("}");
-      GenerateCommonBuilderMethods(writer);
-      if (OptimizeSpeed) {
-        GenerateBuilderParsingMethods(writer);
-      }
-      foreach (FieldDescriptor field in Descriptor.Fields) {
-        writer.WriteLine();
-        // No field comment :(
-        SourceGenerators.CreateFieldGenerator(field).GenerateBuilderMembers(writer);
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-    }
-
-    private void GenerateCommonBuilderMethods(TextGenerator writer) {
-      writer.WriteLine("{0} Builder() {{}}", ClassAccessLevel);
-      writer.WriteLine();
-      writer.WriteLine("{0} result = new {0}();", ClassName);
-      writer.WriteLine();
-      writer.WriteLine("protected override {0} MessageBeingBuilt {{", ClassName);
-      writer.WriteLine("  get { return result; }");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("public override Builder Clear() {");
-      writer.WriteLine("  result = new {0}();", ClassName);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("public override Builder Clone() {");
-      writer.WriteLine("  return new Builder().MergeFrom(result);");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      if (!UseLiteRuntime) {
-        writer.WriteLine("public override pbd::MessageDescriptor DescriptorForType {");
-        writer.WriteLine("  get {{ return {0}.Descriptor; }}", FullClassName);
-        writer.WriteLine("}");
-        writer.WriteLine();
-      }
-      writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
-      writer.WriteLine("  get {{ return {0}.DefaultInstance; }}", FullClassName);
-      writer.WriteLine("}");
-      writer.WriteLine();
-    
-      writer.WriteLine("public override {0} BuildPartial() {{", ClassName);
-      writer.Indent();
-      writer.WriteLine("if (result == null) {");
-      writer.WriteLine("  throw new global::System.InvalidOperationException(\"build() has already been called on this Builder\");");
-      writer.WriteLine("}");
-      foreach (FieldDescriptor field in Descriptor.Fields) {
-        SourceGenerators.CreateFieldGenerator(field).GenerateBuildingCode(writer);
-      }
-      writer.WriteLine("{0} returnMe = result;", ClassName);
-      writer.WriteLine("result = null;");
-      writer.WriteLine("return returnMe;");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-
-      if (OptimizeSpeed) {
-        writer.WriteLine("public override Builder MergeFrom(pb::IMessage{0} other) {{", RuntimeSuffix);
-        writer.WriteLine("  if (other is {0}) {{", ClassName);
-        writer.WriteLine("    return MergeFrom(({0}) other);", ClassName);
-        writer.WriteLine("  } else {");
-        writer.WriteLine("    base.MergeFrom(other);");
-        writer.WriteLine("    return this;");
-        writer.WriteLine("  }");
-        writer.WriteLine("}");
-        writer.WriteLine();
-        writer.WriteLine("public override Builder MergeFrom({0} other) {{", ClassName);
-        // Optimization:  If other is the default instance, we know none of its
-        // fields are set so we can skip the merge.
-        writer.Indent();
-        writer.WriteLine("if (other == {0}.DefaultInstance) return this;", FullClassName);
-        foreach (FieldDescriptor field in Descriptor.Fields) {
-          SourceGenerators.CreateFieldGenerator(field).GenerateMergingCode(writer);
-        }
-        // if message type has extensions
-        if (Descriptor.Proto.ExtensionRangeCount > 0) {
-          writer.WriteLine("  this.MergeExtensionFields(other);");
-        }
-        if (!UseLiteRuntime) {
-          writer.WriteLine("this.MergeUnknownFields(other.UnknownFields);");
-        }
-        writer.WriteLine("return this;");
-        writer.Outdent();
-        writer.WriteLine("}");
-        writer.WriteLine();
-      }
-    }
-
-    private void GenerateBuilderParsingMethods(TextGenerator writer) {
-      List<FieldDescriptor> sortedFields = new List<FieldDescriptor>(Descriptor.Fields);
-      sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber));
-
-      writer.WriteLine("public override Builder MergeFrom(pb::CodedInputStream input) {");
-      writer.WriteLine("  return MergeFrom(input, pb::ExtensionRegistry.Empty);");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
-      writer.Indent();
-      if (!UseLiteRuntime) {
-        writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");
-      }
-      writer.WriteLine("while (true) {");
-      writer.Indent();
-      writer.WriteLine("uint tag = input.ReadTag();");
-      writer.WriteLine("switch (tag) {");
-      writer.Indent();
-      writer.WriteLine("case 0: {"); // 0 signals EOF / limit reached
-      if (!UseLiteRuntime) {
-        writer.WriteLine("  if (unknownFields != null) {");
-        writer.WriteLine("    this.UnknownFields = unknownFields.Build();");
-        writer.WriteLine("  }");
-      }
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("default: {");
-      writer.WriteLine("  if (pb::WireFormat.IsEndGroupTag(tag)) {");
-      if (!UseLiteRuntime) {
-        writer.WriteLine("    if (unknownFields != null) {");
-        writer.WriteLine("      this.UnknownFields = unknownFields.Build();");
-        writer.WriteLine("    }");
-      }
-      writer.WriteLine("    return this;"); // it's an endgroup tag
-      writer.WriteLine("  }");
-      if (!UseLiteRuntime) {
-        writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
-        writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
-        writer.WriteLine("  }");
-      }
-      writer.WriteLine("  ParseUnknownField(input, {0}extensionRegistry, tag);", UseLiteRuntime ? "" : "unknownFields, ");
-      writer.WriteLine("  break;");
-      writer.WriteLine("}");
-      foreach (FieldDescriptor field in sortedFields) {
-        uint tag = WireFormat.MakeTag(field);
-        writer.WriteLine("case {0}: {{", tag);
-        writer.Indent();
-        SourceGenerators.CreateFieldGenerator(field).GenerateParsingCode(writer);
-        writer.WriteLine("break;");
-        writer.Outdent();
-        writer.WriteLine("}");
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-    }
-
-    private void GenerateIsInitialized(TextGenerator writer) {
-      writer.WriteLine("public override bool IsInitialized {");
-      writer.Indent();
-      writer.WriteLine("get {");
-      writer.Indent();
-
-      // Check that all required fields in this message are set.
-      // TODO(kenton):  We can optimize this when we switch to putting all the
-      // "has" fields into a single bitfield.
-      foreach (FieldDescriptor field in Descriptor.Fields) {
-        if (field.IsRequired) {
-          writer.WriteLine("if (!has{0}) return false;", field.CSharpOptions.PropertyName);
-        }
-      }
-  
-      // Now check that all embedded messages are initialized.
-      foreach (FieldDescriptor field in Descriptor.Fields) {
-        if (field.FieldType != FieldType.Message ||
-            !HasRequiredFields(field.MessageType, new Dictionary<MessageDescriptor, object>())) {
-          continue;
-        }
-        string propertyName = NameHelpers.UnderscoresToPascalCase(GetFieldName(field));
-        if (field.IsRepeated) {
-          writer.WriteLine("foreach ({0} element in {1}List) {{", GetClassName(field.MessageType), propertyName);
-          writer.WriteLine("  if (!element.IsInitialized) return false;");
-          writer.WriteLine("}");
-        } else if (field.IsOptional) {
-          writer.WriteLine("if (Has{0}) {{", propertyName);
-          writer.WriteLine("  if (!{0}.IsInitialized) return false;", propertyName);
-          writer.WriteLine("}");
-        } else {
-          writer.WriteLine("if (!{0}.IsInitialized) return false;", propertyName);
-        }
-      }
-
-      if (Descriptor.Proto.ExtensionRangeCount > 0) {
-        writer.WriteLine("if (!ExtensionsAreInitialized) return false;");
-      }
-      writer.WriteLine("return true;");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-    }
-
-    internal void GenerateExtensionRegistrationCode(TextGenerator writer) {
-      foreach (FieldDescriptor extension in Descriptor.Extensions) {
-        new ExtensionGenerator(extension).GenerateExtensionRegistrationCode(writer);
-      }
-      foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
-        new MessageGenerator(nestedMessage).GenerateExtensionRegistrationCode(writer);
-      }
-    }
-  }
-}
+#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.DescriptorProtos;
+using Google.ProtocolBuffers.Descriptors;
+using ExtensionRange = Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class MessageGenerator : SourceGeneratorBase<MessageDescriptor>, ISourceGenerator
+    {
+        internal MessageGenerator(MessageDescriptor descriptor) : base(descriptor)
+        {
+        }
+
+        private string ClassName
+        {
+            get { return Descriptor.Name; }
+        }
+
+        private string FullClassName
+        {
+            get { return GetClassName(Descriptor); }
+        }
+
+        /// <summary>
+        /// Get an identifier that uniquely identifies this type within the file.
+        /// This is used to declare static variables related to this type at the
+        /// outermost file scope.
+        /// </summary>
+        private static string GetUniqueFileScopeIdentifier(IDescriptor descriptor)
+        {
+            return "static_" + descriptor.FullName.Replace(".", "_");
+        }
+
+        internal void GenerateStaticVariables(TextGenerator writer)
+        {
+            // Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is
+            // used in the construction of descriptors, we have a tricky bootstrapping
+            // problem.  To help control static initialization order, we make sure all
+            // descriptors and other static data that depends on them are members of
+            // the proto-descriptor class.  This way, they will be initialized in
+            // a deterministic order.
+
+            string identifier = GetUniqueFileScopeIdentifier(Descriptor);
+
+            if (!UseLiteRuntime)
+            {
+                // The descriptor for this type.
+                string access = Descriptor.File.CSharpOptions.NestClasses ? "private" : "internal";
+                writer.WriteLine("{0} static pbd::MessageDescriptor internal__{1}__Descriptor;", access, identifier);
+                writer.WriteLine(
+                    "{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable;",
+                    access, FullClassName, identifier);
+            }
+            // Generate static members for all nested types.
+            foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes)
+            {
+                new MessageGenerator(nestedMessage).GenerateStaticVariables(writer);
+            }
+        }
+
+        internal void GenerateStaticVariableInitializers(TextGenerator writer)
+        {
+            string identifier = GetUniqueFileScopeIdentifier(Descriptor);
+
+            if (!UseLiteRuntime)
+            {
+                writer.Write("internal__{0}__Descriptor = ", identifier);
+                if (Descriptor.ContainingType == null)
+                {
+                    writer.WriteLine("Descriptor.MessageTypes[{0}];", Descriptor.Index);
+                }
+                else
+                {
+                    writer.WriteLine("internal__{0}__Descriptor.NestedTypes[{1}];",
+                                     GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
+                }
+
+                writer.WriteLine("internal__{0}__FieldAccessorTable = ", identifier);
+                writer.WriteLine(
+                    "    new pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder>(internal__{0}__Descriptor,",
+                    identifier, FullClassName);
+                writer.Print("        new string[] { ");
+                foreach (FieldDescriptor field in Descriptor.Fields)
+                {
+                    writer.Write("\"{0}\", ", field.CSharpOptions.PropertyName);
+                }
+                writer.WriteLine("});");
+            }
+
+            // Generate static member initializers for all nested types.
+            foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes)
+            {
+                new MessageGenerator(nestedMessage).GenerateStaticVariableInitializers(writer);
+            }
+
+            foreach (FieldDescriptor extension in Descriptor.Extensions)
+            {
+                new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
+            }
+        }
+
+        public void Generate(TextGenerator writer)
+        {
+            writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message{3}<{1}, {1}.Builder> {{",
+                             ClassAccessLevel, ClassName,
+                             Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated",
+                             RuntimeSuffix);
+            writer.Indent();
+            // Must call BuildPartial() to make sure all lists are made read-only
+            writer.WriteLine("private static readonly {0} defaultInstance = new Builder().BuildPartial();", ClassName);
+            writer.WriteLine("public static {0} DefaultInstance {{", ClassName);
+            writer.WriteLine("  get { return defaultInstance; }");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
+            writer.WriteLine("  get { return defaultInstance; }");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("protected override {0} ThisMessage {{", ClassName);
+            writer.WriteLine("  get { return this; }");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            if (!UseLiteRuntime)
+            {
+                writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
+                writer.WriteLine("  get {{ return {0}.internal__{1}__Descriptor; }}",
+                                 DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
+                                 GetUniqueFileScopeIdentifier(Descriptor));
+                writer.WriteLine("}");
+                writer.WriteLine();
+                writer.WriteLine(
+                    "protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{",
+                    ClassName);
+                writer.WriteLine("  get {{ return {0}.internal__{1}__FieldAccessorTable; }}",
+                                 DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
+                                 GetUniqueFileScopeIdentifier(Descriptor));
+                writer.WriteLine("}");
+                writer.WriteLine();
+            }
+
+            // Extensions don't need to go in an extra nested type 
+            WriteChildren(writer, null, Descriptor.Extensions);
+
+            if (Descriptor.EnumTypes.Count + Descriptor.NestedTypes.Count > 0)
+            {
+                writer.WriteLine("#region Nested types");
+                writer.WriteLine("public static class Types {");
+                writer.Indent();
+                WriteChildren(writer, null, Descriptor.EnumTypes);
+                WriteChildren(writer, null, Descriptor.NestedTypes);
+                writer.Outdent();
+                writer.WriteLine("}");
+                writer.WriteLine("#endregion");
+                writer.WriteLine();
+            }
+
+            foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
+            {
+                // Rats: we lose the debug comment here :(
+                writer.WriteLine("public const int {0} = {1};", GetFieldConstantName(fieldDescriptor),
+                                 fieldDescriptor.FieldNumber);
+                SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateMembers(writer);
+                writer.WriteLine();
+            }
+
+            if (OptimizeSpeed)
+            {
+                GenerateIsInitialized(writer);
+                GenerateMessageSerializationMethods(writer);
+            }
+            if (UseLiteRuntime)
+            {
+                GenerateLiteRuntimeMethods(writer);
+            }
+
+            GenerateParseFromMethods(writer);
+            GenerateBuilder(writer);
+
+            // Force the static initialization code for the file to run, since it may
+            // initialize static variables declared in this class.
+            writer.WriteLine("static {0}() {{", ClassName);
+            // We call object.ReferenceEquals() just to make it a valid statement on its own.
+            // Another option would be GetType(), but that causes problems in DescriptorProtoFile,
+            // where the bootstrapping is somewhat recursive - type initializers call
+            // each other, effectively. We temporarily see Descriptor as null.
+            writer.WriteLine("  object.ReferenceEquals({0}.Descriptor, null);",
+                             DescriptorUtil.GetFullUmbrellaClassName(Descriptor));
+            writer.WriteLine("}");
+
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+        }
+
+        private void GenerateLiteRuntimeMethods(TextGenerator writer)
+        {
+            bool callbase = Descriptor.Proto.ExtensionRangeCount > 0;
+            writer.WriteLine("#region Lite runtime methods");
+            writer.WriteLine("public override int GetHashCode() {");
+            writer.Indent();
+            writer.WriteLine("int hash = GetType().GetHashCode();");
+            foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
+            {
+                SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteHash(writer);
+            }
+            if (callbase) writer.WriteLine("hash ^= base.GetHashCode();");
+            writer.WriteLine("return hash;");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+
+            writer.WriteLine("public override bool Equals(object obj) {");
+            writer.Indent();
+            writer.WriteLine("{0} other = obj as {0};", ClassName);
+            writer.WriteLine("if (other == null) return false;");
+            foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
+            {
+                SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteEquals(writer);
+            }
+            if (callbase) writer.WriteLine("if (!base.Equals(other)) return false;");
+            writer.WriteLine("return true;");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+
+            writer.WriteLine("public override void PrintTo(global::System.IO.TextWriter writer) {");
+            writer.Indent();
+            List<FieldDescriptor> sorted = new List<FieldDescriptor>(Descriptor.Fields);
+            sorted.Sort(
+                new Comparison<FieldDescriptor>(
+                    delegate(FieldDescriptor a, FieldDescriptor b) { return a.FieldNumber.CompareTo(b.FieldNumber); }));
+            foreach (FieldDescriptor fieldDescriptor in sorted)
+            {
+                SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteToString(writer);
+            }
+            if (callbase) writer.WriteLine("base.PrintTo(writer);");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine("#endregion");
+            writer.WriteLine();
+        }
+
+        private void GenerateMessageSerializationMethods(TextGenerator writer)
+        {
+            List<FieldDescriptor> sortedFields = new List<FieldDescriptor>(Descriptor.Fields);
+            sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber));
+
+            List<ExtensionRange> sortedExtensions = new List<ExtensionRange>(Descriptor.Proto.ExtensionRangeList);
+            sortedExtensions.Sort((r1, r2) => (r1.Start.CompareTo(r2.Start)));
+
+            writer.WriteLine("public override void WriteTo(pb::CodedOutputStream output) {");
+            writer.Indent();
+            // Make sure we've computed the serialized length, so that packed fields are generated correctly.
+            writer.WriteLine("int size = SerializedSize;");
+            if (Descriptor.Proto.ExtensionRangeList.Count > 0)
+            {
+                writer.WriteLine(
+                    "pb::ExtendableMessage{1}<{0}, {0}.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);",
+                    ClassName, RuntimeSuffix);
+            }
+
+            // Merge the fields and the extension ranges, both sorted by field number.
+            for (int i = 0, j = 0; i < Descriptor.Fields.Count || j < sortedExtensions.Count;)
+            {
+                if (i == Descriptor.Fields.Count)
+                {
+                    GenerateSerializeOneExtensionRange(writer, sortedExtensions[j++]);
+                }
+                else if (j == sortedExtensions.Count)
+                {
+                    GenerateSerializeOneField(writer, sortedFields[i++]);
+                }
+                else if (sortedFields[i].FieldNumber < sortedExtensions[j].Start)
+                {
+                    GenerateSerializeOneField(writer, sortedFields[i++]);
+                }
+                else
+                {
+                    GenerateSerializeOneExtensionRange(writer, sortedExtensions[j++]);
+                }
+            }
+
+            if (!UseLiteRuntime)
+            {
+                if (Descriptor.Proto.Options.MessageSetWireFormat)
+                {
+                    writer.WriteLine("UnknownFields.WriteAsMessageSetTo(output);");
+                }
+                else
+                {
+                    writer.WriteLine("UnknownFields.WriteTo(output);");
+                }
+            }
+
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("private int memoizedSerializedSize = -1;");
+            writer.WriteLine("public override int SerializedSize {");
+            writer.Indent();
+            writer.WriteLine("get {");
+            writer.Indent();
+            writer.WriteLine("int size = memoizedSerializedSize;");
+            writer.WriteLine("if (size != -1) return size;");
+            writer.WriteLine();
+            writer.WriteLine("size = 0;");
+            foreach (FieldDescriptor field in Descriptor.Fields)
+            {
+                SourceGenerators.CreateFieldGenerator(field).GenerateSerializedSizeCode(writer);
+            }
+            if (Descriptor.Proto.ExtensionRangeCount > 0)
+            {
+                writer.WriteLine("size += ExtensionsSerializedSize;");
+            }
+
+            if (!UseLiteRuntime)
+            {
+                if (Descriptor.Options.MessageSetWireFormat)
+                {
+                    writer.WriteLine("size += UnknownFields.SerializedSizeAsMessageSet;");
+                }
+                else
+                {
+                    writer.WriteLine("size += UnknownFields.SerializedSize;");
+                }
+            }
+            writer.WriteLine("memoizedSerializedSize = size;");
+            writer.WriteLine("return size;");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+        }
+
+        private static void GenerateSerializeOneField(TextGenerator writer, FieldDescriptor fieldDescriptor)
+        {
+            SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateSerializationCode(writer);
+        }
+
+        private static void GenerateSerializeOneExtensionRange(TextGenerator writer, ExtensionRange extensionRange)
+        {
+            writer.WriteLine("extensionWriter.WriteUntil({0}, output);", extensionRange.End);
+        }
+
+        private void GenerateParseFromMethods(TextGenerator writer)
+        {
+            // Note:  These are separate from GenerateMessageSerializationMethods()
+            //   because they need to be generated even for messages that are optimized
+            //   for code size.
+
+            writer.WriteLine("public static {0} ParseFrom(pb::ByteString data) {{", ClassName);
+            writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine(
+                "public static {0} ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {{",
+                ClassName);
+            writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine("public static {0} ParseFrom(byte[] data) {{", ClassName);
+            writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine("public static {0} ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {{",
+                             ClassName);
+            writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine("public static {0} ParseFrom(global::System.IO.Stream input) {{", ClassName);
+            writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine(
+                "public static {0} ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{",
+                ClassName);
+            writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine("public static {0} ParseDelimitedFrom(global::System.IO.Stream input) {{", ClassName);
+            writer.WriteLine("  return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine(
+                "public static {0} ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{",
+                ClassName);
+            writer.WriteLine("  return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine("public static {0} ParseFrom(pb::CodedInputStream input) {{", ClassName);
+            writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
+            writer.WriteLine("}");
+            writer.WriteLine(
+                "public static {0} ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {{",
+                ClassName);
+            writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
+            writer.WriteLine("}");
+        }
+
+        /// <summary>
+        /// Returns whether or not the specified message type has any required fields.
+        /// If it doesn't, calls to check for initialization can be optimised.
+        /// TODO(jonskeet): Move this into MessageDescriptor?
+        /// </summary>
+        private static bool HasRequiredFields(MessageDescriptor descriptor,
+                                              Dictionary<MessageDescriptor, object> alreadySeen)
+        {
+            if (alreadySeen.ContainsKey(descriptor))
+            {
+                // The type is already in cache.  This means that either:
+                // a. The type has no required fields.
+                // b. We are in the midst of checking if the type has required fields,
+                //    somewhere up the stack.  In this case, we know that if the type
+                //    has any required fields, they'll be found when we return to it,
+                //    and the whole call to HasRequiredFields() will return true.
+                //    Therefore, we don't have to check if this type has required fields
+                //    here.
+                return false;
+            }
+            alreadySeen[descriptor] = descriptor; // Value is irrelevant
+
+            // If the type has extensions, an extension with message type could contain
+            // required fields, so we have to be conservative and assume such an
+            // extension exists.
+            if (descriptor.Extensions.Count > 0)
+            {
+                return true;
+            }
+
+            foreach (FieldDescriptor field in descriptor.Fields)
+            {
+                if (field.IsRequired)
+                {
+                    return true;
+                }
+                // Message or group
+                if (field.MappedType == MappedType.Message)
+                {
+                    if (HasRequiredFields(field.MessageType, alreadySeen))
+                    {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        private void GenerateBuilder(TextGenerator writer)
+        {
+            writer.WriteLine("public static Builder CreateBuilder() { return new Builder(); }");
+            writer.WriteLine("public override Builder ToBuilder() { return CreateBuilder(this); }");
+            writer.WriteLine("public override Builder CreateBuilderForType() { return new Builder(); }");
+            writer.WriteLine("public static Builder CreateBuilder({0} prototype) {{", ClassName);
+            writer.WriteLine("  return (Builder) new Builder().MergeFrom(prototype);");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("{0} sealed partial class Builder : pb::{2}Builder{3}<{1}, Builder> {{",
+                             ClassAccessLevel, ClassName,
+                             Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated", RuntimeSuffix);
+            writer.Indent();
+            writer.WriteLine("protected override Builder ThisBuilder {");
+            writer.WriteLine("  get { return this; }");
+            writer.WriteLine("}");
+            GenerateCommonBuilderMethods(writer);
+            if (OptimizeSpeed)
+            {
+                GenerateBuilderParsingMethods(writer);
+            }
+            foreach (FieldDescriptor field in Descriptor.Fields)
+            {
+                writer.WriteLine();
+                // No field comment :(
+                SourceGenerators.CreateFieldGenerator(field).GenerateBuilderMembers(writer);
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+        }
+
+        private void GenerateCommonBuilderMethods(TextGenerator writer)
+        {
+            writer.WriteLine("{0} Builder() {{}}", ClassAccessLevel);
+            writer.WriteLine();
+            writer.WriteLine("{0} result = new {0}();", ClassName);
+            writer.WriteLine();
+            writer.WriteLine("protected override {0} MessageBeingBuilt {{", ClassName);
+            writer.WriteLine("  get { return result; }");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("public override Builder Clear() {");
+            writer.WriteLine("  result = new {0}();", ClassName);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("public override Builder Clone() {");
+            writer.WriteLine("  return new Builder().MergeFrom(result);");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            if (!UseLiteRuntime)
+            {
+                writer.WriteLine("public override pbd::MessageDescriptor DescriptorForType {");
+                writer.WriteLine("  get {{ return {0}.Descriptor; }}", FullClassName);
+                writer.WriteLine("}");
+                writer.WriteLine();
+            }
+            writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
+            writer.WriteLine("  get {{ return {0}.DefaultInstance; }}", FullClassName);
+            writer.WriteLine("}");
+            writer.WriteLine();
+
+            writer.WriteLine("public override {0} BuildPartial() {{", ClassName);
+            writer.Indent();
+            writer.WriteLine("if (result == null) {");
+            writer.WriteLine(
+                "  throw new global::System.InvalidOperationException(\"build() has already been called on this Builder\");");
+            writer.WriteLine("}");
+            foreach (FieldDescriptor field in Descriptor.Fields)
+            {
+                SourceGenerators.CreateFieldGenerator(field).GenerateBuildingCode(writer);
+            }
+            writer.WriteLine("{0} returnMe = result;", ClassName);
+            writer.WriteLine("result = null;");
+            writer.WriteLine("return returnMe;");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+
+            if (OptimizeSpeed)
+            {
+                writer.WriteLine("public override Builder MergeFrom(pb::IMessage{0} other) {{", RuntimeSuffix);
+                writer.WriteLine("  if (other is {0}) {{", ClassName);
+                writer.WriteLine("    return MergeFrom(({0}) other);", ClassName);
+                writer.WriteLine("  } else {");
+                writer.WriteLine("    base.MergeFrom(other);");
+                writer.WriteLine("    return this;");
+                writer.WriteLine("  }");
+                writer.WriteLine("}");
+                writer.WriteLine();
+                writer.WriteLine("public override Builder MergeFrom({0} other) {{", ClassName);
+                // Optimization:  If other is the default instance, we know none of its
+                // fields are set so we can skip the merge.
+                writer.Indent();
+                writer.WriteLine("if (other == {0}.DefaultInstance) return this;", FullClassName);
+                foreach (FieldDescriptor field in Descriptor.Fields)
+                {
+                    SourceGenerators.CreateFieldGenerator(field).GenerateMergingCode(writer);
+                }
+                // if message type has extensions
+                if (Descriptor.Proto.ExtensionRangeCount > 0)
+                {
+                    writer.WriteLine("  this.MergeExtensionFields(other);");
+                }
+                if (!UseLiteRuntime)
+                {
+                    writer.WriteLine("this.MergeUnknownFields(other.UnknownFields);");
+                }
+                writer.WriteLine("return this;");
+                writer.Outdent();
+                writer.WriteLine("}");
+                writer.WriteLine();
+            }
+        }
+
+        private void GenerateBuilderParsingMethods(TextGenerator writer)
+        {
+            List<FieldDescriptor> sortedFields = new List<FieldDescriptor>(Descriptor.Fields);
+            sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber));
+
+            writer.WriteLine("public override Builder MergeFrom(pb::CodedInputStream input) {");
+            writer.WriteLine("  return MergeFrom(input, pb::ExtensionRegistry.Empty);");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine(
+                "public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
+            writer.Indent();
+            if (!UseLiteRuntime)
+            {
+                writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");
+            }
+            writer.WriteLine("while (true) {");
+            writer.Indent();
+            writer.WriteLine("uint tag = input.ReadTag();");
+            writer.WriteLine("switch (tag) {");
+            writer.Indent();
+            writer.WriteLine("case 0: {"); // 0 signals EOF / limit reached
+            if (!UseLiteRuntime)
+            {
+                writer.WriteLine("  if (unknownFields != null) {");
+                writer.WriteLine("    this.UnknownFields = unknownFields.Build();");
+                writer.WriteLine("  }");
+            }
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("default: {");
+            writer.WriteLine("  if (pb::WireFormat.IsEndGroupTag(tag)) {");
+            if (!UseLiteRuntime)
+            {
+                writer.WriteLine("    if (unknownFields != null) {");
+                writer.WriteLine("      this.UnknownFields = unknownFields.Build();");
+                writer.WriteLine("    }");
+            }
+            writer.WriteLine("    return this;"); // it's an endgroup tag
+            writer.WriteLine("  }");
+            if (!UseLiteRuntime)
+            {
+                writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
+                writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
+                writer.WriteLine("  }");
+            }
+            writer.WriteLine("  ParseUnknownField(input, {0}extensionRegistry, tag);",
+                             UseLiteRuntime ? "" : "unknownFields, ");
+            writer.WriteLine("  break;");
+            writer.WriteLine("}");
+            foreach (FieldDescriptor field in sortedFields)
+            {
+                uint tag = WireFormat.MakeTag(field);
+                writer.WriteLine("case {0}: {{", tag);
+                writer.Indent();
+                SourceGenerators.CreateFieldGenerator(field).GenerateParsingCode(writer);
+                writer.WriteLine("break;");
+                writer.Outdent();
+                writer.WriteLine("}");
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+        }
+
+        private void GenerateIsInitialized(TextGenerator writer)
+        {
+            writer.WriteLine("public override bool IsInitialized {");
+            writer.Indent();
+            writer.WriteLine("get {");
+            writer.Indent();
+
+            // Check that all required fields in this message are set.
+            // TODO(kenton):  We can optimize this when we switch to putting all the
+            // "has" fields into a single bitfield.
+            foreach (FieldDescriptor field in Descriptor.Fields)
+            {
+                if (field.IsRequired)
+                {
+                    writer.WriteLine("if (!has{0}) return false;", field.CSharpOptions.PropertyName);
+                }
+            }
+
+            // Now check that all embedded messages are initialized.
+            foreach (FieldDescriptor field in Descriptor.Fields)
+            {
+                if (field.FieldType != FieldType.Message ||
+                    !HasRequiredFields(field.MessageType, new Dictionary<MessageDescriptor, object>()))
+                {
+                    continue;
+                }
+                string propertyName = NameHelpers.UnderscoresToPascalCase(GetFieldName(field));
+                if (field.IsRepeated)
+                {
+                    writer.WriteLine("foreach ({0} element in {1}List) {{", GetClassName(field.MessageType),
+                                     propertyName);
+                    writer.WriteLine("  if (!element.IsInitialized) return false;");
+                    writer.WriteLine("}");
+                }
+                else if (field.IsOptional)
+                {
+                    writer.WriteLine("if (Has{0}) {{", propertyName);
+                    writer.WriteLine("  if (!{0}.IsInitialized) return false;", propertyName);
+                    writer.WriteLine("}");
+                }
+                else
+                {
+                    writer.WriteLine("if (!{0}.IsInitialized) return false;", propertyName);
+                }
+            }
+
+            if (Descriptor.Proto.ExtensionRangeCount > 0)
+            {
+                writer.WriteLine("if (!ExtensionsAreInitialized) return false;");
+            }
+            writer.WriteLine("return true;");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+        }
+
+        internal void GenerateExtensionRegistrationCode(TextGenerator writer)
+        {
+            foreach (FieldDescriptor extension in Descriptor.Extensions)
+            {
+                new ExtensionGenerator(extension).GenerateExtensionRegistrationCode(writer);
+            }
+            foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes)
+            {
+                new MessageGenerator(nestedMessage).GenerateExtensionRegistrationCode(writer);
+            }
+        }
+    }
+}

+ 134 - 119
src/ProtoGen/PrimitiveFieldGenerator.cs

@@ -1,119 +1,134 @@
-#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.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  // TODO(jonskeet): Refactor this. There's loads of common code here.
-  internal class PrimitiveFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator {
-
-    internal PrimitiveFieldGenerator(FieldDescriptor descriptor)
-        : base(descriptor) {
-    }
-
-    public void GenerateMembers(TextGenerator writer) {
-      writer.WriteLine("private bool has{0};", PropertyName);
-      writer.WriteLine("private {0} {1}_ = {2};", TypeName, Name, DefaultValue);
-      writer.WriteLine("public bool Has{0} {{", PropertyName);
-      writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return {0}_; }}", Name);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuilderMembers(TextGenerator writer) {
-      writer.WriteLine("public bool Has{0} {{", PropertyName);
-      writer.WriteLine("  get {{ return result.Has{0}; }}", PropertyName);
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
-      writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
-      AddNullCheck(writer);
-      writer.WriteLine("  result.has{0} = true;", PropertyName);
-      writer.WriteLine("  result.{0}_ = value;", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
-      writer.WriteLine("  result.has{0} = false;", PropertyName);
-      writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-    }
-
-    public void GenerateMergingCode(TextGenerator writer) {
-      writer.WriteLine("if (other.Has{0}) {{", PropertyName);
-      writer.WriteLine("  {0} = other.{0};", PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuildingCode(TextGenerator writer) {
-      // Nothing to do here for primitive types
-    }
-
-    public void GenerateParsingCode(TextGenerator writer) {
-      writer.WriteLine("{0} = input.Read{1}();", PropertyName, CapitalizedTypeName);
-    }
-
-    public void GenerateSerializationCode(TextGenerator writer) {
-      writer.WriteLine("if (Has{0}) {{", PropertyName);
-      writer.WriteLine("  output.Write{0}({1}, {2});", CapitalizedTypeName, Number, PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateSerializedSizeCode(TextGenerator writer) {
-      writer.WriteLine("if (Has{0}) {{", PropertyName);
-      writer.WriteLine("  size += pb::CodedOutputStream.Compute{0}Size({1}, {2});",
-          CapitalizedTypeName, Number, PropertyName);
-      writer.WriteLine("}");
-    }
-
-    public override void WriteHash(TextGenerator writer) {
-      writer.WriteLine("if (has{0}) hash ^= {1}_.GetHashCode();", PropertyName, Name);
-    }
-
-    public override void WriteEquals(TextGenerator writer) {
-      writer.WriteLine("if (has{0} != other.has{0} || (has{0} && !{1}_.Equals(other.{1}_))) return false;", PropertyName, Name);
-    }
-
-    public override void WriteToString(TextGenerator writer) {
-      writer.WriteLine("PrintField(\"{0}\", has{1}, {2}_, writer);", Descriptor.Name, PropertyName, Name);
-    }
-  }
-}
+#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.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    // TODO(jonskeet): Refactor this. There's loads of common code here.
+    internal class PrimitiveFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
+    {
+        internal PrimitiveFieldGenerator(FieldDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        public void GenerateMembers(TextGenerator writer)
+        {
+            writer.WriteLine("private bool has{0};", PropertyName);
+            writer.WriteLine("private {0} {1}_ = {2};", TypeName, Name, DefaultValue);
+            writer.WriteLine("public bool Has{0} {{", PropertyName);
+            writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return {0}_; }}", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuilderMembers(TextGenerator writer)
+        {
+            writer.WriteLine("public bool Has{0} {{", PropertyName);
+            writer.WriteLine("  get {{ return result.Has{0}; }}", PropertyName);
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
+            writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
+            AddNullCheck(writer);
+            writer.WriteLine("  result.has{0} = true;", PropertyName);
+            writer.WriteLine("  result.{0}_ = value;", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  result.has{0} = false;", PropertyName);
+            writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+        }
+
+        public void GenerateMergingCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (other.Has{0}) {{", PropertyName);
+            writer.WriteLine("  {0} = other.{0};", PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuildingCode(TextGenerator writer)
+        {
+            // Nothing to do here for primitive types
+        }
+
+        public void GenerateParsingCode(TextGenerator writer)
+        {
+            writer.WriteLine("{0} = input.Read{1}();", PropertyName, CapitalizedTypeName);
+        }
+
+        public void GenerateSerializationCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (Has{0}) {{", PropertyName);
+            writer.WriteLine("  output.Write{0}({1}, {2});", CapitalizedTypeName, Number, PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateSerializedSizeCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (Has{0}) {{", PropertyName);
+            writer.WriteLine("  size += pb::CodedOutputStream.Compute{0}Size({1}, {2});",
+                             CapitalizedTypeName, Number, PropertyName);
+            writer.WriteLine("}");
+        }
+
+        public override void WriteHash(TextGenerator writer)
+        {
+            writer.WriteLine("if (has{0}) hash ^= {1}_.GetHashCode();", PropertyName, Name);
+        }
+
+        public override void WriteEquals(TextGenerator writer)
+        {
+            writer.WriteLine("if (has{0} != other.has{0} || (has{0} && !{1}_.Equals(other.{1}_))) return false;",
+                             PropertyName, Name);
+        }
+
+        public override void WriteToString(TextGenerator writer)
+        {
+            writer.WriteLine("PrintField(\"{0}\", has{1}, {2}_, writer);", Descriptor.Name, PropertyName, Name);
+        }
+    }
+}

+ 77 - 71
src/ProtoGen/Program.cs

@@ -1,72 +1,78 @@
-#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.DescriptorProtos;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  /// <summary>
-  /// Entry point for the Protocol Buffers generator.
-  /// </summary>
-  internal class Program {
-    internal static int Main(string[] args) {
-      try {
-        // Hack to make sure everything's initialized
-        DescriptorProtoFile.Descriptor.ToString();
-        GeneratorOptions options = new GeneratorOptions {Arguments = args};
-
-        IList<string> validationFailures;
-        if (!options.TryValidate(out validationFailures)) {
-          // We've already got the message-building logic in the exception...
-          InvalidOptionsException exception = new InvalidOptionsException(validationFailures);
-          Console.WriteLine(exception.Message);
-          return 1;
-        }
-
-        Generator generator = Generator.CreateGenerator(options);
-        generator.Generate();
-        return 0;
-      }
-      catch (Exception e) {
-        Console.Error.WriteLine("Error: {0}", e.Message);
-        Console.Error.WriteLine();
-        Console.Error.WriteLine("Detailed exception information: {0}", e);
-        return 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 Google.ProtocolBuffers.DescriptorProtos;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// Entry point for the Protocol Buffers generator.
+    /// </summary>
+    internal class Program
+    {
+        internal static int Main(string[] args)
+        {
+            try
+            {
+                // Hack to make sure everything's initialized
+                DescriptorProtoFile.Descriptor.ToString();
+                GeneratorOptions options = new GeneratorOptions {Arguments = args};
+
+                IList<string> validationFailures;
+                if (!options.TryValidate(out validationFailures))
+                {
+                    // We've already got the message-building logic in the exception...
+                    InvalidOptionsException exception = new InvalidOptionsException(validationFailures);
+                    Console.WriteLine(exception.Message);
+                    return 1;
+                }
+
+                Generator generator = Generator.CreateGenerator(options);
+                generator.Generate();
+                return 0;
+            }
+            catch (Exception e)
+            {
+                Console.Error.WriteLine("Error: {0}", e.Message);
+                Console.Error.WriteLine();
+                Console.Error.WriteLine("Detailed exception information: {0}", e);
+                return 1;
+            }
+        }
+    }
 }

+ 186 - 153
src/ProtoGen/ProgramPreprocess.cs

@@ -1,153 +1,186 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  /// <summary>
-  /// Preprocesses any input files with an extension of '.proto' by running protoc.exe.  If arguments
-  /// are supplied with '--' prefix they are provided to protoc.exe, otherwise they are assumed to
-  /// be used for ProtoGen.exe which is run on the resulting output proto buffer.  If the option
-  /// --descriptor_set_out= is specified the proto buffer file is kept, otherwise it will be removed
-  /// after code generation.
-  /// </summary>
-  public class ProgramPreprocess {
-    private static int Main(string[] args) {
-      try {
-        return Environment.ExitCode = Run(args);
-      }
-      catch (Exception ex) {
-        Console.Error.WriteLine(ex);
-        return Environment.ExitCode = 2;
-      }
-    }
-
-    public static int Run(params string[] args) {
-      bool deleteFile = false;
-      string tempFile = null;
-      int result;
-      bool doHelp = args.Length == 0;
-      try {
-        List<string> protocArgs = new List<string>();
-        List<string> protoGenArgs = new List<string>();
-
-        foreach (string arg in args) {
-          doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/?");
-          doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/help");
-          doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "-?");
-          doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "-help");
-
-          if (arg.StartsWith("--descriptor_set_out=")) {
-            tempFile = arg.Substring("--descriptor_set_out=".Length);
-            protoGenArgs.Add(tempFile);
-          }
-        }
-
-        if (doHelp) {
-          Console.WriteLine();
-          Console.WriteLine("PROTOC.exe: Use any of the following options that begin with '--':");
-          Console.WriteLine();
-          try {
-            RunProtoc("--help");
-          }
-          catch (Exception ex) {
-            Console.Error.WriteLine(ex.Message);
-          }
-          Console.WriteLine();
-          Console.WriteLine();
-          Console.WriteLine("PROTOGEN.exe: The following options are used to specify defaults for code generation.");
-          Console.WriteLine();
-          Program.Main(new string[0]);
-          return 0;
-        }
-
-        foreach (string arg in args) {
-          if (arg.StartsWith("--")) {
-            protocArgs.Add(arg);
-          }
-          else if (File.Exists(arg) && StringComparer.OrdinalIgnoreCase.Equals(".proto", Path.GetExtension(arg))) {
-            if (tempFile == null) {
-              deleteFile = true;
-              tempFile = Path.GetTempFileName();
-              protocArgs.Add(String.Format("--descriptor_set_out={0}", tempFile));
-              protoGenArgs.Add(tempFile);
-            }
-            protocArgs.Add(arg);
-          }
-          else {
-            protoGenArgs.Add(arg);
-          }
-        }
-
-        if (tempFile != null) {
-          result = RunProtoc(protocArgs.ToArray());
-          if (result != 0) {
-            return result;
-          }
-        }
-
-        result = Program.Main(protoGenArgs.ToArray());
-      }
-      finally {
-        if (deleteFile && tempFile != null && File.Exists(tempFile)) {
-          File.Delete(tempFile);
-        }
-      }
-      return result;
-    }
-
-    private static int RunProtoc(params string[] args) {
-      const string protoc = "protoc.exe";
-      string exePath = protoc;
-
-      // Why oh why is this not in System.IO.Path or Environment...?
-      List<string> searchPath = new List<string>();
-      searchPath.Add(Environment.CurrentDirectory);
-      searchPath.Add(AppDomain.CurrentDomain.BaseDirectory);
-      searchPath.AddRange((Environment.GetEnvironmentVariable("PATH") ?? String.Empty).Split(Path.PathSeparator));
-
-      foreach (string path in searchPath) {
-        if (File.Exists(exePath = Path.Combine(path, protoc))) {
-          break;
-        }
-      }
-
-      if (!File.Exists(exePath)) {
-        throw new FileNotFoundException("Unable to locate " + protoc + " make sure it is in the PATH, cwd, or exe dir.");
-      }
-
-      for (int i = 0; i < args.Length; i++) {
-        if (args[i].IndexOf(' ') > 0 && args[i][0] != '"') {
-          args[i] = '"' + args[i] + '"';
-        }
-      }
-
-      ProcessStartInfo psi = new ProcessStartInfo(exePath);
-      psi.Arguments = String.Join(" ", args);
-      psi.RedirectStandardError = true;
-      psi.RedirectStandardInput = false;
-      psi.RedirectStandardOutput = true;
-      psi.ErrorDialog = false;
-      psi.CreateNoWindow = true;
-      psi.UseShellExecute = false;
-      psi.WorkingDirectory = Environment.CurrentDirectory;
-
-      Process process = Process.Start(psi);
-      if (process == null) {
-        return 1;
-      }
-
-      process.WaitForExit();
-
-      string tmp = process.StandardOutput.ReadToEnd();
-      if (tmp.Trim().Length > 0) {
-        Console.Out.WriteLine(tmp);
-      }
-      tmp = process.StandardError.ReadToEnd();
-      if (tmp.Trim().Length > 0) {
-        Console.Error.WriteLine(tmp);
-      }
-      return process.ExitCode;
-    }
-  }
-}
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// Preprocesses any input files with an extension of '.proto' by running protoc.exe.  If arguments
+    /// are supplied with '--' prefix they are provided to protoc.exe, otherwise they are assumed to
+    /// be used for ProtoGen.exe which is run on the resulting output proto buffer.  If the option
+    /// --descriptor_set_out= is specified the proto buffer file is kept, otherwise it will be removed
+    /// after code generation.
+    /// </summary>
+    public class ProgramPreprocess
+    {
+        private static int Main(string[] args)
+        {
+            try
+            {
+                return Environment.ExitCode = Run(args);
+            }
+            catch (Exception ex)
+            {
+                Console.Error.WriteLine(ex);
+                return Environment.ExitCode = 2;
+            }
+        }
+
+        public static int Run(params string[] args)
+        {
+            bool deleteFile = false;
+            string tempFile = null;
+            int result;
+            bool doHelp = args.Length == 0;
+            try
+            {
+                List<string> protocArgs = new List<string>();
+                List<string> protoGenArgs = new List<string>();
+
+                foreach (string arg in args)
+                {
+                    doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/?");
+                    doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/help");
+                    doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "-?");
+                    doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "-help");
+
+                    if (arg.StartsWith("--descriptor_set_out="))
+                    {
+                        tempFile = arg.Substring("--descriptor_set_out=".Length);
+                        protoGenArgs.Add(tempFile);
+                    }
+                }
+
+                if (doHelp)
+                {
+                    Console.WriteLine();
+                    Console.WriteLine("PROTOC.exe: Use any of the following options that begin with '--':");
+                    Console.WriteLine();
+                    try
+                    {
+                        RunProtoc("--help");
+                    }
+                    catch (Exception ex)
+                    {
+                        Console.Error.WriteLine(ex.Message);
+                    }
+                    Console.WriteLine();
+                    Console.WriteLine();
+                    Console.WriteLine(
+                        "PROTOGEN.exe: The following options are used to specify defaults for code generation.");
+                    Console.WriteLine();
+                    Program.Main(new string[0]);
+                    return 0;
+                }
+
+                foreach (string arg in args)
+                {
+                    if (arg.StartsWith("--"))
+                    {
+                        protocArgs.Add(arg);
+                    }
+                    else if (File.Exists(arg) &&
+                             StringComparer.OrdinalIgnoreCase.Equals(".proto", Path.GetExtension(arg)))
+                    {
+                        if (tempFile == null)
+                        {
+                            deleteFile = true;
+                            tempFile = Path.GetTempFileName();
+                            protocArgs.Add(String.Format("--descriptor_set_out={0}", tempFile));
+                            protoGenArgs.Add(tempFile);
+                        }
+                        protocArgs.Add(arg);
+                    }
+                    else
+                    {
+                        protoGenArgs.Add(arg);
+                    }
+                }
+
+                if (tempFile != null)
+                {
+                    result = RunProtoc(protocArgs.ToArray());
+                    if (result != 0)
+                    {
+                        return result;
+                    }
+                }
+
+                result = Program.Main(protoGenArgs.ToArray());
+            }
+            finally
+            {
+                if (deleteFile && tempFile != null && File.Exists(tempFile))
+                {
+                    File.Delete(tempFile);
+                }
+            }
+            return result;
+        }
+
+        private static int RunProtoc(params string[] args)
+        {
+            const string protoc = "protoc.exe";
+            string exePath = protoc;
+
+            // Why oh why is this not in System.IO.Path or Environment...?
+            List<string> searchPath = new List<string>();
+            searchPath.Add(Environment.CurrentDirectory);
+            searchPath.Add(AppDomain.CurrentDomain.BaseDirectory);
+            searchPath.AddRange((Environment.GetEnvironmentVariable("PATH") ?? String.Empty).Split(Path.PathSeparator));
+
+            foreach (string path in searchPath)
+            {
+                if (File.Exists(exePath = Path.Combine(path, protoc)))
+                {
+                    break;
+                }
+            }
+
+            if (!File.Exists(exePath))
+            {
+                throw new FileNotFoundException("Unable to locate " + protoc +
+                                                " make sure it is in the PATH, cwd, or exe dir.");
+            }
+
+            for (int i = 0; i < args.Length; i++)
+            {
+                if (args[i].IndexOf(' ') > 0 && args[i][0] != '"')
+                {
+                    args[i] = '"' + args[i] + '"';
+                }
+            }
+
+            ProcessStartInfo psi = new ProcessStartInfo(exePath);
+            psi.Arguments = String.Join(" ", args);
+            psi.RedirectStandardError = true;
+            psi.RedirectStandardInput = false;
+            psi.RedirectStandardOutput = true;
+            psi.ErrorDialog = false;
+            psi.CreateNoWindow = true;
+            psi.UseShellExecute = false;
+            psi.WorkingDirectory = Environment.CurrentDirectory;
+
+            Process process = Process.Start(psi);
+            if (process == null)
+            {
+                return 1;
+            }
+
+            process.WaitForExit();
+
+            string tmp = process.StandardOutput.ReadToEnd();
+            if (tmp.Trim().Length > 0)
+            {
+                Console.Out.WriteLine(tmp);
+            }
+            tmp = process.StandardError.ReadToEnd();
+            if (tmp.Trim().Length > 0)
+            {
+                Console.Error.WriteLine(tmp);
+            }
+            return process.ExitCode;
+        }
+    }
+}

+ 40 - 37
src/ProtoGen/Properties/AssemblyInfo.cs

@@ -1,37 +1,40 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ProtoGen")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ProtoGen")]
-[assembly: AssemblyCopyright("Copyright ©  2008")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("7101763b-7a38-41be-87f5-7ede4c554509")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyFileVersion("2.3.0.277")]
-
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("ProtoGen")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ProtoGen")]
+[assembly: AssemblyCopyright("Copyright ©  2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("7101763b-7a38-41be-87f5-7ede4c554509")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("2.3.0.277")]
+
+[assembly: AssemblyVersion("2.3.0.277")]
+[assembly: AssemblyFileVersion("2.3.0.277")]

+ 219 - 194
src/ProtoGen/RepeatedEnumFieldGenerator.cs

@@ -1,194 +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 Google.ProtocolBuffers.DescriptorProtos;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class RepeatedEnumFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator {
-
-    internal RepeatedEnumFieldGenerator(FieldDescriptor descriptor)
-      : base(descriptor) {
-    }
-
-    public void GenerateMembers(TextGenerator writer) {
-      if (Descriptor.IsPacked && OptimizeSpeed) {
-        writer.WriteLine("private int {0}MemoizedSerializedSize;", Name);
-      }
-      writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
-      writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return pbc::Lists.AsReadOnly({0}_); }}", Name);
-      writer.WriteLine("}");
-
-      // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
-      writer.WriteLine("public int {0}Count {{", PropertyName);
-      writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
-      writer.WriteLine("}");
-
-      writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
-      writer.WriteLine("  return {0}_[index];", Name);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuilderMembers(TextGenerator writer) {
-      // Note:  We can return the original list here, because we make it unmodifiable when we build
-      // We return it via IPopsicleList so that collection initializers work more pleasantly.
-      writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return result.{0}_; }}", Name);
-      writer.WriteLine("}");
-      writer.WriteLine("public int {0}Count {{", PropertyName);
-      writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
-      writer.WriteLine("}");
-      writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
-      writer.WriteLine("  return result.Get{0}(index);", PropertyName);
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
-      writer.WriteLine("  result.{0}_[index] = value;", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
-      writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
-      writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
-      writer.WriteLine("  result.{0}_.Clear();", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-    }
-
-    public void GenerateMergingCode(TextGenerator writer) {
-      writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
-      writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuildingCode(TextGenerator writer) {
-      writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
-    }
-
-    public void GenerateParsingCode(TextGenerator writer) {
-        // If packed, set up the while loop
-      if (Descriptor.IsPacked) {
-        writer.WriteLine("int length = input.ReadInt32();");
-        writer.WriteLine("int oldLimit = input.PushLimit(length);");
-        writer.WriteLine("while (!input.ReachedLimit) {");
-        writer.Indent();
-      }
-
-      // Read and store the enum
-      // TODO(jonskeet): Make a more efficient way of doing this
-      writer.WriteLine("int rawValue = input.ReadEnum();");
-      writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);
-      if (!UseLiteRuntime) {
-        writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
-        writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
-        writer.WriteLine("  }");
-        writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);
-      }
-      writer.WriteLine("} else {");
-      writer.WriteLine("  Add{0}(({1}) rawValue);", PropertyName, TypeName);
-      writer.WriteLine("}");
-      
-      if (Descriptor.IsPacked) {
-        writer.Outdent();
-        writer.WriteLine("}");
-        writer.WriteLine("input.PopLimit(oldLimit);");
-      }
-    }
-
-    public void GenerateSerializationCode(TextGenerator writer) {
-      writer.WriteLine("if ({0}_.Count > 0) {{", Name);
-      writer.Indent();
-      if (Descriptor.IsPacked) {
-        writer.WriteLine("output.WriteRawVarint32({0});", WireFormat.MakeTag(Descriptor));
-        writer.WriteLine("output.WriteRawVarint32((uint) {0}MemoizedSerializedSize);", Name);
-        writer.WriteLine("foreach (int element in {0}_) {{", Name);
-        writer.WriteLine("  output.WriteEnumNoTag(element);");
-        writer.WriteLine("}");
-      } else {
-        writer.WriteLine("foreach (int element in {0}_) {{", Name);
-        writer.WriteLine("  output.WriteEnum({0}, element);", Number);
-        writer.WriteLine("}");
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-    }
-
-    public void GenerateSerializedSizeCode(TextGenerator writer) {
-      writer.WriteLine("{");
-      writer.Indent();
-      writer.WriteLine("int dataSize = 0;");
-      writer.WriteLine("if ({0}_.Count > 0) {{", Name);
-      writer.Indent();
-      writer.WriteLine("foreach ({0} element in {1}_) {{", TypeName, Name);
-      writer.WriteLine("  dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);");
-      writer.WriteLine("}");
-      writer.WriteLine("size += dataSize;");
-      int tagSize = CodedOutputStream.ComputeTagSize(Descriptor.FieldNumber);
-      if (Descriptor.IsPacked) {
-        writer.WriteLine("size += {0};", tagSize);
-        writer.WriteLine("size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);");
-      } else {
-        writer.WriteLine("size += {0} * {1}_.Count;", tagSize, Name);
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-      // cache the data size for packed fields.
-      if (Descriptor.IsPacked) {
-        writer.WriteLine("{0}MemoizedSerializedSize = dataSize;", Name);
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-    }
-
-    public override void WriteHash(TextGenerator writer) {
-      writer.WriteLine("foreach({0} i in {1}_)", TypeName, Name);
-      writer.WriteLine("  hash ^= i.GetHashCode();");
-    }
-
-    public override void WriteEquals(TextGenerator writer) {
-      writer.WriteLine("if({0}_.Count != other.{0}_.Count) return false;", Name);
-      writer.WriteLine("for(int ix=0; ix < {0}_.Count; ix++)", Name);
-      writer.WriteLine("  if(!{0}_[ix].Equals(other.{0}_[ix])) return false;", Name);
-    }
-
-    public override void WriteToString(TextGenerator writer) {
-      writer.WriteLine("PrintField(\"{0}\", {1}_, writer);", Descriptor.Name, Name);
-    }
-  }
-}
+#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.DescriptorProtos;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class RepeatedEnumFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
+    {
+        internal RepeatedEnumFieldGenerator(FieldDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        public void GenerateMembers(TextGenerator writer)
+        {
+            if (Descriptor.IsPacked && OptimizeSpeed)
+            {
+                writer.WriteLine("private int {0}MemoizedSerializedSize;", Name);
+            }
+            writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
+            writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return pbc::Lists.AsReadOnly({0}_); }}", Name);
+            writer.WriteLine("}");
+
+            // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
+            writer.WriteLine("public int {0}Count {{", PropertyName);
+            writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
+            writer.WriteLine("}");
+
+            writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
+            writer.WriteLine("  return {0}_[index];", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuilderMembers(TextGenerator writer)
+        {
+            // Note:  We can return the original list here, because we make it unmodifiable when we build
+            // We return it via IPopsicleList so that collection initializers work more pleasantly.
+            writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return result.{0}_; }}", Name);
+            writer.WriteLine("}");
+            writer.WriteLine("public int {0}Count {{", PropertyName);
+            writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
+            writer.WriteLine("}");
+            writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
+            writer.WriteLine("  return result.Get{0}(index);", PropertyName);
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
+            writer.WriteLine("  result.{0}_[index] = value;", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
+            writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
+            writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  result.{0}_.Clear();", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+        }
+
+        public void GenerateMergingCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
+            writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuildingCode(TextGenerator writer)
+        {
+            writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
+        }
+
+        public void GenerateParsingCode(TextGenerator writer)
+        {
+            // If packed, set up the while loop
+            if (Descriptor.IsPacked)
+            {
+                writer.WriteLine("int length = input.ReadInt32();");
+                writer.WriteLine("int oldLimit = input.PushLimit(length);");
+                writer.WriteLine("while (!input.ReachedLimit) {");
+                writer.Indent();
+            }
+
+            // Read and store the enum
+            // TODO(jonskeet): Make a more efficient way of doing this
+            writer.WriteLine("int rawValue = input.ReadEnum();");
+            writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);
+            if (!UseLiteRuntime)
+            {
+                writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
+                writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
+                writer.WriteLine("  }");
+                writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);
+            }
+            writer.WriteLine("} else {");
+            writer.WriteLine("  Add{0}(({1}) rawValue);", PropertyName, TypeName);
+            writer.WriteLine("}");
+
+            if (Descriptor.IsPacked)
+            {
+                writer.Outdent();
+                writer.WriteLine("}");
+                writer.WriteLine("input.PopLimit(oldLimit);");
+            }
+        }
+
+        public void GenerateSerializationCode(TextGenerator writer)
+        {
+            writer.WriteLine("if ({0}_.Count > 0) {{", Name);
+            writer.Indent();
+            if (Descriptor.IsPacked)
+            {
+                writer.WriteLine("output.WriteRawVarint32({0});", WireFormat.MakeTag(Descriptor));
+                writer.WriteLine("output.WriteRawVarint32((uint) {0}MemoizedSerializedSize);", Name);
+                writer.WriteLine("foreach (int element in {0}_) {{", Name);
+                writer.WriteLine("  output.WriteEnumNoTag(element);");
+                writer.WriteLine("}");
+            }
+            else
+            {
+                writer.WriteLine("foreach (int element in {0}_) {{", Name);
+                writer.WriteLine("  output.WriteEnum({0}, element);", Number);
+                writer.WriteLine("}");
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+        }
+
+        public void GenerateSerializedSizeCode(TextGenerator writer)
+        {
+            writer.WriteLine("{");
+            writer.Indent();
+            writer.WriteLine("int dataSize = 0;");
+            writer.WriteLine("if ({0}_.Count > 0) {{", Name);
+            writer.Indent();
+            writer.WriteLine("foreach ({0} element in {1}_) {{", TypeName, Name);
+            writer.WriteLine("  dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);");
+            writer.WriteLine("}");
+            writer.WriteLine("size += dataSize;");
+            int tagSize = CodedOutputStream.ComputeTagSize(Descriptor.FieldNumber);
+            if (Descriptor.IsPacked)
+            {
+                writer.WriteLine("size += {0};", tagSize);
+                writer.WriteLine("size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);");
+            }
+            else
+            {
+                writer.WriteLine("size += {0} * {1}_.Count;", tagSize, Name);
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+            // cache the data size for packed fields.
+            if (Descriptor.IsPacked)
+            {
+                writer.WriteLine("{0}MemoizedSerializedSize = dataSize;", Name);
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+        }
+
+        public override void WriteHash(TextGenerator writer)
+        {
+            writer.WriteLine("foreach({0} i in {1}_)", TypeName, Name);
+            writer.WriteLine("  hash ^= i.GetHashCode();");
+        }
+
+        public override void WriteEquals(TextGenerator writer)
+        {
+            writer.WriteLine("if({0}_.Count != other.{0}_.Count) return false;", Name);
+            writer.WriteLine("for(int ix=0; ix < {0}_.Count; ix++)", Name);
+            writer.WriteLine("  if(!{0}_[ix].Equals(other.{0}_[ix])) return false;", Name);
+        }
+
+        public override void WriteToString(TextGenerator writer)
+        {
+            writer.WriteLine("PrintField(\"{0}\", {1}_, writer);", Descriptor.Name, Name);
+        }
+    }
+}

+ 170 - 153
src/ProtoGen/RepeatedMessageFieldGenerator.cs

@@ -1,153 +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 Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class RepeatedMessageFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator {
-
-    internal RepeatedMessageFieldGenerator(FieldDescriptor descriptor)
-      : base(descriptor) {
-    }
-    
-    public void GenerateMembers(TextGenerator writer) {
-      writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
-      writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return {0}_; }}", Name);
-      writer.WriteLine("}");
-
-      // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
-      writer.WriteLine("public int {0}Count {{", PropertyName);
-      writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
-      writer.WriteLine("}");
-
-      writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
-      writer.WriteLine("  return {0}_[index];", Name);
-      writer.WriteLine("}");
-    }    
-
-    public void GenerateBuilderMembers(TextGenerator writer) {
-      // Note:  We can return the original list here, because we make it unmodifiable when we build
-      // We return it via IPopsicleList so that collection initializers work more pleasantly.
-      writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return result.{0}_; }}", Name);
-      writer.WriteLine("}");
-      writer.WriteLine("public int {0}Count {{", PropertyName);
-      writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
-      writer.WriteLine("}");
-      writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
-      writer.WriteLine("  return result.Get{0}(index);", PropertyName);
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
-      AddNullCheck(writer);
-      writer.WriteLine("  result.{0}_[index] = value;", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      // Extra overload for builder (just on messages)
-      writer.WriteLine("public Builder Set{0}(int index, {1}.Builder builderForValue) {{", PropertyName, TypeName);
-      AddNullCheck(writer, "builderForValue");
-      writer.WriteLine("  result.{0}_[index] = builderForValue.Build();", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
-      AddNullCheck(writer);
-      writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      // Extra overload for builder (just on messages)
-      writer.WriteLine("public Builder Add{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
-      AddNullCheck(writer, "builderForValue");
-      writer.WriteLine("  result.{0}_.Add(builderForValue.Build());", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
-      writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
-      writer.WriteLine("  result.{0}_.Clear();", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-    }    
-
-    public void GenerateMergingCode(TextGenerator writer) {
-      writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
-      writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuildingCode(TextGenerator writer) {
-      writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
-    }
-
-    public void GenerateParsingCode(TextGenerator writer) {
-      writer.WriteLine("{0}.Builder subBuilder = {0}.CreateBuilder();", TypeName);
-      if (Descriptor.FieldType == FieldType.Group) {
-        writer.WriteLine("input.ReadGroup({0}, subBuilder, extensionRegistry);", Number);
-      } else {
-        writer.WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");
-      }
-      writer.WriteLine("Add{0}(subBuilder.BuildPartial());", PropertyName);
-    }
-
-    public void GenerateSerializationCode(TextGenerator writer) {
-      writer.WriteLine("foreach ({0} element in {1}List) {{", TypeName, PropertyName);
-      writer.WriteLine("  output.Write{0}({1}, element);", MessageOrGroup, Number);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateSerializedSizeCode(TextGenerator writer) {
-      writer.WriteLine("foreach ({0} element in {1}List) {{", TypeName, PropertyName);
-      writer.WriteLine("  size += pb::CodedOutputStream.Compute{0}Size({1}, element);", MessageOrGroup, Number);
-      writer.WriteLine("}");
-    }
-
-    public override void WriteHash(TextGenerator writer) {
-      writer.WriteLine("foreach({0} i in {1}_)", TypeName, Name);
-      writer.WriteLine("  hash ^= i.GetHashCode();");
-    }
-
-    public override void WriteEquals(TextGenerator writer) {
-      writer.WriteLine("if({0}_.Count != other.{0}_.Count) return false;", Name);
-      writer.WriteLine("for(int ix=0; ix < {0}_.Count; ix++)", Name);
-      writer.WriteLine("  if(!{0}_[ix].Equals(other.{0}_[ix])) return false;", Name);
-    }
-
-    public override void WriteToString(TextGenerator writer) {
-      writer.WriteLine("PrintField(\"{0}\", {1}_, writer);",
-        Descriptor.FieldType == FieldType.Group ? Descriptor.MessageType.Name : Descriptor.Name, Name);
-    }
-
-  }
-}
+#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.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class RepeatedMessageFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
+    {
+        internal RepeatedMessageFieldGenerator(FieldDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        public void GenerateMembers(TextGenerator writer)
+        {
+            writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
+            writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return {0}_; }}", Name);
+            writer.WriteLine("}");
+
+            // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
+            writer.WriteLine("public int {0}Count {{", PropertyName);
+            writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
+            writer.WriteLine("}");
+
+            writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
+            writer.WriteLine("  return {0}_[index];", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuilderMembers(TextGenerator writer)
+        {
+            // Note:  We can return the original list here, because we make it unmodifiable when we build
+            // We return it via IPopsicleList so that collection initializers work more pleasantly.
+            writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return result.{0}_; }}", Name);
+            writer.WriteLine("}");
+            writer.WriteLine("public int {0}Count {{", PropertyName);
+            writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
+            writer.WriteLine("}");
+            writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
+            writer.WriteLine("  return result.Get{0}(index);", PropertyName);
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
+            AddNullCheck(writer);
+            writer.WriteLine("  result.{0}_[index] = value;", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            // Extra overload for builder (just on messages)
+            writer.WriteLine("public Builder Set{0}(int index, {1}.Builder builderForValue) {{", PropertyName, TypeName);
+            AddNullCheck(writer, "builderForValue");
+            writer.WriteLine("  result.{0}_[index] = builderForValue.Build();", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
+            AddNullCheck(writer);
+            writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            // Extra overload for builder (just on messages)
+            writer.WriteLine("public Builder Add{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
+            AddNullCheck(writer, "builderForValue");
+            writer.WriteLine("  result.{0}_.Add(builderForValue.Build());", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
+            writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  result.{0}_.Clear();", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+        }
+
+        public void GenerateMergingCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
+            writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuildingCode(TextGenerator writer)
+        {
+            writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
+        }
+
+        public void GenerateParsingCode(TextGenerator writer)
+        {
+            writer.WriteLine("{0}.Builder subBuilder = {0}.CreateBuilder();", TypeName);
+            if (Descriptor.FieldType == FieldType.Group)
+            {
+                writer.WriteLine("input.ReadGroup({0}, subBuilder, extensionRegistry);", Number);
+            }
+            else
+            {
+                writer.WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");
+            }
+            writer.WriteLine("Add{0}(subBuilder.BuildPartial());", PropertyName);
+        }
+
+        public void GenerateSerializationCode(TextGenerator writer)
+        {
+            writer.WriteLine("foreach ({0} element in {1}List) {{", TypeName, PropertyName);
+            writer.WriteLine("  output.Write{0}({1}, element);", MessageOrGroup, Number);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateSerializedSizeCode(TextGenerator writer)
+        {
+            writer.WriteLine("foreach ({0} element in {1}List) {{", TypeName, PropertyName);
+            writer.WriteLine("  size += pb::CodedOutputStream.Compute{0}Size({1}, element);", MessageOrGroup, Number);
+            writer.WriteLine("}");
+        }
+
+        public override void WriteHash(TextGenerator writer)
+        {
+            writer.WriteLine("foreach({0} i in {1}_)", TypeName, Name);
+            writer.WriteLine("  hash ^= i.GetHashCode();");
+        }
+
+        public override void WriteEquals(TextGenerator writer)
+        {
+            writer.WriteLine("if({0}_.Count != other.{0}_.Count) return false;", Name);
+            writer.WriteLine("for(int ix=0; ix < {0}_.Count; ix++)", Name);
+            writer.WriteLine("  if(!{0}_[ix].Equals(other.{0}_[ix])) return false;", Name);
+        }
+
+        public override void WriteToString(TextGenerator writer)
+        {
+            writer.WriteLine("PrintField(\"{0}\", {1}_, writer);",
+                             Descriptor.FieldType == FieldType.Group ? Descriptor.MessageType.Name : Descriptor.Name,
+                             Name);
+        }
+    }
+}

+ 216 - 187
src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs

@@ -1,187 +1,216 @@
-#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.DescriptorProtos;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class RepeatedPrimitiveFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator {
-
-    internal RepeatedPrimitiveFieldGenerator(FieldDescriptor descriptor)
-      : base(descriptor) {
-    }
-
-    public void GenerateMembers(TextGenerator writer) {
-      if (Descriptor.IsPacked && OptimizeSpeed) {
-        writer.WriteLine("private int {0}MemoizedSerializedSize;", Name);
-      }
-      writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return pbc::Lists.AsReadOnly({0}_); }}", Name);
-      writer.WriteLine("}");
-
-      // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
-      writer.WriteLine("public int {0}Count {{", PropertyName);
-      writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
-      writer.WriteLine("}");
-
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
-      writer.WriteLine("  return {0}_[index];", Name);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuilderMembers(TextGenerator writer) {
-      // Note:  We can return the original list here, because we make it unmodifiable when we build
-      // We return it via IPopsicleList so that collection initializers work more pleasantly.
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
-      writer.WriteLine("  get {{ return result.{0}_; }}", Name);
-      writer.WriteLine("}");
-      writer.WriteLine("public int {0}Count {{", PropertyName);
-      writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
-      writer.WriteLine("  return result.Get{0}(index);", PropertyName);
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
-      AddNullCheck(writer);
-      writer.WriteLine("  result.{0}_[index] = value;", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
-      AddNullCheck(writer);
-      writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      AddClsComplianceCheck(writer);
-      writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
-      writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-      writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
-      writer.WriteLine("  result.{0}_.Clear();", Name);
-      writer.WriteLine("  return this;");
-      writer.WriteLine("}");
-    }
-
-    public void GenerateMergingCode(TextGenerator writer) {
-      writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
-      writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
-      writer.WriteLine("}");
-    }
-
-    public void GenerateBuildingCode(TextGenerator writer) {
-      writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
-    }
-
-    public void GenerateParsingCode(TextGenerator writer) {
-      if (Descriptor.IsPacked) {
-        writer.WriteLine("int length = input.ReadInt32();");
-        writer.WriteLine("int limit = input.PushLimit(length);");
-        writer.WriteLine("while (!input.ReachedLimit) {");
-        writer.WriteLine("  Add{0}(input.Read{1}());", PropertyName, CapitalizedTypeName);
-        writer.WriteLine("}");
-        writer.WriteLine("input.PopLimit(limit);");
-      } else {
-        writer.WriteLine("Add{0}(input.Read{1}());", PropertyName, CapitalizedTypeName);
-      }
-    }
-
-    public void GenerateSerializationCode(TextGenerator writer) {
-      writer.WriteLine("if ({0}_.Count > 0) {{", Name);
-      writer.Indent();
-      if (Descriptor.IsPacked) {
-        writer.WriteLine("output.WriteRawVarint32({0});", WireFormat.MakeTag(Descriptor));
-        writer.WriteLine("output.WriteRawVarint32((uint) {0}MemoizedSerializedSize);", Name);
-        writer.WriteLine("foreach ({0} element in {1}_) {{", TypeName, Name);
-        writer.WriteLine("  output.Write{0}NoTag(element);", CapitalizedTypeName);
-        writer.WriteLine("}");
-      } else {
-        writer.WriteLine("foreach ({0} element in {1}_) {{", TypeName, Name);
-        writer.WriteLine("  output.Write{0}({1}, element);", CapitalizedTypeName, Number);
-        writer.WriteLine("}");
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-    }
-
-    public void GenerateSerializedSizeCode(TextGenerator writer) {
-      writer.WriteLine("{");
-      writer.Indent();
-      writer.WriteLine("int dataSize = 0;");
-      if (FixedSize == -1) {
-        writer.WriteLine("foreach ({0} element in {1}List) {{", TypeName, PropertyName);
-        writer.WriteLine("  dataSize += pb::CodedOutputStream.Compute{0}SizeNoTag(element);", CapitalizedTypeName, Number);
-        writer.WriteLine("}");
-      } else {
-        writer.WriteLine("dataSize = {0} * {1}_.Count;", FixedSize, Name);
-      }
-      writer.WriteLine("size += dataSize;");
-      int tagSize = CodedOutputStream.ComputeTagSize(Descriptor.FieldNumber);
-      if (Descriptor.IsPacked) {
-        writer.WriteLine("if ({0}_.Count != 0) {{", Name);
-        writer.WriteLine("  size += {0} + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);", tagSize);
-        writer.WriteLine("}");
-      } else {
-        writer.WriteLine("size += {0} * {1}_.Count;", tagSize, Name);
-      }
-      // cache the data size for packed fields.
-      if (Descriptor.IsPacked) {
-        writer.WriteLine("{0}MemoizedSerializedSize = dataSize;", Name);
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-    }
-
-    public override void WriteHash(TextGenerator writer) {
-      writer.WriteLine("foreach({0} i in {1}_)", TypeName, Name);
-      writer.WriteLine("  hash ^= i.GetHashCode();");
-    }
-
-    public override void WriteEquals(TextGenerator writer) {
-      writer.WriteLine("if({0}_.Count != other.{0}_.Count) return false;", Name);
-      writer.WriteLine("for(int ix=0; ix < {0}_.Count; ix++)", Name);
-      writer.WriteLine("  if(!{0}_[ix].Equals(other.{0}_[ix])) return false;", Name);
-    }
-
-    public override void WriteToString(TextGenerator writer) {
-      writer.WriteLine("PrintField(\"{0}\", {1}_, writer);", Descriptor.Name, Name);
-    }
-  }
-}
+#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.DescriptorProtos;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class RepeatedPrimitiveFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
+    {
+        internal RepeatedPrimitiveFieldGenerator(FieldDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        public void GenerateMembers(TextGenerator writer)
+        {
+            if (Descriptor.IsPacked && OptimizeSpeed)
+            {
+                writer.WriteLine("private int {0}MemoizedSerializedSize;", Name);
+            }
+            writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return pbc::Lists.AsReadOnly({0}_); }}", Name);
+            writer.WriteLine("}");
+
+            // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
+            writer.WriteLine("public int {0}Count {{", PropertyName);
+            writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
+            writer.WriteLine("}");
+
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
+            writer.WriteLine("  return {0}_[index];", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuilderMembers(TextGenerator writer)
+        {
+            // Note:  We can return the original list here, because we make it unmodifiable when we build
+            // We return it via IPopsicleList so that collection initializers work more pleasantly.
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
+            writer.WriteLine("  get {{ return result.{0}_; }}", Name);
+            writer.WriteLine("}");
+            writer.WriteLine("public int {0}Count {{", PropertyName);
+            writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
+            writer.WriteLine("  return result.Get{0}(index);", PropertyName);
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
+            AddNullCheck(writer);
+            writer.WriteLine("  result.{0}_[index] = value;", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
+            AddNullCheck(writer);
+            writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            AddClsComplianceCheck(writer);
+            writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
+            writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+            writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  result.{0}_.Clear();", Name);
+            writer.WriteLine("  return this;");
+            writer.WriteLine("}");
+        }
+
+        public void GenerateMergingCode(TextGenerator writer)
+        {
+            writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
+            writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
+            writer.WriteLine("}");
+        }
+
+        public void GenerateBuildingCode(TextGenerator writer)
+        {
+            writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
+        }
+
+        public void GenerateParsingCode(TextGenerator writer)
+        {
+            if (Descriptor.IsPacked)
+            {
+                writer.WriteLine("int length = input.ReadInt32();");
+                writer.WriteLine("int limit = input.PushLimit(length);");
+                writer.WriteLine("while (!input.ReachedLimit) {");
+                writer.WriteLine("  Add{0}(input.Read{1}());", PropertyName, CapitalizedTypeName);
+                writer.WriteLine("}");
+                writer.WriteLine("input.PopLimit(limit);");
+            }
+            else
+            {
+                writer.WriteLine("Add{0}(input.Read{1}());", PropertyName, CapitalizedTypeName);
+            }
+        }
+
+        public void GenerateSerializationCode(TextGenerator writer)
+        {
+            writer.WriteLine("if ({0}_.Count > 0) {{", Name);
+            writer.Indent();
+            if (Descriptor.IsPacked)
+            {
+                writer.WriteLine("output.WriteRawVarint32({0});", WireFormat.MakeTag(Descriptor));
+                writer.WriteLine("output.WriteRawVarint32((uint) {0}MemoizedSerializedSize);", Name);
+                writer.WriteLine("foreach ({0} element in {1}_) {{", TypeName, Name);
+                writer.WriteLine("  output.Write{0}NoTag(element);", CapitalizedTypeName);
+                writer.WriteLine("}");
+            }
+            else
+            {
+                writer.WriteLine("foreach ({0} element in {1}_) {{", TypeName, Name);
+                writer.WriteLine("  output.Write{0}({1}, element);", CapitalizedTypeName, Number);
+                writer.WriteLine("}");
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+        }
+
+        public void GenerateSerializedSizeCode(TextGenerator writer)
+        {
+            writer.WriteLine("{");
+            writer.Indent();
+            writer.WriteLine("int dataSize = 0;");
+            if (FixedSize == -1)
+            {
+                writer.WriteLine("foreach ({0} element in {1}List) {{", TypeName, PropertyName);
+                writer.WriteLine("  dataSize += pb::CodedOutputStream.Compute{0}SizeNoTag(element);",
+                                 CapitalizedTypeName, Number);
+                writer.WriteLine("}");
+            }
+            else
+            {
+                writer.WriteLine("dataSize = {0} * {1}_.Count;", FixedSize, Name);
+            }
+            writer.WriteLine("size += dataSize;");
+            int tagSize = CodedOutputStream.ComputeTagSize(Descriptor.FieldNumber);
+            if (Descriptor.IsPacked)
+            {
+                writer.WriteLine("if ({0}_.Count != 0) {{", Name);
+                writer.WriteLine("  size += {0} + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);", tagSize);
+                writer.WriteLine("}");
+            }
+            else
+            {
+                writer.WriteLine("size += {0} * {1}_.Count;", tagSize, Name);
+            }
+            // cache the data size for packed fields.
+            if (Descriptor.IsPacked)
+            {
+                writer.WriteLine("{0}MemoizedSerializedSize = dataSize;", Name);
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+        }
+
+        public override void WriteHash(TextGenerator writer)
+        {
+            writer.WriteLine("foreach({0} i in {1}_)", TypeName, Name);
+            writer.WriteLine("  hash ^= i.GetHashCode();");
+        }
+
+        public override void WriteEquals(TextGenerator writer)
+        {
+            writer.WriteLine("if({0}_.Count != other.{0}_.Count) return false;", Name);
+            writer.WriteLine("for(int ix=0; ix < {0}_.Count; ix++)", Name);
+            writer.WriteLine("  if(!{0}_[ix].Equals(other.{0}_[ix])) return false;", Name);
+        }
+
+        public override void WriteToString(TextGenerator writer)
+        {
+            writer.WriteLine("PrintField(\"{0}\", {1}_, writer);", Descriptor.Name, Name);
+        }
+    }
+}

+ 184 - 168
src/ProtoGen/ServiceGenerator.cs

@@ -1,169 +1,185 @@
-#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.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class GenericServiceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator {
-
-    private enum RequestOrResponse {
-      Request,
-      Response
-    }
+#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.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class GenericServiceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator
+    {
+        private enum RequestOrResponse
+        {
+            Request,
+            Response
+        }
+
+        internal GenericServiceGenerator(ServiceDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        public void Generate(TextGenerator writer)
+        {
+            writer.WriteLine("{0} abstract class {1} : pb::IService {{", ClassAccessLevel, Descriptor.Name);
+            writer.Indent();
+
+            foreach (MethodDescriptor method in Descriptor.Methods)
+            {
+                writer.WriteLine("{0} abstract void {1}(", ClassAccessLevel,
+                                 NameHelpers.UnderscoresToPascalCase(method.Name));
+                writer.WriteLine("    pb::IRpcController controller,");
+                writer.WriteLine("    {0} request,", GetClassName(method.InputType));
+                writer.WriteLine("    global::System.Action<{0}> done);", GetClassName(method.OutputType));
+            }
 
-    internal GenericServiceGenerator(ServiceDescriptor descriptor)
-      : base(descriptor) {
-    }
-
-    public void Generate(TextGenerator writer) {
-      writer.WriteLine("{0} abstract class {1} : pb::IService {{", ClassAccessLevel, Descriptor.Name);
-      writer.Indent();
-
-      foreach (MethodDescriptor method in Descriptor.Methods) {
-        writer.WriteLine("{0} abstract void {1}(", ClassAccessLevel, NameHelpers.UnderscoresToPascalCase(method.Name));
-        writer.WriteLine("    pb::IRpcController controller,");
-        writer.WriteLine("    {0} request,", GetClassName(method.InputType));
-        writer.WriteLine("    global::System.Action<{0}> done);", GetClassName(method.OutputType));
-      }
-
-      // Generate Descriptor and DescriptorForType.
-      writer.WriteLine();
-      writer.WriteLine("{0} static pbd::ServiceDescriptor Descriptor {{", ClassAccessLevel);
-      writer.WriteLine("  get {{ return {0}.Descriptor.Services[{1}]; }}",
-        DescriptorUtil.GetQualifiedUmbrellaClassName(Descriptor.File.CSharpOptions), Descriptor.Index);
-      writer.WriteLine("}");
-      writer.WriteLine("{0} pbd::ServiceDescriptor DescriptorForType {{", ClassAccessLevel);
-      writer.WriteLine("  get { return Descriptor; }");
-      writer.WriteLine("}");
-
-      GenerateCallMethod(writer);
-      GenerateGetPrototype(RequestOrResponse.Request, writer);
-      GenerateGetPrototype(RequestOrResponse.Response, writer);
-      GenerateStub(writer);
-
-      writer.Outdent();
-      writer.WriteLine("}");
-    }
-
-    private void GenerateCallMethod(TextGenerator writer) {
-      writer.WriteLine();
-      writer.WriteLine("public void CallMethod(", ClassAccessLevel);
-      writer.WriteLine("    pbd::MethodDescriptor method,");
-      writer.WriteLine("    pb::IRpcController controller,");
-      writer.WriteLine("    pb::IMessage request,");
-      writer.WriteLine("    global::System.Action<pb::IMessage> done) {");
-      writer.Indent();
-      writer.WriteLine("if (method.Service != Descriptor) {");
-      writer.WriteLine("  throw new global::System.ArgumentException(");
-      writer.WriteLine("      \"Service.CallMethod() given method descriptor for wrong service type.\");");
-      writer.WriteLine("}");
-      writer.WriteLine("switch(method.Index) {");
-      writer.Indent();
-      foreach (MethodDescriptor method in Descriptor.Methods) {
-        writer.WriteLine("case {0}:", method.Index);
-        writer.WriteLine("  this.{0}(controller, ({1}) request,",
-            NameHelpers.UnderscoresToPascalCase(method.Name), GetClassName(method.InputType));
-        writer.WriteLine("      pb::RpcUtil.SpecializeCallback<{0}>(", GetClassName(method.OutputType));
-        writer.WriteLine("      done));");
-        writer.WriteLine("  return;");
-      }
-      writer.WriteLine("default:");
-      writer.WriteLine("  throw new global::System.InvalidOperationException(\"Can't get here.\");");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-    }
-
-    private void GenerateGetPrototype(RequestOrResponse which, TextGenerator writer) {
-      writer.WriteLine("public pb::IMessage Get{0}Prototype(pbd::MethodDescriptor method) {{", which);
-      writer.Indent();
-      writer.WriteLine("if (method.Service != Descriptor) {");
-      writer.WriteLine("  throw new global::System.ArgumentException(");
-      writer.WriteLine("      \"Service.Get{0}Prototype() given method descriptor for wrong service type.\");", which);
-      writer.WriteLine("}");
-      writer.WriteLine("switch(method.Index) {");
-      writer.Indent();
-
-      foreach (MethodDescriptor method in Descriptor.Methods) {
-        writer.WriteLine("case {0}:", method.Index);
-        writer.WriteLine("  return {0}.DefaultInstance;", 
-          GetClassName(which == RequestOrResponse.Request ? method.InputType : method.OutputType));
-      }
-      writer.WriteLine("default:");
-      writer.WriteLine("  throw new global::System.InvalidOperationException(\"Can't get here.\");");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine();
-    }
-
-    private void GenerateStub(TextGenerator writer) {
-      writer.WriteLine("public static Stub CreateStub(pb::IRpcChannel channel) {");
-      writer.WriteLine("  return new Stub(channel);");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("{0} class Stub : {1} {{", ClassAccessLevel, GetClassName(Descriptor));
-      writer.Indent();
-      writer.WriteLine("internal Stub(pb::IRpcChannel channel) {");
-      writer.WriteLine("  this.channel = channel;");
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("private readonly pb::IRpcChannel channel;");
-      writer.WriteLine();
-      writer.WriteLine("public pb::IRpcChannel Channel {");
-      writer.WriteLine("  get { return channel; }");
-      writer.WriteLine("}");
-
-      foreach (MethodDescriptor method in Descriptor.Methods) {
-        writer.WriteLine();
-        writer.WriteLine("public override void {0}(", NameHelpers.UnderscoresToPascalCase(method.Name));
-        writer.WriteLine("    pb::IRpcController controller,");
-        writer.WriteLine("    {0} request,", GetClassName(method.InputType));
-        writer.WriteLine("    global::System.Action<{0}> done) {{", GetClassName(method.OutputType));
-        writer.Indent();
-        writer.WriteLine("channel.CallMethod(Descriptor.Methods[{0}],", method.Index);
-        writer.WriteLine("    controller, request, {0}.DefaultInstance,", GetClassName(method.OutputType));
-        writer.WriteLine("    pb::RpcUtil.GeneralizeCallback<{0}, {0}.Builder>(done, {0}.DefaultInstance));",
-            GetClassName(method.OutputType));
-        writer.Outdent();
-        writer.WriteLine("}");
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-    }
-  }
-}
+            // Generate Descriptor and DescriptorForType.
+            writer.WriteLine();
+            writer.WriteLine("{0} static pbd::ServiceDescriptor Descriptor {{", ClassAccessLevel);
+            writer.WriteLine("  get {{ return {0}.Descriptor.Services[{1}]; }}",
+                             DescriptorUtil.GetQualifiedUmbrellaClassName(Descriptor.File.CSharpOptions),
+                             Descriptor.Index);
+            writer.WriteLine("}");
+            writer.WriteLine("{0} pbd::ServiceDescriptor DescriptorForType {{", ClassAccessLevel);
+            writer.WriteLine("  get { return Descriptor; }");
+            writer.WriteLine("}");
+
+            GenerateCallMethod(writer);
+            GenerateGetPrototype(RequestOrResponse.Request, writer);
+            GenerateGetPrototype(RequestOrResponse.Response, writer);
+            GenerateStub(writer);
+
+            writer.Outdent();
+            writer.WriteLine("}");
+        }
+
+        private void GenerateCallMethod(TextGenerator writer)
+        {
+            writer.WriteLine();
+            writer.WriteLine("public void CallMethod(", ClassAccessLevel);
+            writer.WriteLine("    pbd::MethodDescriptor method,");
+            writer.WriteLine("    pb::IRpcController controller,");
+            writer.WriteLine("    pb::IMessage request,");
+            writer.WriteLine("    global::System.Action<pb::IMessage> done) {");
+            writer.Indent();
+            writer.WriteLine("if (method.Service != Descriptor) {");
+            writer.WriteLine("  throw new global::System.ArgumentException(");
+            writer.WriteLine("      \"Service.CallMethod() given method descriptor for wrong service type.\");");
+            writer.WriteLine("}");
+            writer.WriteLine("switch(method.Index) {");
+            writer.Indent();
+            foreach (MethodDescriptor method in Descriptor.Methods)
+            {
+                writer.WriteLine("case {0}:", method.Index);
+                writer.WriteLine("  this.{0}(controller, ({1}) request,",
+                                 NameHelpers.UnderscoresToPascalCase(method.Name), GetClassName(method.InputType));
+                writer.WriteLine("      pb::RpcUtil.SpecializeCallback<{0}>(", GetClassName(method.OutputType));
+                writer.WriteLine("      done));");
+                writer.WriteLine("  return;");
+            }
+            writer.WriteLine("default:");
+            writer.WriteLine("  throw new global::System.InvalidOperationException(\"Can't get here.\");");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+        }
+
+        private void GenerateGetPrototype(RequestOrResponse which, TextGenerator writer)
+        {
+            writer.WriteLine("public pb::IMessage Get{0}Prototype(pbd::MethodDescriptor method) {{", which);
+            writer.Indent();
+            writer.WriteLine("if (method.Service != Descriptor) {");
+            writer.WriteLine("  throw new global::System.ArgumentException(");
+            writer.WriteLine("      \"Service.Get{0}Prototype() given method descriptor for wrong service type.\");",
+                             which);
+            writer.WriteLine("}");
+            writer.WriteLine("switch(method.Index) {");
+            writer.Indent();
+
+            foreach (MethodDescriptor method in Descriptor.Methods)
+            {
+                writer.WriteLine("case {0}:", method.Index);
+                writer.WriteLine("  return {0}.DefaultInstance;",
+                                 GetClassName(which == RequestOrResponse.Request ? method.InputType : method.OutputType));
+            }
+            writer.WriteLine("default:");
+            writer.WriteLine("  throw new global::System.InvalidOperationException(\"Can't get here.\");");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+        }
+
+        private void GenerateStub(TextGenerator writer)
+        {
+            writer.WriteLine("public static Stub CreateStub(pb::IRpcChannel channel) {");
+            writer.WriteLine("  return new Stub(channel);");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("{0} class Stub : {1} {{", ClassAccessLevel, GetClassName(Descriptor));
+            writer.Indent();
+            writer.WriteLine("internal Stub(pb::IRpcChannel channel) {");
+            writer.WriteLine("  this.channel = channel;");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("private readonly pb::IRpcChannel channel;");
+            writer.WriteLine();
+            writer.WriteLine("public pb::IRpcChannel Channel {");
+            writer.WriteLine("  get { return channel; }");
+            writer.WriteLine("}");
+
+            foreach (MethodDescriptor method in Descriptor.Methods)
+            {
+                writer.WriteLine();
+                writer.WriteLine("public override void {0}(", NameHelpers.UnderscoresToPascalCase(method.Name));
+                writer.WriteLine("    pb::IRpcController controller,");
+                writer.WriteLine("    {0} request,", GetClassName(method.InputType));
+                writer.WriteLine("    global::System.Action<{0}> done) {{", GetClassName(method.OutputType));
+                writer.Indent();
+                writer.WriteLine("channel.CallMethod(Descriptor.Methods[{0}],", method.Index);
+                writer.WriteLine("    controller, request, {0}.DefaultInstance,", GetClassName(method.OutputType));
+                writer.WriteLine("    pb::RpcUtil.GeneralizeCallback<{0}, {0}.Builder>(done, {0}.DefaultInstance));",
+                                 GetClassName(method.OutputType));
+                writer.Outdent();
+                writer.WriteLine("}");
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+        }
+    }
+}

+ 239 - 197
src/ProtoGen/ServiceInterfaceGenerator.cs

@@ -1,4 +1,5 @@
 #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/
@@ -30,6 +31,7 @@
 // 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;
@@ -37,215 +39,255 @@ using System.Collections.Generic;
 using Google.ProtocolBuffers.DescriptorProtos;
 using Google.ProtocolBuffers.Descriptors;
 
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal class ServiceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator {
-
-    readonly CSharpServiceType svcType;
-    ISourceGenerator _generator;
-
-    internal ServiceGenerator(ServiceDescriptor descriptor)
-      : base(descriptor) {
-      svcType = descriptor.File.CSharpOptions.ServiceGeneratorType;
-      switch (svcType) {
-        case CSharpServiceType.NONE:
-          _generator = new NoServicesGenerator(descriptor);
-          break;
-        case CSharpServiceType.GENERIC:
-          _generator = new GenericServiceGenerator(descriptor);
-          break;
-        case CSharpServiceType.INTERFACE:
-          _generator = new ServiceInterfaceGenerator(descriptor);
-          break;
-        case CSharpServiceType.IRPCDISPATCH:
-          _generator = new RpcServiceGenerator(descriptor);
-          break;
-        default: throw new ApplicationException("Unknown ServiceGeneratorType = " + svcType.ToString());
-      }
-    }
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal class ServiceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator
+    {
+        private readonly CSharpServiceType svcType;
+        private ISourceGenerator _generator;
 
-    public void Generate(TextGenerator writer) {
-      _generator.Generate(writer);
-    }
-      
-    class NoServicesGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator {
-      
-      public NoServicesGenerator(ServiceDescriptor descriptor)
-        : base(descriptor) {
-      }
-      public virtual void Generate(TextGenerator writer) {
-        writer.WriteLine("/*");
-        writer.WriteLine("* Service generation is now disabled by default, use the following option to enable:");
-        writer.WriteLine("* option (google.protobuf.csharp_file_options).service_generator_type = GENERIC;");
-        writer.WriteLine("*/");
-      }
-    }
+        internal ServiceGenerator(ServiceDescriptor descriptor)
+            : base(descriptor)
+        {
+            svcType = descriptor.File.CSharpOptions.ServiceGeneratorType;
+            switch (svcType)
+            {
+                case CSharpServiceType.NONE:
+                    _generator = new NoServicesGenerator(descriptor);
+                    break;
+                case CSharpServiceType.GENERIC:
+                    _generator = new GenericServiceGenerator(descriptor);
+                    break;
+                case CSharpServiceType.INTERFACE:
+                    _generator = new ServiceInterfaceGenerator(descriptor);
+                    break;
+                case CSharpServiceType.IRPCDISPATCH:
+                    _generator = new RpcServiceGenerator(descriptor);
+                    break;
+                default:
+                    throw new ApplicationException("Unknown ServiceGeneratorType = " + svcType.ToString());
+            }
+        }
 
-    class ServiceInterfaceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator {
-      
-      public ServiceInterfaceGenerator(ServiceDescriptor descriptor)
-        : base(descriptor) {
-      }
+        public void Generate(TextGenerator writer)
+        {
+            _generator.Generate(writer);
+        }
 
-      public virtual void Generate(TextGenerator writer) {
+        private class NoServicesGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator
+        {
+            public NoServicesGenerator(ServiceDescriptor descriptor)
+                : base(descriptor)
+            {
+            }
 
-        CSharpServiceOptions options = Descriptor.Options.GetExtension(CSharpOptions.CsharpServiceOptions);
-        if (options != null && options.HasInterfaceId) {
-          writer.WriteLine("[global::System.Runtime.InteropServices.GuidAttribute(\"{0}\")]", new Guid(options.InterfaceId));
+            public virtual void Generate(TextGenerator writer)
+            {
+                writer.WriteLine("/*");
+                writer.WriteLine("* Service generation is now disabled by default, use the following option to enable:");
+                writer.WriteLine("* option (google.protobuf.csharp_file_options).service_generator_type = GENERIC;");
+                writer.WriteLine("*/");
+            }
         }
-        writer.WriteLine("{0} partial interface I{1} {{", ClassAccessLevel, Descriptor.Name);
-        writer.Indent();
 
-        foreach (MethodDescriptor method in Descriptor.Methods)
+        private class ServiceInterfaceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator
         {
-          CSharpMethodOptions mth = method.Options.GetExtension(CSharpOptions.CsharpMethodOptions);
-          if(mth.HasDispatchId) {
-            writer.WriteLine("[global::System.Runtime.InteropServices.DispId({0})]", mth.DispatchId);
-          }
-          writer.WriteLine("{0} {1}({2} {3});", GetClassName(method.OutputType), NameHelpers.UnderscoresToPascalCase(method.Name), GetClassName(method.InputType), NameHelpers.UnderscoresToCamelCase(method.InputType.Name));
+            public ServiceInterfaceGenerator(ServiceDescriptor descriptor)
+                : base(descriptor)
+            {
+            }
+
+            public virtual void Generate(TextGenerator writer)
+            {
+                CSharpServiceOptions options = Descriptor.Options.GetExtension(CSharpOptions.CsharpServiceOptions);
+                if (options != null && options.HasInterfaceId)
+                {
+                    writer.WriteLine("[global::System.Runtime.InteropServices.GuidAttribute(\"{0}\")]",
+                                     new Guid(options.InterfaceId));
+                }
+                writer.WriteLine("{0} partial interface I{1} {{", ClassAccessLevel, Descriptor.Name);
+                writer.Indent();
+
+                foreach (MethodDescriptor method in Descriptor.Methods)
+                {
+                    CSharpMethodOptions mth = method.Options.GetExtension(CSharpOptions.CsharpMethodOptions);
+                    if (mth.HasDispatchId)
+                    {
+                        writer.WriteLine("[global::System.Runtime.InteropServices.DispId({0})]", mth.DispatchId);
+                    }
+                    writer.WriteLine("{0} {1}({2} {3});", GetClassName(method.OutputType),
+                                     NameHelpers.UnderscoresToPascalCase(method.Name), GetClassName(method.InputType),
+                                     NameHelpers.UnderscoresToCamelCase(method.InputType.Name));
+                }
+
+                writer.Outdent();
+                writer.WriteLine("}");
+            }
         }
 
-        writer.Outdent();
-        writer.WriteLine("}");
-      }
-    }
-    
-    class RpcServiceGenerator : ServiceInterfaceGenerator {
+        private class RpcServiceGenerator : ServiceInterfaceGenerator
+        {
+            public RpcServiceGenerator(ServiceDescriptor descriptor)
+                : base(descriptor)
+            {
+            }
 
-      public RpcServiceGenerator(ServiceDescriptor descriptor)
-        : base(descriptor) {
-      }
+            public override void Generate(TextGenerator writer)
+            {
+                base.Generate(writer);
 
-      public override void Generate(TextGenerator writer)
-      {
-        base.Generate(writer);
+                writer.WriteLine();
 
-        writer.WriteLine();
+                // CLIENT Proxy
+                {
+                    if (Descriptor.File.CSharpOptions.ClsCompliance)
+                        writer.WriteLine("[global::System.CLSCompliant(false)]");
+                    writer.WriteLine("{0} partial class {1} : I{1}, pb::IRpcDispatch, global::System.IDisposable {{",
+                                     ClassAccessLevel, Descriptor.Name);
+                    writer.Indent();
+                    writer.WriteLine("private readonly bool dispose;");
+                    writer.WriteLine("private readonly pb::IRpcDispatch dispatch;");
 
-        // CLIENT Proxy
-        {
-          if (Descriptor.File.CSharpOptions.ClsCompliance)
-            writer.WriteLine("[global::System.CLSCompliant(false)]");
-          writer.WriteLine("{0} partial class {1} : I{1}, pb::IRpcDispatch, global::System.IDisposable {{", ClassAccessLevel, Descriptor.Name);
-          writer.Indent();
-          writer.WriteLine("private readonly bool dispose;");
-          writer.WriteLine("private readonly pb::IRpcDispatch dispatch;");
-
-          writer.WriteLine("public {0}(pb::IRpcDispatch dispatch) : this(dispatch, true) {{", Descriptor.Name);
-          writer.WriteLine("}");
-          writer.WriteLine("public {0}(pb::IRpcDispatch dispatch, bool dispose) {{", Descriptor.Name);
-          writer.WriteLine("  if (null == (this.dispatch = dispatch)) throw new global::System.ArgumentNullException();");
-          writer.WriteLine("  this.dispose = dispose && dispatch is global::System.IDisposable;");
-          writer.WriteLine("}");
-          writer.WriteLine();
-
-          writer.WriteLine("public void Dispose() {");
-          writer.WriteLine("  if (dispose) ((global::System.IDisposable)dispatch).Dispose();");
-          writer.WriteLine("}");
-          writer.WriteLine();
-          writer.WriteLine("TMessage pb::IRpcDispatch.CallMethod<TMessage, TBuilder>(string method, pb::IMessageLite request, pb::IBuilderLite<TMessage, TBuilder> response) {");
-          writer.WriteLine("  return dispatch.CallMethod(method, request, response);");
-          writer.WriteLine("}");
-          writer.WriteLine();
-
-          foreach (MethodDescriptor method in Descriptor.Methods) {
-            writer.WriteLine("public {0} {1}({2} {3}) {{", GetClassName(method.OutputType), NameHelpers.UnderscoresToPascalCase(method.Name), GetClassName(method.InputType), NameHelpers.UnderscoresToCamelCase(method.InputType.Name));
-            writer.WriteLine("   return dispatch.CallMethod(\"{0}\", {1}, {2}.CreateBuilder());",
-                             method.Name,
-                             NameHelpers.UnderscoresToCamelCase(method.InputType.Name),
-                             GetClassName(method.OutputType)
-              );
-            writer.WriteLine("}");
-            writer.WriteLine();
-          }
-        }
-        // SERVER - DISPATCH
-        {
-          if (Descriptor.File.CSharpOptions.ClsCompliance)
-            writer.WriteLine("[global::System.CLSCompliant(false)]");
-          writer.WriteLine("public partial class Dispatch : pb::IRpcDispatch, global::System.IDisposable {");
-          writer.Indent();
-          writer.WriteLine("private readonly bool dispose;");
-          writer.WriteLine("private readonly I{0} implementation;", Descriptor.Name);
-
-          writer.WriteLine("public Dispatch(I{0} implementation) : this(implementation, true) {{", Descriptor.Name);
-          writer.WriteLine("}");
-          writer.WriteLine("public Dispatch(I{0} implementation, bool dispose) {{", Descriptor.Name);
-          writer.WriteLine("  if (null == (this.implementation = implementation)) throw new global::System.ArgumentNullException();");
-          writer.WriteLine("  this.dispose = dispose && implementation is global::System.IDisposable;");
-          writer.WriteLine("}");
-          writer.WriteLine();
-
-          writer.WriteLine("public void Dispose() {");
-          writer.WriteLine("  if (dispose) ((global::System.IDisposable)implementation).Dispose();");
-          writer.WriteLine("}");
-          writer.WriteLine();
-
-          writer.WriteLine("public TMessage CallMethod<TMessage, TBuilder>(string methodName, pb::IMessageLite request, pb::IBuilderLite<TMessage, TBuilder> response)");
-          writer.WriteLine("  where TMessage : IMessageLite<TMessage, TBuilder>");
-          writer.WriteLine("  where TBuilder : IBuilderLite<TMessage, TBuilder> {");
-          writer.Indent();
-          writer.WriteLine("switch(methodName) {");
-          writer.Indent();
-
-          foreach (MethodDescriptor method in Descriptor.Methods) {
-            writer.WriteLine("case \"{0}\": return response.MergeFrom(implementation.{1}(({2})request)).Build();", method.Name, NameHelpers.UnderscoresToPascalCase(method.Name), GetClassName(method.InputType));
-          }
-          writer.WriteLine("default: throw new global::System.MissingMethodException(typeof(ISearchService).FullName, methodName);");
-          writer.Outdent();
-          writer.WriteLine("}");//end switch
-          writer.Outdent();
-          writer.WriteLine("}");//end invoke
-          writer.Outdent();
-          writer.WriteLine("}");//end server
-        }
-        // SERVER - STUB
-        {
-          if (Descriptor.File.CSharpOptions.ClsCompliance)
-            writer.WriteLine("[global::System.CLSCompliant(false)]");
-          writer.WriteLine("public partial class ServerStub : pb::IRpcServerStub, global::System.IDisposable {");
-          writer.Indent();
-          writer.WriteLine("private readonly bool dispose;");
-          writer.WriteLine("private readonly pb::IRpcDispatch implementation;", Descriptor.Name);
-
-          writer.WriteLine("public ServerStub(I{0} implementation) : this(implementation, true) {{", Descriptor.Name);
-          writer.WriteLine("}");
-          writer.WriteLine("public ServerStub(I{0} implementation, bool dispose) : this(new Dispatch(implementation, dispose), dispose) {{", Descriptor.Name);
-          writer.WriteLine("}");
-
-          writer.WriteLine("public ServerStub(pb::IRpcDispatch implementation) : this(implementation, true) {");
-          writer.WriteLine("}");
-          writer.WriteLine("public ServerStub(pb::IRpcDispatch implementation, bool dispose) {");
-          writer.WriteLine("  if (null == (this.implementation = implementation)) throw new global::System.ArgumentNullException();");
-          writer.WriteLine("  this.dispose = dispose && implementation is global::System.IDisposable;");
-          writer.WriteLine("}");
-          writer.WriteLine();
-
-          writer.WriteLine("public void Dispose() {");
-          writer.WriteLine("  if (dispose) ((global::System.IDisposable)implementation).Dispose();");
-          writer.WriteLine("}");
-          writer.WriteLine();
-
-          writer.WriteLine("public pb::IMessageLite CallMethod(string methodName, pb::CodedInputStream input, pb::ExtensionRegistry registry) {{", Descriptor.Name);
-          writer.Indent();
-          writer.WriteLine("switch(methodName) {");
-          writer.Indent();
-
-          foreach (MethodDescriptor method in Descriptor.Methods)
-          {
-            writer.WriteLine("case \"{0}\": return implementation.CallMethod(methodName, {1}.ParseFrom(input, registry), {2}.CreateBuilder());", method.Name, GetClassName(method.InputType), GetClassName(method.OutputType));
-          }
-          writer.WriteLine("default: throw new global::System.MissingMethodException(typeof(ISearchService).FullName, methodName);");
-          writer.Outdent();
-          writer.WriteLine("}");//end switch
-          writer.Outdent();
-          writer.WriteLine("}");//end invoke
-          writer.Outdent();
-          writer.WriteLine("}");//end server
-        }
+                    writer.WriteLine("public {0}(pb::IRpcDispatch dispatch) : this(dispatch, true) {{", Descriptor.Name);
+                    writer.WriteLine("}");
+                    writer.WriteLine("public {0}(pb::IRpcDispatch dispatch, bool dispose) {{", Descriptor.Name);
+                    writer.WriteLine(
+                        "  if (null == (this.dispatch = dispatch)) throw new global::System.ArgumentNullException();");
+                    writer.WriteLine("  this.dispose = dispose && dispatch is global::System.IDisposable;");
+                    writer.WriteLine("}");
+                    writer.WriteLine();
+
+                    writer.WriteLine("public void Dispose() {");
+                    writer.WriteLine("  if (dispose) ((global::System.IDisposable)dispatch).Dispose();");
+                    writer.WriteLine("}");
+                    writer.WriteLine();
+                    writer.WriteLine(
+                        "TMessage pb::IRpcDispatch.CallMethod<TMessage, TBuilder>(string method, pb::IMessageLite request, pb::IBuilderLite<TMessage, TBuilder> response) {");
+                    writer.WriteLine("  return dispatch.CallMethod(method, request, response);");
+                    writer.WriteLine("}");
+                    writer.WriteLine();
+
+                    foreach (MethodDescriptor method in Descriptor.Methods)
+                    {
+                        writer.WriteLine("public {0} {1}({2} {3}) {{", GetClassName(method.OutputType),
+                                         NameHelpers.UnderscoresToPascalCase(method.Name),
+                                         GetClassName(method.InputType),
+                                         NameHelpers.UnderscoresToCamelCase(method.InputType.Name));
+                        writer.WriteLine("   return dispatch.CallMethod(\"{0}\", {1}, {2}.CreateBuilder());",
+                                         method.Name,
+                                         NameHelpers.UnderscoresToCamelCase(method.InputType.Name),
+                                         GetClassName(method.OutputType)
+                            );
+                        writer.WriteLine("}");
+                        writer.WriteLine();
+                    }
+                }
+                // SERVER - DISPATCH
+                {
+                    if (Descriptor.File.CSharpOptions.ClsCompliance)
+                        writer.WriteLine("[global::System.CLSCompliant(false)]");
+                    writer.WriteLine("public partial class Dispatch : pb::IRpcDispatch, global::System.IDisposable {");
+                    writer.Indent();
+                    writer.WriteLine("private readonly bool dispose;");
+                    writer.WriteLine("private readonly I{0} implementation;", Descriptor.Name);
+
+                    writer.WriteLine("public Dispatch(I{0} implementation) : this(implementation, true) {{",
+                                     Descriptor.Name);
+                    writer.WriteLine("}");
+                    writer.WriteLine("public Dispatch(I{0} implementation, bool dispose) {{", Descriptor.Name);
+                    writer.WriteLine(
+                        "  if (null == (this.implementation = implementation)) throw new global::System.ArgumentNullException();");
+                    writer.WriteLine("  this.dispose = dispose && implementation is global::System.IDisposable;");
+                    writer.WriteLine("}");
+                    writer.WriteLine();
+
+                    writer.WriteLine("public void Dispose() {");
+                    writer.WriteLine("  if (dispose) ((global::System.IDisposable)implementation).Dispose();");
+                    writer.WriteLine("}");
+                    writer.WriteLine();
 
-        writer.Outdent();
-        writer.WriteLine("}");
-      }
+                    writer.WriteLine(
+                        "public TMessage CallMethod<TMessage, TBuilder>(string methodName, pb::IMessageLite request, pb::IBuilderLite<TMessage, TBuilder> response)");
+                    writer.WriteLine("  where TMessage : IMessageLite<TMessage, TBuilder>");
+                    writer.WriteLine("  where TBuilder : IBuilderLite<TMessage, TBuilder> {");
+                    writer.Indent();
+                    writer.WriteLine("switch(methodName) {");
+                    writer.Indent();
+
+                    foreach (MethodDescriptor method in Descriptor.Methods)
+                    {
+                        writer.WriteLine(
+                            "case \"{0}\": return response.MergeFrom(implementation.{1}(({2})request)).Build();",
+                            method.Name, NameHelpers.UnderscoresToPascalCase(method.Name),
+                            GetClassName(method.InputType));
+                    }
+                    writer.WriteLine(
+                        "default: throw new global::System.MissingMethodException(typeof(ISearchService).FullName, methodName);");
+                    writer.Outdent();
+                    writer.WriteLine("}"); //end switch
+                    writer.Outdent();
+                    writer.WriteLine("}"); //end invoke
+                    writer.Outdent();
+                    writer.WriteLine("}"); //end server
+                }
+                // SERVER - STUB
+                {
+                    if (Descriptor.File.CSharpOptions.ClsCompliance)
+                        writer.WriteLine("[global::System.CLSCompliant(false)]");
+                    writer.WriteLine(
+                        "public partial class ServerStub : pb::IRpcServerStub, global::System.IDisposable {");
+                    writer.Indent();
+                    writer.WriteLine("private readonly bool dispose;");
+                    writer.WriteLine("private readonly pb::IRpcDispatch implementation;", Descriptor.Name);
+
+                    writer.WriteLine("public ServerStub(I{0} implementation) : this(implementation, true) {{",
+                                     Descriptor.Name);
+                    writer.WriteLine("}");
+                    writer.WriteLine(
+                        "public ServerStub(I{0} implementation, bool dispose) : this(new Dispatch(implementation, dispose), dispose) {{",
+                        Descriptor.Name);
+                    writer.WriteLine("}");
+
+                    writer.WriteLine("public ServerStub(pb::IRpcDispatch implementation) : this(implementation, true) {");
+                    writer.WriteLine("}");
+                    writer.WriteLine("public ServerStub(pb::IRpcDispatch implementation, bool dispose) {");
+                    writer.WriteLine(
+                        "  if (null == (this.implementation = implementation)) throw new global::System.ArgumentNullException();");
+                    writer.WriteLine("  this.dispose = dispose && implementation is global::System.IDisposable;");
+                    writer.WriteLine("}");
+                    writer.WriteLine();
+
+                    writer.WriteLine("public void Dispose() {");
+                    writer.WriteLine("  if (dispose) ((global::System.IDisposable)implementation).Dispose();");
+                    writer.WriteLine("}");
+                    writer.WriteLine();
+
+                    writer.WriteLine(
+                        "public pb::IMessageLite CallMethod(string methodName, pb::CodedInputStream input, pb::ExtensionRegistry registry) {{",
+                        Descriptor.Name);
+                    writer.Indent();
+                    writer.WriteLine("switch(methodName) {");
+                    writer.Indent();
+
+                    foreach (MethodDescriptor method in Descriptor.Methods)
+                    {
+                        writer.WriteLine(
+                            "case \"{0}\": return implementation.CallMethod(methodName, {1}.ParseFrom(input, registry), {2}.CreateBuilder());",
+                            method.Name, GetClassName(method.InputType), GetClassName(method.OutputType));
+                    }
+                    writer.WriteLine(
+                        "default: throw new global::System.MissingMethodException(typeof(ISearchService).FullName, methodName);");
+                    writer.Outdent();
+                    writer.WriteLine("}"); //end switch
+                    writer.Outdent();
+                    writer.WriteLine("}"); //end invoke
+                    writer.Outdent();
+                    writer.WriteLine("}"); //end server
+                }
+
+                writer.Outdent();
+                writer.WriteLine("}");
+            }
+        }
     }
-  }
-}
+}

+ 156 - 131
src/ProtoGen/SourceGeneratorBase.cs

@@ -1,131 +1,156 @@
-#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.Collections.Generic;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  internal abstract class SourceGeneratorBase<T> where T : IDescriptor {
-
-    private readonly T descriptor;
-
-    protected readonly bool OptimizeSpeed;
-    protected readonly bool OptimizeSize;
-    protected readonly bool UseLiteRuntime;
-    protected readonly string RuntimeSuffix;
-
-    protected SourceGeneratorBase(T descriptor) {
-      this.descriptor = descriptor;
-
-      OptimizeSize = descriptor.File.Options.OptimizeFor == Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.CODE_SIZE;
-      OptimizeSpeed = descriptor.File.Options.OptimizeFor == Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED;
-      UseLiteRuntime = descriptor.File.Options.OptimizeFor == Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.LITE_RUNTIME;
-      //Lite runtime uses OptimizeSpeed code branches
-      OptimizeSpeed |= UseLiteRuntime;
-      RuntimeSuffix = UseLiteRuntime ? "Lite" : "";
-    }
-
-    protected T Descriptor {
-      get { return descriptor; }
-    }
-
-    internal static string GetClassName(IDescriptor descriptor) {
-      return ToCSharpName(descriptor.FullName, descriptor.File);
-    }
-
-    // Groups are hacky:  The name of the field is just the lower-cased name
-    // of the group type.  In C#, though, we would like to retain the original
-    // capitalization of the type name.
-    internal static string GetFieldName(FieldDescriptor descriptor) {
-      if (descriptor.FieldType == FieldType.Group) {
-        return descriptor.MessageType.Name;
-      } else {
-        return descriptor.Name;
-      }
-    }
-
-    internal static string GetFieldConstantName(FieldDescriptor field) {
-      return field.CSharpOptions.PropertyName + "FieldNumber";
-    }
-
-    private static string ToCSharpName(string name, FileDescriptor file) {
-      string result = file.CSharpOptions.Namespace;
-      if (file.CSharpOptions.NestClasses) {
-        if (result != "") {
-          result += ".";
-        }
-        result += file.CSharpOptions.UmbrellaClassname;
-      }
-      if (result != "") {
-        result += '.';
-      }
-      string classname;
-      if (file.Package == "") {
-        classname = name;
-      } else {
-        // Strip the proto package from full_name since we've replaced it with
-        // the C# namespace.
-        classname = name.Substring(file.Package.Length + 1);
-      }
-      result += classname.Replace(".", ".Types.");
-      return "global::" + result;
-    }
-
-    protected string ClassAccessLevel {
-      get { 
-        return descriptor.File.CSharpOptions.PublicClasses ? "public" : "internal";
-      }
-    }
-
-    protected void WriteChildren<TChild>(TextGenerator writer, string region, IEnumerable<TChild> children) 
-        where TChild : IDescriptor {
-      // Copy the set of children; makes access easier
-      List<TChild> copy = new List<TChild>(children);
-      if (copy.Count == 0) {
-        return;
-      }
-
-      if (region != null) {
-        writer.WriteLine("#region {0}", region);
-      }
-      foreach (TChild child in children) {
-        SourceGenerators.CreateGenerator(child).Generate(writer);
-      }
-      if (region != null) {
-        writer.WriteLine("#endregion");
-        writer.WriteLine();
-      }
-    }
-  }
-}
+#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.Collections.Generic;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    internal abstract class SourceGeneratorBase<T> where T : IDescriptor
+    {
+        private readonly T descriptor;
+
+        protected readonly bool OptimizeSpeed;
+        protected readonly bool OptimizeSize;
+        protected readonly bool UseLiteRuntime;
+        protected readonly string RuntimeSuffix;
+
+        protected SourceGeneratorBase(T descriptor)
+        {
+            this.descriptor = descriptor;
+
+            OptimizeSize = descriptor.File.Options.OptimizeFor ==
+                           Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.CODE_SIZE;
+            OptimizeSpeed = descriptor.File.Options.OptimizeFor ==
+                            Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED;
+            UseLiteRuntime = descriptor.File.Options.OptimizeFor ==
+                             Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.LITE_RUNTIME;
+            //Lite runtime uses OptimizeSpeed code branches
+            OptimizeSpeed |= UseLiteRuntime;
+            RuntimeSuffix = UseLiteRuntime ? "Lite" : "";
+        }
+
+        protected T Descriptor
+        {
+            get { return descriptor; }
+        }
+
+        internal static string GetClassName(IDescriptor descriptor)
+        {
+            return ToCSharpName(descriptor.FullName, descriptor.File);
+        }
+
+        // Groups are hacky:  The name of the field is just the lower-cased name
+        // of the group type.  In C#, though, we would like to retain the original
+        // capitalization of the type name.
+        internal static string GetFieldName(FieldDescriptor descriptor)
+        {
+            if (descriptor.FieldType == FieldType.Group)
+            {
+                return descriptor.MessageType.Name;
+            }
+            else
+            {
+                return descriptor.Name;
+            }
+        }
+
+        internal static string GetFieldConstantName(FieldDescriptor field)
+        {
+            return field.CSharpOptions.PropertyName + "FieldNumber";
+        }
+
+        private static string ToCSharpName(string name, FileDescriptor file)
+        {
+            string result = file.CSharpOptions.Namespace;
+            if (file.CSharpOptions.NestClasses)
+            {
+                if (result != "")
+                {
+                    result += ".";
+                }
+                result += file.CSharpOptions.UmbrellaClassname;
+            }
+            if (result != "")
+            {
+                result += '.';
+            }
+            string classname;
+            if (file.Package == "")
+            {
+                classname = name;
+            }
+            else
+            {
+                // Strip the proto package from full_name since we've replaced it with
+                // the C# namespace.
+                classname = name.Substring(file.Package.Length + 1);
+            }
+            result += classname.Replace(".", ".Types.");
+            return "global::" + result;
+        }
+
+        protected string ClassAccessLevel
+        {
+            get { return descriptor.File.CSharpOptions.PublicClasses ? "public" : "internal"; }
+        }
+
+        protected void WriteChildren<TChild>(TextGenerator writer, string region, IEnumerable<TChild> children)
+            where TChild : IDescriptor
+        {
+            // Copy the set of children; makes access easier
+            List<TChild> copy = new List<TChild>(children);
+            if (copy.Count == 0)
+            {
+                return;
+            }
+
+            if (region != null)
+            {
+                writer.WriteLine("#region {0}", region);
+            }
+            foreach (TChild child in children)
+            {
+                SourceGenerators.CreateGenerator(child).Generate(writer);
+            }
+            if (region != null)
+            {
+                writer.WriteLine("#endregion");
+                writer.WriteLine();
+            }
+        }
+    }
+}

+ 152 - 79
src/ProtoGen/SourceGenerators.cs

@@ -1,79 +1,152 @@
-#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.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-
-  public delegate TResult Func<T, TResult>(T arg);
-
-  internal static class SourceGenerators {
-
-    private static readonly Dictionary<Type, Func<IDescriptor, ISourceGenerator>> GeneratorFactories = new Dictionary<Type, Func<IDescriptor, ISourceGenerator>> {
-      { typeof(FileDescriptor), descriptor => new UmbrellaClassGenerator((FileDescriptor) descriptor) },
-      { typeof(EnumDescriptor), descriptor => new EnumGenerator((EnumDescriptor) descriptor) },
-      { typeof(ServiceDescriptor), descriptor => new ServiceGenerator((ServiceDescriptor) descriptor) },
-      { typeof(MessageDescriptor), descriptor => new MessageGenerator((MessageDescriptor) descriptor) },
-      // For other fields, we have IFieldSourceGenerators.
-      { typeof(FieldDescriptor), descriptor => new ExtensionGenerator((FieldDescriptor) descriptor) }
-    };
-
-    public static IFieldSourceGenerator CreateFieldGenerator(FieldDescriptor field) {
-      switch (field.MappedType) {
-        case MappedType.Message :
-          return field.IsRepeated 
-              ? (IFieldSourceGenerator) new RepeatedMessageFieldGenerator(field)
-              : new MessageFieldGenerator(field);
-        case MappedType.Enum:
-          return field.IsRepeated
-              ? (IFieldSourceGenerator)new RepeatedEnumFieldGenerator(field)
-              : new EnumFieldGenerator(field);
-        default:
-          return field.IsRepeated
-              ? (IFieldSourceGenerator)new RepeatedPrimitiveFieldGenerator(field)
-              : new PrimitiveFieldGenerator(field);
-      }
-    }
-
-    public static ISourceGenerator CreateGenerator<T>(T descriptor) where T : IDescriptor {
-      Func<IDescriptor, ISourceGenerator> factory;
-      if (!GeneratorFactories.TryGetValue(typeof(T), out factory)) {
-        throw new ArgumentException("No generator registered for " + typeof(T).Name);
-      }
-      return factory(descriptor);
-    }
-  }
-}
+#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.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    public delegate TResult Func<T, TResult>(T arg);
+
+    internal static class SourceGenerators
+    {
+        private static readonly Dictionary<Type, Func<IDescriptor, ISourceGenerator>> GeneratorFactories = new Dictionary
+            <Type, Func<IDescriptor, ISourceGenerator>>
+                                                                                                               {
+                                                                                                                   {
+                                                                                                                       typeof
+                                                                                                                       (
+                                                                                                                       FileDescriptor
+                                                                                                                       )
+                                                                                                                       ,
+                                                                                                                       descriptor
+                                                                                                                       =>
+                                                                                                                       new UmbrellaClassGenerator
+                                                                                                                           ((
+                                                                                                                            FileDescriptor
+                                                                                                                            )
+                                                                                                                            descriptor)
+                                                                                                                       },
+                                                                                                                   {
+                                                                                                                       typeof
+                                                                                                                       (
+                                                                                                                       EnumDescriptor
+                                                                                                                       )
+                                                                                                                       ,
+                                                                                                                       descriptor
+                                                                                                                       =>
+                                                                                                                       new EnumGenerator
+                                                                                                                           ((
+                                                                                                                            EnumDescriptor
+                                                                                                                            )
+                                                                                                                            descriptor)
+                                                                                                                       },
+                                                                                                                   {
+                                                                                                                       typeof
+                                                                                                                       (
+                                                                                                                       ServiceDescriptor
+                                                                                                                       )
+                                                                                                                       ,
+                                                                                                                       descriptor
+                                                                                                                       =>
+                                                                                                                       new ServiceGenerator
+                                                                                                                           ((
+                                                                                                                            ServiceDescriptor
+                                                                                                                            )
+                                                                                                                            descriptor)
+                                                                                                                       },
+                                                                                                                   {
+                                                                                                                       typeof
+                                                                                                                       (
+                                                                                                                       MessageDescriptor
+                                                                                                                       )
+                                                                                                                       ,
+                                                                                                                       descriptor
+                                                                                                                       =>
+                                                                                                                       new MessageGenerator
+                                                                                                                           ((
+                                                                                                                            MessageDescriptor
+                                                                                                                            )
+                                                                                                                            descriptor)
+                                                                                                                       },
+                                                                                                                   // For other fields, we have IFieldSourceGenerators.
+                                                                                                                   {
+                                                                                                                       typeof
+                                                                                                                       (
+                                                                                                                       FieldDescriptor
+                                                                                                                       )
+                                                                                                                       ,
+                                                                                                                       descriptor
+                                                                                                                       =>
+                                                                                                                       new ExtensionGenerator
+                                                                                                                           ((
+                                                                                                                            FieldDescriptor
+                                                                                                                            )
+                                                                                                                            descriptor)
+                                                                                                                       }
+                                                                                                               };
+
+        public static IFieldSourceGenerator CreateFieldGenerator(FieldDescriptor field)
+        {
+            switch (field.MappedType)
+            {
+                case MappedType.Message:
+                    return field.IsRepeated
+                               ? (IFieldSourceGenerator) new RepeatedMessageFieldGenerator(field)
+                               : new MessageFieldGenerator(field);
+                case MappedType.Enum:
+                    return field.IsRepeated
+                               ? (IFieldSourceGenerator) new RepeatedEnumFieldGenerator(field)
+                               : new EnumFieldGenerator(field);
+                default:
+                    return field.IsRepeated
+                               ? (IFieldSourceGenerator) new RepeatedPrimitiveFieldGenerator(field)
+                               : new PrimitiveFieldGenerator(field);
+            }
+        }
+
+        public static ISourceGenerator CreateGenerator<T>(T descriptor) where T : IDescriptor
+        {
+            Func<IDescriptor, ISourceGenerator> factory;
+            if (!GeneratorFactories.TryGetValue(typeof (T), out factory))
+            {
+                throw new ArgumentException("No generator registered for " + typeof (T).Name);
+            }
+            return factory(descriptor);
+        }
+    }
+}

+ 285 - 241
src/ProtoGen/UmbrellaClassGenerator.cs

@@ -1,241 +1,285 @@
-// 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.
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen {
-  /// <summary>
-  /// Generator for the class describing the .proto file in general,
-  /// containing things like the message descriptor.
-  /// </summary>
-  internal sealed class UmbrellaClassGenerator : SourceGeneratorBase<FileDescriptor>, ISourceGenerator {
-
-    internal UmbrellaClassGenerator(FileDescriptor descriptor)
-      : base(descriptor) {
-    }
-
-    // Recursively searches the given message to see if it contains any extensions.
-    private static bool UsesExtensions(IMessage message) {
-      // We conservatively assume that unknown fields are extensions.
-      if (message.UnknownFields.FieldDictionary.Count > 0) {
-        return true;
-      }
-
-      foreach (KeyValuePair<FieldDescriptor, object> keyValue in message.AllFields) {
-        FieldDescriptor field = keyValue.Key;
-        if (field.IsExtension) {
-          return true;
-        }
-        if (field.MappedType == MappedType.Message) {
-          if (field.IsRepeated) {
-            foreach (IMessage subMessage in (IEnumerable)keyValue.Value) {
-              if (UsesExtensions(subMessage)) {
-                return true;
-              }
-            }
-          } else {
-            if (UsesExtensions((IMessage)keyValue.Value)) {
-              return true;
-            }
-          }
-        }
-      }
-      return false;
-    }
-
-    public void Generate(TextGenerator writer) {
-      WriteIntroduction(writer);
-      WriteExtensionRegistration(writer);
-      WriteChildren(writer, "Extensions", Descriptor.Extensions);
-      writer.WriteLine("#region Static variables");
-      foreach (MessageDescriptor message in Descriptor.MessageTypes) {
-        new MessageGenerator(message).GenerateStaticVariables(writer);
-      }
-      writer.WriteLine("#endregion");
-      if (!UseLiteRuntime) {
-        WriteDescriptor(writer);
-      } else {
-        WriteLiteExtensions(writer);
-      }
-      // The class declaration either gets closed before or after the children are written.
-      if (!Descriptor.CSharpOptions.NestClasses) {
-        writer.Outdent();
-        writer.WriteLine("}");
-
-        // Close the namespace around the umbrella class if defined
-        if (!Descriptor.CSharpOptions.NestClasses && Descriptor.CSharpOptions.UmbrellaNamespace != "") {
-          writer.Outdent();
-          writer.WriteLine("}");
-        }
-      }
-      WriteChildren(writer, "Enums", Descriptor.EnumTypes);
-      WriteChildren(writer, "Messages", Descriptor.MessageTypes);
-      WriteChildren(writer, "Services", Descriptor.Services);
-      if (Descriptor.CSharpOptions.NestClasses) {
-        writer.Outdent();
-        writer.WriteLine("}");
-      }
-      if (Descriptor.CSharpOptions.Namespace != "") {
-        writer.Outdent();
-        writer.WriteLine("}");
-      }
-    }
-
-    private void WriteIntroduction(TextGenerator writer) {
-      writer.WriteLine("// Generated by {0}.  DO NOT EDIT!", this.GetType().Assembly.FullName);
-      writer.WriteLine();
-      writer.WriteLine("using pb = global::Google.ProtocolBuffers;");
-      writer.WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;");
-      writer.WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;");
-      writer.WriteLine("using scg = global::System.Collections.Generic;");
-
-      if (Descriptor.CSharpOptions.Namespace != "") {
-        writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.Namespace);
-        writer.Indent();
-        writer.WriteLine();
-      }
-      // Add the namespace around the umbrella class if defined
-      if(!Descriptor.CSharpOptions.NestClasses && Descriptor.CSharpOptions.UmbrellaNamespace != "") {
-        writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.UmbrellaNamespace);
-        writer.Indent();
-        writer.WriteLine();
-      }
-    
-      if (Descriptor.CSharpOptions.CodeContracts) {
-          writer.WriteLine("[global::System.Diagnostics.Contracts.ContractVerificationAttribute(false)]");
-      }
-      writer.WriteLine("{0} static partial class {1} {{", ClassAccessLevel, Descriptor.CSharpOptions.UmbrellaClassname);
-      writer.WriteLine();
-      writer.Indent();
-    }
-
-    private void WriteExtensionRegistration(TextGenerator writer) {
-      writer.WriteLine("#region Extension registration");
-      writer.WriteLine("public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {");
-      writer.Indent();
-      foreach (FieldDescriptor extension in Descriptor.Extensions) {
-        new ExtensionGenerator(extension).GenerateExtensionRegistrationCode(writer);
-      }
-      foreach (MessageDescriptor message in Descriptor.MessageTypes) {
-        new MessageGenerator(message).GenerateExtensionRegistrationCode(writer);
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine("#endregion");
-    }
-
-    private void WriteDescriptor(TextGenerator writer) {
-      writer.WriteLine("#region Descriptor");
-
-      writer.WriteLine("public static pbd::FileDescriptor Descriptor {");
-      writer.WriteLine("  get { return descriptor; }");
-      writer.WriteLine("}");
-      writer.WriteLine("private static pbd::FileDescriptor descriptor;");
-      writer.WriteLine();
-      writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
-      writer.Indent();
-      writer.WriteLine("byte[] descriptorData = global::System.Convert.FromBase64String(");
-      writer.Indent();
-      writer.Indent();
-
-      // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
-      byte[] bytes = Descriptor.Proto.ToByteArray();
-      string base64 = Convert.ToBase64String(bytes);
-
-      while (base64.Length > 60) {
-        writer.WriteLine("\"{0}\" + ", base64.Substring(0, 60));
-        base64 = base64.Substring(60);
-      }
-      writer.WriteLine("\"{0}\");", base64);
-      writer.Outdent();
-      writer.Outdent();
-      writer.WriteLine("pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {");
-      writer.Indent();
-      writer.WriteLine("descriptor = root;");
-      foreach (MessageDescriptor message in Descriptor.MessageTypes) {
-        new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
-      }
-      foreach (FieldDescriptor extension in Descriptor.Extensions) {
-        new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
-      }
-
-      if (UsesExtensions(Descriptor.Proto)) {
-        // Must construct an ExtensionRegistry containing all possible extensions
-        // and return it.
-        writer.WriteLine("pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();");
-        writer.WriteLine("RegisterAllExtensions(registry);");
-        foreach (FileDescriptor dependency in Descriptor.Dependencies) {
-          writer.WriteLine("{0}.RegisterAllExtensions(registry);", DescriptorUtil.GetFullUmbrellaClassName(dependency));
-        }
-        writer.WriteLine("return registry;");
-      } else {
-        writer.WriteLine("return null;");
-      }
-      writer.Outdent();
-      writer.WriteLine("};");
-
-      // -----------------------------------------------------------------
-      // Invoke internalBuildGeneratedFileFrom() to build the file.
-      writer.WriteLine("pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,");
-      writer.WriteLine("    new pbd::FileDescriptor[] {");
-      foreach (FileDescriptor dependency in Descriptor.Dependencies) {
-        writer.WriteLine("    {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency));
-      }
-      writer.WriteLine("    }, assigner);");
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine("#endregion");
-      writer.WriteLine();
-    }
-
-    private void WriteLiteExtensions(TextGenerator writer) {
-      writer.WriteLine("#region Extensions");
-      writer.WriteLine("internal static readonly object Descriptor;");
-      writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
-      writer.Indent();
-      writer.WriteLine("Descriptor = null;");
-
-      foreach (MessageDescriptor message in Descriptor.MessageTypes) {
-        new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
-      }
-      foreach (FieldDescriptor extension in Descriptor.Extensions) {
-        new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
-      }
-      writer.Outdent();
-      writer.WriteLine("}");
-      writer.WriteLine("#endregion");
-      writer.WriteLine();
-    }
-  }
-}
+// 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.
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+    /// <summary>
+    /// Generator for the class describing the .proto file in general,
+    /// containing things like the message descriptor.
+    /// </summary>
+    internal sealed class UmbrellaClassGenerator : SourceGeneratorBase<FileDescriptor>, ISourceGenerator
+    {
+        internal UmbrellaClassGenerator(FileDescriptor descriptor)
+            : base(descriptor)
+        {
+        }
+
+        // Recursively searches the given message to see if it contains any extensions.
+        private static bool UsesExtensions(IMessage message)
+        {
+            // We conservatively assume that unknown fields are extensions.
+            if (message.UnknownFields.FieldDictionary.Count > 0)
+            {
+                return true;
+            }
+
+            foreach (KeyValuePair<FieldDescriptor, object> keyValue in message.AllFields)
+            {
+                FieldDescriptor field = keyValue.Key;
+                if (field.IsExtension)
+                {
+                    return true;
+                }
+                if (field.MappedType == MappedType.Message)
+                {
+                    if (field.IsRepeated)
+                    {
+                        foreach (IMessage subMessage in (IEnumerable) keyValue.Value)
+                        {
+                            if (UsesExtensions(subMessage))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (UsesExtensions((IMessage) keyValue.Value))
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+
+        public void Generate(TextGenerator writer)
+        {
+            WriteIntroduction(writer);
+            WriteExtensionRegistration(writer);
+            WriteChildren(writer, "Extensions", Descriptor.Extensions);
+            writer.WriteLine("#region Static variables");
+            foreach (MessageDescriptor message in Descriptor.MessageTypes)
+            {
+                new MessageGenerator(message).GenerateStaticVariables(writer);
+            }
+            writer.WriteLine("#endregion");
+            if (!UseLiteRuntime)
+            {
+                WriteDescriptor(writer);
+            }
+            else
+            {
+                WriteLiteExtensions(writer);
+            }
+            // The class declaration either gets closed before or after the children are written.
+            if (!Descriptor.CSharpOptions.NestClasses)
+            {
+                writer.Outdent();
+                writer.WriteLine("}");
+
+                // Close the namespace around the umbrella class if defined
+                if (!Descriptor.CSharpOptions.NestClasses && Descriptor.CSharpOptions.UmbrellaNamespace != "")
+                {
+                    writer.Outdent();
+                    writer.WriteLine("}");
+                }
+            }
+            WriteChildren(writer, "Enums", Descriptor.EnumTypes);
+            WriteChildren(writer, "Messages", Descriptor.MessageTypes);
+            WriteChildren(writer, "Services", Descriptor.Services);
+            if (Descriptor.CSharpOptions.NestClasses)
+            {
+                writer.Outdent();
+                writer.WriteLine("}");
+            }
+            if (Descriptor.CSharpOptions.Namespace != "")
+            {
+                writer.Outdent();
+                writer.WriteLine("}");
+            }
+        }
+
+        private void WriteIntroduction(TextGenerator writer)
+        {
+            writer.WriteLine("// Generated by {0}.  DO NOT EDIT!", this.GetType().Assembly.FullName);
+            writer.WriteLine();
+            writer.WriteLine("using pb = global::Google.ProtocolBuffers;");
+            writer.WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;");
+            writer.WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;");
+            writer.WriteLine("using scg = global::System.Collections.Generic;");
+
+            if (Descriptor.CSharpOptions.Namespace != "")
+            {
+                writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.Namespace);
+                writer.Indent();
+                writer.WriteLine();
+            }
+            // Add the namespace around the umbrella class if defined
+            if (!Descriptor.CSharpOptions.NestClasses && Descriptor.CSharpOptions.UmbrellaNamespace != "")
+            {
+                writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.UmbrellaNamespace);
+                writer.Indent();
+                writer.WriteLine();
+            }
+
+            if (Descriptor.CSharpOptions.CodeContracts)
+            {
+                writer.WriteLine("[global::System.Diagnostics.Contracts.ContractVerificationAttribute(false)]");
+            }
+            writer.WriteLine("{0} static partial class {1} {{", ClassAccessLevel,
+                             Descriptor.CSharpOptions.UmbrellaClassname);
+            writer.WriteLine();
+            writer.Indent();
+        }
+
+        private void WriteExtensionRegistration(TextGenerator writer)
+        {
+            writer.WriteLine("#region Extension registration");
+            writer.WriteLine("public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {");
+            writer.Indent();
+            foreach (FieldDescriptor extension in Descriptor.Extensions)
+            {
+                new ExtensionGenerator(extension).GenerateExtensionRegistrationCode(writer);
+            }
+            foreach (MessageDescriptor message in Descriptor.MessageTypes)
+            {
+                new MessageGenerator(message).GenerateExtensionRegistrationCode(writer);
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine("#endregion");
+        }
+
+        private void WriteDescriptor(TextGenerator writer)
+        {
+            writer.WriteLine("#region Descriptor");
+
+            writer.WriteLine("public static pbd::FileDescriptor Descriptor {");
+            writer.WriteLine("  get { return descriptor; }");
+            writer.WriteLine("}");
+            writer.WriteLine("private static pbd::FileDescriptor descriptor;");
+            writer.WriteLine();
+            writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
+            writer.Indent();
+            writer.WriteLine("byte[] descriptorData = global::System.Convert.FromBase64String(");
+            writer.Indent();
+            writer.Indent();
+
+            // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
+            byte[] bytes = Descriptor.Proto.ToByteArray();
+            string base64 = Convert.ToBase64String(bytes);
+
+            while (base64.Length > 60)
+            {
+                writer.WriteLine("\"{0}\" + ", base64.Substring(0, 60));
+                base64 = base64.Substring(60);
+            }
+            writer.WriteLine("\"{0}\");", base64);
+            writer.Outdent();
+            writer.Outdent();
+            writer.WriteLine(
+                "pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {");
+            writer.Indent();
+            writer.WriteLine("descriptor = root;");
+            foreach (MessageDescriptor message in Descriptor.MessageTypes)
+            {
+                new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
+            }
+            foreach (FieldDescriptor extension in Descriptor.Extensions)
+            {
+                new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
+            }
+
+            if (UsesExtensions(Descriptor.Proto))
+            {
+                // Must construct an ExtensionRegistry containing all possible extensions
+                // and return it.
+                writer.WriteLine("pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();");
+                writer.WriteLine("RegisterAllExtensions(registry);");
+                foreach (FileDescriptor dependency in Descriptor.Dependencies)
+                {
+                    writer.WriteLine("{0}.RegisterAllExtensions(registry);",
+                                     DescriptorUtil.GetFullUmbrellaClassName(dependency));
+                }
+                writer.WriteLine("return registry;");
+            }
+            else
+            {
+                writer.WriteLine("return null;");
+            }
+            writer.Outdent();
+            writer.WriteLine("};");
+
+            // -----------------------------------------------------------------
+            // Invoke internalBuildGeneratedFileFrom() to build the file.
+            writer.WriteLine("pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,");
+            writer.WriteLine("    new pbd::FileDescriptor[] {");
+            foreach (FileDescriptor dependency in Descriptor.Dependencies)
+            {
+                writer.WriteLine("    {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency));
+            }
+            writer.WriteLine("    }, assigner);");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine("#endregion");
+            writer.WriteLine();
+        }
+
+        private void WriteLiteExtensions(TextGenerator writer)
+        {
+            writer.WriteLine("#region Extensions");
+            writer.WriteLine("internal static readonly object Descriptor;");
+            writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
+            writer.Indent();
+            writer.WriteLine("Descriptor = null;");
+
+            foreach (MessageDescriptor message in Descriptor.MessageTypes)
+            {
+                new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
+            }
+            foreach (FieldDescriptor extension in Descriptor.Extensions)
+            {
+                new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
+            }
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine("#endregion");
+            writer.WriteLine();
+        }
+    }
+}

+ 5 - 3
src/ProtoGen/app.config

@@ -1,3 +1,5 @@
-<?xml version="1.0"?>
-<configuration>
-	<startup/></configuration>
+<?xml version="1.0"?>
+
+<configuration>
+  <startup />
+</configuration>

+ 304 - 260
src/ProtoMunge/Program.cs

@@ -1,261 +1,305 @@
-#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.IO;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoMunge
-{
-  /// <summary>
-  /// Utility console application which takes a message descriptor and a corresponding message,
-  /// and produces a new message with similar but random data. The data is the same length
-  /// as the original, but with random values within appropriate bands. (For instance, a compressed
-  /// integer in the range 0-127 will end up as another integer in the same range, to keep the length
-  /// the same.)
-  /// TODO(jonskeet): Potentially refactor to use an instance instead, making it simpler to
-  /// be thread-safe for external use.
-  /// </summary>
-  public sealed class Program {
-
-    static readonly Random rng = new Random();
-
-    static int Main(string[] args) {
-      if (args.Length != 3) {
-        Console.Error.WriteLine("Usage: ProtoMunge <descriptor type name> <input data> <output file>");
-        Console.Error.WriteLine("The descriptor type name is the fully-qualified message name, including assembly.");
-        Console.Error.WriteLine("(At a future date it may be possible to do this without building the .NET assembly at all.)");
-        return 1;
-      }
-      IMessage defaultMessage;
-      try {
-        defaultMessage = MessageUtil.GetDefaultMessage(args[0]);
-      } catch (ArgumentException e) {
-        Console.Error.WriteLine(e.Message);
-        return 1;
-      }
-      try {
-        IBuilder builder = defaultMessage.WeakCreateBuilderForType();
-        byte[] inputData = File.ReadAllBytes(args[1]);
-        builder.WeakMergeFrom(ByteString.CopyFrom(inputData));
-        IMessage original = builder.WeakBuild();
-        IMessage munged = Munge(original);
-        if (original.SerializedSize != munged.SerializedSize) {
-          throw new Exception("Serialized sizes don't match");
-        }
-        File.WriteAllBytes(args[2], munged.ToByteArray());
-        return 0;
-      } catch (Exception e) {
-        Console.Error.WriteLine("Error: {0}", e.Message);
-        Console.Error.WriteLine();
-        Console.Error.WriteLine("Detailed exception information: {0}", e);
-        return 1;
-      }
-    }
-
-    /// <summary>
-    /// Munges a message recursively.
-    /// </summary>
-    /// <returns>A new message of the same type as the original message,
-    /// but munged so that all the data is desensitised.</returns>
-    private static IMessage Munge(IMessage message) {
-      IBuilder builder = message.WeakCreateBuilderForType();
-      foreach (var pair in message.AllFields) {
-        if (pair.Key.IsRepeated) {
-          foreach (object singleValue in (IEnumerable)pair.Value) {
-            builder.WeakAddRepeatedField(pair.Key, CheckedMungeValue(pair.Key, singleValue));
-          }
-        } else {
-          builder[pair.Key] = CheckedMungeValue(pair.Key, pair.Value);
-        }
-      }
-      IMessage munged = builder.WeakBuild();
-      if (message.SerializedSize != munged.SerializedSize) {
-        Console.WriteLine("Sub message sizes: {0}/{1}", message.SerializedSize, munged.SerializedSize);
-      }
-      return munged;
-    }
-
-    /// <summary>
-    /// Munges a single value and checks that the length ends up the same as it was before.
-    /// </summary>
-    private static object CheckedMungeValue(FieldDescriptor fieldDescriptor, object value) {
-      int currentSize = CodedOutputStream.ComputeFieldSize(fieldDescriptor.FieldType, fieldDescriptor.FieldNumber, value);
-      object mungedValue = MungeValue(fieldDescriptor, value);
-      int mungedSize = CodedOutputStream.ComputeFieldSize(fieldDescriptor.FieldType, fieldDescriptor.FieldNumber, mungedValue);
-      // Exceptions log more easily than assertions
-      if (currentSize != mungedSize) {
-        throw new Exception("Munged value had wrong size. Field type: " + fieldDescriptor.FieldType
-            + "; old value: " + value + "; new value: " + mungedValue);
-      }
-      return mungedValue;
-    }
-
-    /// <summary>
-    /// Munges a single value of the specified field descriptor. (i.e. if the field is
-    /// actually a repeated int, this method receives a single int value to munge, and
-    /// is called multiple times).
-    /// </summary>
-    private static object MungeValue(FieldDescriptor fieldDescriptor, object value) {
-      switch (fieldDescriptor.FieldType) {
-        case FieldType.SInt64:
-        case FieldType.Int64:
-          return (long) MungeVarint64((ulong) (long)value);
-        case FieldType.UInt64:
-          return MungeVarint64((ulong)value);
-        case FieldType.SInt32:
-          return (int)MungeVarint32((uint)(int)value);
-        case FieldType.Int32:
-          return MungeInt32((int) value);
-        case FieldType.UInt32:
-          return MungeVarint32((uint)value);
-        case FieldType.Double:
-          return rng.NextDouble();
-        case FieldType.Float:
-          return (float)rng.NextDouble();
-        case FieldType.Fixed64: {
-          byte[] data = new byte[8];
-          rng.NextBytes(data);
-          return BitConverter.ToUInt64(data, 0);
-        }
-        case FieldType.Fixed32:  {
-          byte[] data = new byte[4];
-          rng.NextBytes(data);
-          return BitConverter.ToUInt32(data, 0);
-        }
-        case FieldType.Bool:
-          return rng.Next(2) == 1;
-        case FieldType.String:
-          return MungeString((string)value);
-        case FieldType.Group:
-        case FieldType.Message:
-          return Munge((IMessage)value);
-        case FieldType.Bytes:
-          return MungeByteString((ByteString)value);
-        case FieldType.SFixed64: {
-            byte[] data = new byte[8];
-            rng.NextBytes(data);
-            return BitConverter.ToInt64(data, 0);
-          }
-        case FieldType.SFixed32: {
-            byte[] data = new byte[4];
-            rng.NextBytes(data);
-            return BitConverter.ToInt32(data, 0);
-          }
-        case FieldType.Enum:
-          return MungeEnum(fieldDescriptor, (EnumValueDescriptor) value);
-        default:
-          // TODO(jonskeet): Different exception?
-          throw new ArgumentException("Invalid field descriptor");
-      }
-    }
-
-    private static object MungeString(string original) {
-      foreach (char c in original) {
-        if (c > 127) {
-          throw new ArgumentException("Can't handle non-ascii yet");
-        }
-      }
-      char[] chars = new char[original.Length];
-      // Convert to pure ASCII - no control characters.
-      for (int i = 0; i < chars.Length; i++) {
-        chars[i] = (char) rng.Next(32, 127);
-      }
-      return new string(chars);
-    }
-
-    /// <summary>
-    /// Int32 fields are slightly strange - we need to keep the sign the same way it is:
-    /// negative numbers can munge to any other negative number (it'll always take
-    /// 10 bytes) but positive numbers have to stay positive, so we can't use the
-    /// full range of 32 bits.
-    /// </summary>
-    private static int MungeInt32(int value) {
-      if (value < 0) {
-        return rng.Next(int.MinValue, 0);
-      }
-      int length = CodedOutputStream.ComputeRawVarint32Size((uint) value);
-      uint min = length == 1 ? 0 : 1U << ((length - 1) * 7);
-      uint max = length == 5 ? int.MaxValue : (1U << (length * 7)) - 1;
-      return (int) NextRandomUInt64(min, max);
-    }
-
-    private static uint MungeVarint32(uint original) {
-      int length = CodedOutputStream.ComputeRawVarint32Size(original);
-      uint min = length == 1 ? 0 : 1U << ((length - 1) * 7);
-      uint max = length == 5 ? uint.MaxValue : (1U << (length * 7)) - 1;
-      return (uint)NextRandomUInt64(min, max);
-    }
-
-    private static ulong MungeVarint64(ulong original) {
-      int length = CodedOutputStream.ComputeRawVarint64Size(original);
-      ulong min = length == 1 ? 0 : 1UL << ((length - 1) * 7);
-      ulong max = length == 10 ? ulong.MaxValue : (1UL<< (length * 7)) - 1;
-      return NextRandomUInt64(min, max);
-    }
-
-    /// <summary>
-    /// Returns a random number in the range [min, max] (both inclusive).
-    /// </summary>    
-    private static ulong NextRandomUInt64(ulong min, ulong max) {
-      if (min > max) {
-        throw new ArgumentException("min must be <= max; min=" + min + "; max = " + max);
-      }
-      ulong range = max - min;
-      // This isn't actually terribly good at very large ranges - but it doesn't really matter for the sake
-      // of this program.
-      return min + (ulong)(range * rng.NextDouble());
-    }
-
-    private static object MungeEnum(FieldDescriptor fieldDescriptor, EnumValueDescriptor original) {
-      // Find all the values which get encoded to the same size as the current value, and pick one at random
-      int originalSize = CodedOutputStream.ComputeRawVarint32Size((uint)original.Number);
-      List<EnumValueDescriptor> sameSizeValues = new List<EnumValueDescriptor> ();
-      foreach (EnumValueDescriptor candidate in fieldDescriptor.EnumType.Values) {
-        if (CodedOutputStream.ComputeRawVarint32Size((uint)candidate.Number) == originalSize) {
-          sameSizeValues.Add(candidate);
-        }
-      }
-      return sameSizeValues[rng.Next(sameSizeValues.Count)];
-    }
-
-    private static object MungeByteString(ByteString byteString) {
-      byte[] data = new byte[byteString.Length];
-      rng.NextBytes(data);
-      return ByteString.CopyFrom(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.Collections;
+using System.Collections.Generic;
+using System.IO;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoMunge
+{
+    /// <summary>
+    /// Utility console application which takes a message descriptor and a corresponding message,
+    /// and produces a new message with similar but random data. The data is the same length
+    /// as the original, but with random values within appropriate bands. (For instance, a compressed
+    /// integer in the range 0-127 will end up as another integer in the same range, to keep the length
+    /// the same.)
+    /// TODO(jonskeet): Potentially refactor to use an instance instead, making it simpler to
+    /// be thread-safe for external use.
+    /// </summary>
+    public sealed class Program
+    {
+        private static readonly Random rng = new Random();
+
+        private static int Main(string[] args)
+        {
+            if (args.Length != 3)
+            {
+                Console.Error.WriteLine("Usage: ProtoMunge <descriptor type name> <input data> <output file>");
+                Console.Error.WriteLine(
+                    "The descriptor type name is the fully-qualified message name, including assembly.");
+                Console.Error.WriteLine(
+                    "(At a future date it may be possible to do this without building the .NET assembly at all.)");
+                return 1;
+            }
+            IMessage defaultMessage;
+            try
+            {
+                defaultMessage = MessageUtil.GetDefaultMessage(args[0]);
+            }
+            catch (ArgumentException e)
+            {
+                Console.Error.WriteLine(e.Message);
+                return 1;
+            }
+            try
+            {
+                IBuilder builder = defaultMessage.WeakCreateBuilderForType();
+                byte[] inputData = File.ReadAllBytes(args[1]);
+                builder.WeakMergeFrom(ByteString.CopyFrom(inputData));
+                IMessage original = builder.WeakBuild();
+                IMessage munged = Munge(original);
+                if (original.SerializedSize != munged.SerializedSize)
+                {
+                    throw new Exception("Serialized sizes don't match");
+                }
+                File.WriteAllBytes(args[2], munged.ToByteArray());
+                return 0;
+            }
+            catch (Exception e)
+            {
+                Console.Error.WriteLine("Error: {0}", e.Message);
+                Console.Error.WriteLine();
+                Console.Error.WriteLine("Detailed exception information: {0}", e);
+                return 1;
+            }
+        }
+
+        /// <summary>
+        /// Munges a message recursively.
+        /// </summary>
+        /// <returns>A new message of the same type as the original message,
+        /// but munged so that all the data is desensitised.</returns>
+        private static IMessage Munge(IMessage message)
+        {
+            IBuilder builder = message.WeakCreateBuilderForType();
+            foreach (var pair in message.AllFields)
+            {
+                if (pair.Key.IsRepeated)
+                {
+                    foreach (object singleValue in (IEnumerable) pair.Value)
+                    {
+                        builder.WeakAddRepeatedField(pair.Key, CheckedMungeValue(pair.Key, singleValue));
+                    }
+                }
+                else
+                {
+                    builder[pair.Key] = CheckedMungeValue(pair.Key, pair.Value);
+                }
+            }
+            IMessage munged = builder.WeakBuild();
+            if (message.SerializedSize != munged.SerializedSize)
+            {
+                Console.WriteLine("Sub message sizes: {0}/{1}", message.SerializedSize, munged.SerializedSize);
+            }
+            return munged;
+        }
+
+        /// <summary>
+        /// Munges a single value and checks that the length ends up the same as it was before.
+        /// </summary>
+        private static object CheckedMungeValue(FieldDescriptor fieldDescriptor, object value)
+        {
+            int currentSize = CodedOutputStream.ComputeFieldSize(fieldDescriptor.FieldType, fieldDescriptor.FieldNumber,
+                                                                 value);
+            object mungedValue = MungeValue(fieldDescriptor, value);
+            int mungedSize = CodedOutputStream.ComputeFieldSize(fieldDescriptor.FieldType, fieldDescriptor.FieldNumber,
+                                                                mungedValue);
+            // Exceptions log more easily than assertions
+            if (currentSize != mungedSize)
+            {
+                throw new Exception("Munged value had wrong size. Field type: " + fieldDescriptor.FieldType
+                                    + "; old value: " + value + "; new value: " + mungedValue);
+            }
+            return mungedValue;
+        }
+
+        /// <summary>
+        /// Munges a single value of the specified field descriptor. (i.e. if the field is
+        /// actually a repeated int, this method receives a single int value to munge, and
+        /// is called multiple times).
+        /// </summary>
+        private static object MungeValue(FieldDescriptor fieldDescriptor, object value)
+        {
+            switch (fieldDescriptor.FieldType)
+            {
+                case FieldType.SInt64:
+                case FieldType.Int64:
+                    return (long) MungeVarint64((ulong) (long) value);
+                case FieldType.UInt64:
+                    return MungeVarint64((ulong) value);
+                case FieldType.SInt32:
+                    return (int) MungeVarint32((uint) (int) value);
+                case FieldType.Int32:
+                    return MungeInt32((int) value);
+                case FieldType.UInt32:
+                    return MungeVarint32((uint) value);
+                case FieldType.Double:
+                    return rng.NextDouble();
+                case FieldType.Float:
+                    return (float) rng.NextDouble();
+                case FieldType.Fixed64:
+                    {
+                        byte[] data = new byte[8];
+                        rng.NextBytes(data);
+                        return BitConverter.ToUInt64(data, 0);
+                    }
+                case FieldType.Fixed32:
+                    {
+                        byte[] data = new byte[4];
+                        rng.NextBytes(data);
+                        return BitConverter.ToUInt32(data, 0);
+                    }
+                case FieldType.Bool:
+                    return rng.Next(2) == 1;
+                case FieldType.String:
+                    return MungeString((string) value);
+                case FieldType.Group:
+                case FieldType.Message:
+                    return Munge((IMessage) value);
+                case FieldType.Bytes:
+                    return MungeByteString((ByteString) value);
+                case FieldType.SFixed64:
+                    {
+                        byte[] data = new byte[8];
+                        rng.NextBytes(data);
+                        return BitConverter.ToInt64(data, 0);
+                    }
+                case FieldType.SFixed32:
+                    {
+                        byte[] data = new byte[4];
+                        rng.NextBytes(data);
+                        return BitConverter.ToInt32(data, 0);
+                    }
+                case FieldType.Enum:
+                    return MungeEnum(fieldDescriptor, (EnumValueDescriptor) value);
+                default:
+                    // TODO(jonskeet): Different exception?
+                    throw new ArgumentException("Invalid field descriptor");
+            }
+        }
+
+        private static object MungeString(string original)
+        {
+            foreach (char c in original)
+            {
+                if (c > 127)
+                {
+                    throw new ArgumentException("Can't handle non-ascii yet");
+                }
+            }
+            char[] chars = new char[original.Length];
+            // Convert to pure ASCII - no control characters.
+            for (int i = 0; i < chars.Length; i++)
+            {
+                chars[i] = (char) rng.Next(32, 127);
+            }
+            return new string(chars);
+        }
+
+        /// <summary>
+        /// Int32 fields are slightly strange - we need to keep the sign the same way it is:
+        /// negative numbers can munge to any other negative number (it'll always take
+        /// 10 bytes) but positive numbers have to stay positive, so we can't use the
+        /// full range of 32 bits.
+        /// </summary>
+        private static int MungeInt32(int value)
+        {
+            if (value < 0)
+            {
+                return rng.Next(int.MinValue, 0);
+            }
+            int length = CodedOutputStream.ComputeRawVarint32Size((uint) value);
+            uint min = length == 1 ? 0 : 1U << ((length - 1)*7);
+            uint max = length == 5 ? int.MaxValue : (1U << (length*7)) - 1;
+            return (int) NextRandomUInt64(min, max);
+        }
+
+        private static uint MungeVarint32(uint original)
+        {
+            int length = CodedOutputStream.ComputeRawVarint32Size(original);
+            uint min = length == 1 ? 0 : 1U << ((length - 1)*7);
+            uint max = length == 5 ? uint.MaxValue : (1U << (length*7)) - 1;
+            return (uint) NextRandomUInt64(min, max);
+        }
+
+        private static ulong MungeVarint64(ulong original)
+        {
+            int length = CodedOutputStream.ComputeRawVarint64Size(original);
+            ulong min = length == 1 ? 0 : 1UL << ((length - 1)*7);
+            ulong max = length == 10 ? ulong.MaxValue : (1UL << (length*7)) - 1;
+            return NextRandomUInt64(min, max);
+        }
+
+        /// <summary>
+        /// Returns a random number in the range [min, max] (both inclusive).
+        /// </summary>    
+        private static ulong NextRandomUInt64(ulong min, ulong max)
+        {
+            if (min > max)
+            {
+                throw new ArgumentException("min must be <= max; min=" + min + "; max = " + max);
+            }
+            ulong range = max - min;
+            // This isn't actually terribly good at very large ranges - but it doesn't really matter for the sake
+            // of this program.
+            return min + (ulong) (range*rng.NextDouble());
+        }
+
+        private static object MungeEnum(FieldDescriptor fieldDescriptor, EnumValueDescriptor original)
+        {
+            // Find all the values which get encoded to the same size as the current value, and pick one at random
+            int originalSize = CodedOutputStream.ComputeRawVarint32Size((uint) original.Number);
+            List<EnumValueDescriptor> sameSizeValues = new List<EnumValueDescriptor>();
+            foreach (EnumValueDescriptor candidate in fieldDescriptor.EnumType.Values)
+            {
+                if (CodedOutputStream.ComputeRawVarint32Size((uint) candidate.Number) == originalSize)
+                {
+                    sameSizeValues.Add(candidate);
+                }
+            }
+            return sameSizeValues[rng.Next(sameSizeValues.Count)];
+        }
+
+        private static object MungeByteString(ByteString byteString)
+        {
+            byte[] data = new byte[byteString.Length];
+            rng.NextBytes(data);
+            return ByteString.CopyFrom(data);
+        }
+    }
 }

+ 40 - 36
src/ProtoMunge/Properties/AssemblyInfo.cs

@@ -1,36 +1,40 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ProtoMunge")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ProtoMunge")]
-[assembly: AssemblyCopyright("Copyright ©  2008")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("4d26ed0e-a6ca-4df9-bb87-59429d49b676")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyFileVersion("2.3.0.277")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("ProtoMunge")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ProtoMunge")]
+[assembly: AssemblyCopyright("Copyright ©  2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("4d26ed0e-a6ca-4df9-bb87-59429d49b676")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("2.3.0.277")]
+
+[assembly: AssemblyVersion("2.3.0.277")]
+[assembly: AssemblyFileVersion("2.3.0.277")]

+ 5 - 3
src/ProtoMunge/app.config

@@ -1,3 +1,5 @@
-<?xml version="1.0"?>
-<configuration>
-	<startup/></configuration>
+<?xml version="1.0"?>
+
+<configuration>
+  <startup />
+</configuration>

+ 476 - 419
src/ProtocolBuffers.Test/AbstractMessageTest.cs

@@ -1,419 +1,476 @@
-#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.Descriptors;
-using NUnit.Framework;
-using Google.ProtocolBuffers.TestProtos;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class AbstractMessageTest {
-
-    [Test]
-    public void Clear() {
-      AbstractMessageWrapper message = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(TestUtil.GetAllSet())).Clear().Build();
-      TestUtil.AssertClear((TestAllTypes) message.WrappedMessage);
-    }
-
-    [Test]
-    public void Copy() {
-      AbstractMessageWrapper message = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder()).MergeFrom(TestUtil.GetAllSet()).Build();
-      TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
-    }
-
-    [Test]
-    public void SerializedSize() {
-      TestAllTypes message = TestUtil.GetAllSet();
-      IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());
-
-      Assert.AreEqual(message.SerializedSize, abstractMessage.SerializedSize);
-    }
-
-    [Test]
-    public void Serialization() {
-      IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());
-      TestUtil.AssertAllFieldsSet(TestAllTypes.ParseFrom(abstractMessage.ToByteString()));
-      Assert.AreEqual(TestUtil.GetAllSet().ToByteString(), abstractMessage.ToByteString());
-    }
-
-    [Test]
-    public void Parsing() {
-      IBuilder builder = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder());
-      AbstractMessageWrapper message = (AbstractMessageWrapper) builder.WeakMergeFrom(TestUtil.GetAllSet().ToByteString()).WeakBuild();
-      TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
-    }
-
-    [Test]
-    public void PackedSerialization() {
-      IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetPackedSet());
-      TestUtil.AssertPackedFieldsSet(TestPackedTypes.ParseFrom(abstractMessage.ToByteString()));
-      Assert.AreEqual(TestUtil.GetPackedSet().ToByteString(), abstractMessage.ToByteString());
-    }
-
-    [Test]
-    public void PackedParsing() {
-      AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestPackedTypes.CreateBuilder());
-      AbstractMessageWrapper message = builder.MergeFrom(TestUtil.GetPackedSet().ToByteString()).Build();
-      TestUtil.AssertPackedFieldsSet((TestPackedTypes)message.WrappedMessage);
-    }
-
-    [Test]
-    public void OptimizedForSize() {
-      // We're mostly only Checking that this class was compiled successfully.
-      TestOptimizedForSize message = TestOptimizedForSize.CreateBuilder().SetI(1).Build();
-      message = TestOptimizedForSize.ParseFrom(message.ToByteString());
-      Assert.AreEqual(2, message.SerializedSize);
-    }
-
-    // -----------------------------------------------------------------
-    // Tests for isInitialized().
-
-    private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;
-    private static readonly TestRequired TestRequiredInitialized = TestRequired.CreateBuilder().SetA(1).SetB(2).SetC(3).Build();
-
-    [Test]
-    public void IsInitialized() {
-      TestRequired.Builder builder = TestRequired.CreateBuilder();
-      AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);
-
-      Assert.IsFalse(abstractBuilder.IsInitialized);
-      builder.A = 1;
-      Assert.IsFalse(abstractBuilder.IsInitialized);
-      builder.B = 1;
-      Assert.IsFalse(abstractBuilder.IsInitialized);
-      builder.C = 1;
-      Assert.IsTrue(abstractBuilder.IsInitialized);
-    }
-
-    [Test]
-    public void ForeignIsInitialized() {
-      TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
-      AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);
-
-      Assert.IsTrue(abstractBuilder.IsInitialized);
-
-      builder.SetOptionalMessage(TestRequiredUninitialized);
-      Assert.IsFalse(abstractBuilder.IsInitialized);
-
-      builder.SetOptionalMessage(TestRequiredInitialized);
-      Assert.IsTrue(abstractBuilder.IsInitialized);
-
-      builder.AddRepeatedMessage(TestRequiredUninitialized);
-      Assert.IsFalse(abstractBuilder.IsInitialized);
-
-      builder.SetRepeatedMessage(0, TestRequiredInitialized);
-      Assert.IsTrue(abstractBuilder.IsInitialized);
-    }
-
-    // -----------------------------------------------------------------
-    // Tests for mergeFrom
-
-    static readonly TestAllTypes MergeSource = TestAllTypes.CreateBuilder()
-        .SetOptionalInt32(1)
-        .SetOptionalString("foo")
-        .SetOptionalForeignMessage(ForeignMessage.DefaultInstance)
-        .AddRepeatedString("bar")
-        .Build();
-
-    static readonly TestAllTypes MergeDest = TestAllTypes.CreateBuilder()
-        .SetOptionalInt64(2)
-        .SetOptionalString("baz")
-        .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(3).Build())
-        .AddRepeatedString("qux")
-        .Build();
-
-    const string MergeResultText = "optional_int32: 1\n" +
-        "optional_int64: 2\n" +
-        "optional_string: \"foo\"\n" +
-        "optional_foreign_message {\n" +
-        "  c: 3\n" +
-        "}\n" +
-        "repeated_string: \"qux\"\n" +
-        "repeated_string: \"bar\"\n";
-
-    [Test]
-    public void MergeFrom() {
-      AbstractMessageWrapper result = (AbstractMessageWrapper) 
-        new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(MergeDest))
-            .MergeFrom(MergeSource)
-            .Build();
-
-      Assert.AreEqual(MergeResultText, result.ToString());
-    }
-
-    // -----------------------------------------------------------------
-    // Tests for equals and hashCode
-    
-    [Test]
-    public void EqualsAndHashCode() {
-      TestAllTypes a = TestUtil.GetAllSet();
-      TestAllTypes b = TestAllTypes.CreateBuilder().Build();
-      TestAllTypes c = TestAllTypes.CreateBuilder(b).AddRepeatedString("x").Build();
-      TestAllTypes d = TestAllTypes.CreateBuilder(c).AddRepeatedString("y").Build();
-      TestAllExtensions e = TestUtil.GetAllExtensionsSet();
-      TestAllExtensions f = TestAllExtensions.CreateBuilder(e)
-          .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 999).Build();
-        
-      CheckEqualsIsConsistent(a);
-      CheckEqualsIsConsistent(b);
-      CheckEqualsIsConsistent(c);
-      CheckEqualsIsConsistent(d);
-      CheckEqualsIsConsistent(e);
-      CheckEqualsIsConsistent(f);
-      
-      CheckNotEqual(a, b);
-      CheckNotEqual(a, c);
-      CheckNotEqual(a, d);
-      CheckNotEqual(a, e);
-      CheckNotEqual(a, f);
-
-      CheckNotEqual(b, c);
-      CheckNotEqual(b, d);
-      CheckNotEqual(b, e);
-      CheckNotEqual(b, f);
-
-      CheckNotEqual(c, d);
-      CheckNotEqual(c, e);
-      CheckNotEqual(c, f);
-
-      CheckNotEqual(d, e);
-      CheckNotEqual(d, f);
-
-      CheckNotEqual(e, f);
-
-      // Deserializing into the TestEmptyMessage such that every field is an UnknownFieldSet.Field
-      TestEmptyMessage eUnknownFields = TestEmptyMessage.ParseFrom(e.ToByteArray());
-      TestEmptyMessage fUnknownFields = TestEmptyMessage.ParseFrom(f.ToByteArray());
-      CheckNotEqual(eUnknownFields, fUnknownFields);
-      CheckEqualsIsConsistent(eUnknownFields);
-      CheckEqualsIsConsistent(fUnknownFields);
-
-      // Subseqent reconstitutions should be identical
-      TestEmptyMessage eUnknownFields2 = TestEmptyMessage.ParseFrom(e.ToByteArray());
-      CheckEqualsIsConsistent(eUnknownFields, eUnknownFields2);
-    }
-    
-    /// <summary>
-    /// Asserts that the given protos are equal and have the same hash code.
-    /// </summary>
-    private static void CheckEqualsIsConsistent(IMessage message) {
-      // Object should be equal to itself.
-      Assert.AreEqual(message, message);
-      
-      // Object should be equal to a dynamic copy of itself.
-      DynamicMessage dynamic = DynamicMessage.CreateBuilder(message).Build();
-      CheckEqualsIsConsistent(message, dynamic);
-    }
-
-    /// <summary>
-    /// Asserts that the given protos are equal and have the same hash code.
-    /// </summary>
-    private static void CheckEqualsIsConsistent(IMessage message1, IMessage message2) {
-      Assert.AreEqual(message1, message2);
-      Assert.AreEqual(message2, message1);
-      Assert.AreEqual(message2.GetHashCode(), message1.GetHashCode());
-    }
-
-    /// <summary>
-    /// Asserts that the given protos are not equal and have different hash codes.
-    /// </summary>
-    /// <remarks>
-    /// It's valid for non-equal objects to have the same hash code, so
-    /// this test is stricter than it needs to be. However, this should happen
-    /// relatively rarely. (If this test fails, it's probably still due to a bug.)
-    /// </remarks>
-    private static void CheckNotEqual(IMessage m1, IMessage m2) {
-      String equalsError = string.Format("{0} should not be equal to {1}", m1, m2);
-      Assert.IsFalse(m1.Equals(m2), equalsError);
-      Assert.IsFalse(m2.Equals(m1), equalsError);
-
-      Assert.IsFalse(m1.GetHashCode() == m2.GetHashCode(),
-        string.Format("{0} should have a different hash code from {1}", m1, m2));
-    }
-
-    /// <summary>
-    /// Extends AbstractMessage and wraps some other message object.  The methods
-    /// of the Message interface which aren't explicitly implemented by
-    /// AbstractMessage are forwarded to the wrapped object.  This allows us to
-    /// test that AbstractMessage's implementations work even if the wrapped
-    /// object does not use them.
-    /// </summary>
-    private class AbstractMessageWrapper : AbstractMessage<AbstractMessageWrapper, AbstractMessageWrapper.Builder> {
-      private readonly IMessage wrappedMessage;
-
-      public IMessage WrappedMessage {
-        get { return wrappedMessage; }
-      }
-
-      public AbstractMessageWrapper(IMessage wrappedMessage) {
-        this.wrappedMessage = wrappedMessage;
-      }
-
-      public override MessageDescriptor DescriptorForType {
-        get { return wrappedMessage.DescriptorForType; }
-      }
-
-      public override AbstractMessageWrapper DefaultInstanceForType {
-        get { return new AbstractMessageWrapper(wrappedMessage.WeakDefaultInstanceForType); }
-      }
-
-      public override IDictionary<FieldDescriptor, object> AllFields {
-        get { return wrappedMessage.AllFields; }
-      }
-
-      public override bool HasField(FieldDescriptor field) {
-        return wrappedMessage.HasField(field);
-      }
-    
-      public override object this[FieldDescriptor field] {
-        get { return wrappedMessage[field]; }
-      }
-
-      public override object this[FieldDescriptor field, int index] {
-        get { return wrappedMessage[field, index]; }
-      }
-
-      public override int GetRepeatedFieldCount(FieldDescriptor field) {
-        return wrappedMessage.GetRepeatedFieldCount(field);
-      }
-      
-      public override UnknownFieldSet UnknownFields {
-        get { return wrappedMessage.UnknownFields; }
-      }
-
-      public override Builder CreateBuilderForType() {
-        return new Builder(wrappedMessage.WeakCreateBuilderForType());
-      }
-
-      public override Builder ToBuilder() {
-        return new Builder(wrappedMessage.WeakToBuilder());
-      }
-      
-      internal class Builder : AbstractBuilder<AbstractMessageWrapper, Builder> {
-        private readonly IBuilder wrappedBuilder;
-
-        protected override Builder ThisBuilder {
-          get { return this; }
-        }
-
-        internal Builder(IBuilder wrappedBuilder) {
-          this.wrappedBuilder = wrappedBuilder;
-        }
-
-        public override Builder MergeFrom(AbstractMessageWrapper other) {
-          wrappedBuilder.WeakMergeFrom(other.wrappedMessage);
-          return this;
-        }
-
-        public override bool IsInitialized {
-          get { return wrappedBuilder.IsInitialized; }
-        }
-
-        public override IDictionary<FieldDescriptor, object> AllFields {
-          get { return wrappedBuilder.AllFields; }
-        }
-
-        public override object this[FieldDescriptor field] {
-          get { return wrappedBuilder[field]; }
-          set { wrappedBuilder[field] = value; }
-        }
-
-        public override MessageDescriptor DescriptorForType {
-          get { return wrappedBuilder.DescriptorForType; }
-        }
-
-        public override int GetRepeatedFieldCount(FieldDescriptor field) {
-          return wrappedBuilder.GetRepeatedFieldCount(field);
-        }
-
-        public override object this[FieldDescriptor field, int index] {
-          get { return wrappedBuilder[field, index]; }
-          set { wrappedBuilder[field, index] = value; }
-        }
-
-        public override bool HasField(FieldDescriptor field) {
-          return wrappedBuilder.HasField(field);
-        }
-
-        public override UnknownFieldSet UnknownFields {
-          get { return wrappedBuilder.UnknownFields; }
-          set { wrappedBuilder.UnknownFields = value; }
-        }
-
-        public override AbstractMessageWrapper Build() {
-          return new AbstractMessageWrapper(wrappedBuilder.WeakBuild());
-        }
-
-        public override AbstractMessageWrapper BuildPartial() {
-          return new AbstractMessageWrapper(wrappedBuilder.WeakBuildPartial());
-        }
-
-        public override Builder Clone() {
-          return new Builder(wrappedBuilder.WeakClone());
-        }
-
-        public override AbstractMessageWrapper DefaultInstanceForType {
-          get { return new AbstractMessageWrapper(wrappedBuilder.WeakDefaultInstanceForType); }
-        }
-
-        public override Builder ClearField(FieldDescriptor field) {
-          wrappedBuilder.WeakClearField(field);
-          return this;
-        }
-
-        public override Builder AddRepeatedField(FieldDescriptor field, object value) {
-          wrappedBuilder.WeakAddRepeatedField(field, value);
-          return this;
-        }
-
-        public override IBuilder CreateBuilderForField(FieldDescriptor field) {
-          wrappedBuilder.CreateBuilderForField(field);
-          return this;
-        }
-
-        public override Builder MergeFrom(IMessage other) {
-          wrappedBuilder.WeakMergeFrom(other);
-          return this;
-        }
-
-        public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
-          wrappedBuilder.WeakMergeFrom(input, extensionRegistry);
-          return this;
-        }
-      }
-    }
-  }
-}
+#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.Descriptors;
+using NUnit.Framework;
+using Google.ProtocolBuffers.TestProtos;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class AbstractMessageTest
+    {
+        [Test]
+        public void Clear()
+        {
+            AbstractMessageWrapper message =
+                new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(TestUtil.GetAllSet())).Clear().Build();
+            TestUtil.AssertClear((TestAllTypes) message.WrappedMessage);
+        }
+
+        [Test]
+        public void Copy()
+        {
+            AbstractMessageWrapper message =
+                new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder()).MergeFrom(TestUtil.GetAllSet()).Build();
+            TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
+        }
+
+        [Test]
+        public void SerializedSize()
+        {
+            TestAllTypes message = TestUtil.GetAllSet();
+            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());
+
+            Assert.AreEqual(message.SerializedSize, abstractMessage.SerializedSize);
+        }
+
+        [Test]
+        public void Serialization()
+        {
+            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());
+            TestUtil.AssertAllFieldsSet(TestAllTypes.ParseFrom(abstractMessage.ToByteString()));
+            Assert.AreEqual(TestUtil.GetAllSet().ToByteString(), abstractMessage.ToByteString());
+        }
+
+        [Test]
+        public void Parsing()
+        {
+            IBuilder builder = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder());
+            AbstractMessageWrapper message =
+                (AbstractMessageWrapper) builder.WeakMergeFrom(TestUtil.GetAllSet().ToByteString()).WeakBuild();
+            TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
+        }
+
+        [Test]
+        public void PackedSerialization()
+        {
+            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetPackedSet());
+            TestUtil.AssertPackedFieldsSet(TestPackedTypes.ParseFrom(abstractMessage.ToByteString()));
+            Assert.AreEqual(TestUtil.GetPackedSet().ToByteString(), abstractMessage.ToByteString());
+        }
+
+        [Test]
+        public void PackedParsing()
+        {
+            AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestPackedTypes.CreateBuilder());
+            AbstractMessageWrapper message = builder.MergeFrom(TestUtil.GetPackedSet().ToByteString()).Build();
+            TestUtil.AssertPackedFieldsSet((TestPackedTypes) message.WrappedMessage);
+        }
+
+        [Test]
+        public void OptimizedForSize()
+        {
+            // We're mostly only Checking that this class was compiled successfully.
+            TestOptimizedForSize message = TestOptimizedForSize.CreateBuilder().SetI(1).Build();
+            message = TestOptimizedForSize.ParseFrom(message.ToByteString());
+            Assert.AreEqual(2, message.SerializedSize);
+        }
+
+        // -----------------------------------------------------------------
+        // Tests for isInitialized().
+
+        private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;
+
+        private static readonly TestRequired TestRequiredInitialized =
+            TestRequired.CreateBuilder().SetA(1).SetB(2).SetC(3).Build();
+
+        [Test]
+        public void IsInitialized()
+        {
+            TestRequired.Builder builder = TestRequired.CreateBuilder();
+            AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);
+
+            Assert.IsFalse(abstractBuilder.IsInitialized);
+            builder.A = 1;
+            Assert.IsFalse(abstractBuilder.IsInitialized);
+            builder.B = 1;
+            Assert.IsFalse(abstractBuilder.IsInitialized);
+            builder.C = 1;
+            Assert.IsTrue(abstractBuilder.IsInitialized);
+        }
+
+        [Test]
+        public void ForeignIsInitialized()
+        {
+            TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
+            AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);
+
+            Assert.IsTrue(abstractBuilder.IsInitialized);
+
+            builder.SetOptionalMessage(TestRequiredUninitialized);
+            Assert.IsFalse(abstractBuilder.IsInitialized);
+
+            builder.SetOptionalMessage(TestRequiredInitialized);
+            Assert.IsTrue(abstractBuilder.IsInitialized);
+
+            builder.AddRepeatedMessage(TestRequiredUninitialized);
+            Assert.IsFalse(abstractBuilder.IsInitialized);
+
+            builder.SetRepeatedMessage(0, TestRequiredInitialized);
+            Assert.IsTrue(abstractBuilder.IsInitialized);
+        }
+
+        // -----------------------------------------------------------------
+        // Tests for mergeFrom
+
+        private static readonly TestAllTypes MergeSource = TestAllTypes.CreateBuilder()
+            .SetOptionalInt32(1)
+            .SetOptionalString("foo")
+            .SetOptionalForeignMessage(ForeignMessage.DefaultInstance)
+            .AddRepeatedString("bar")
+            .Build();
+
+        private static readonly TestAllTypes MergeDest = TestAllTypes.CreateBuilder()
+            .SetOptionalInt64(2)
+            .SetOptionalString("baz")
+            .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(3).Build())
+            .AddRepeatedString("qux")
+            .Build();
+
+        private const string MergeResultText = "optional_int32: 1\n" +
+                                               "optional_int64: 2\n" +
+                                               "optional_string: \"foo\"\n" +
+                                               "optional_foreign_message {\n" +
+                                               "  c: 3\n" +
+                                               "}\n" +
+                                               "repeated_string: \"qux\"\n" +
+                                               "repeated_string: \"bar\"\n";
+
+        [Test]
+        public void MergeFrom()
+        {
+            AbstractMessageWrapper result = (AbstractMessageWrapper)
+                                            new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(MergeDest))
+                                                .MergeFrom(MergeSource)
+                                                .Build();
+
+            Assert.AreEqual(MergeResultText, result.ToString());
+        }
+
+        // -----------------------------------------------------------------
+        // Tests for equals and hashCode
+
+        [Test]
+        public void EqualsAndHashCode()
+        {
+            TestAllTypes a = TestUtil.GetAllSet();
+            TestAllTypes b = TestAllTypes.CreateBuilder().Build();
+            TestAllTypes c = TestAllTypes.CreateBuilder(b).AddRepeatedString("x").Build();
+            TestAllTypes d = TestAllTypes.CreateBuilder(c).AddRepeatedString("y").Build();
+            TestAllExtensions e = TestUtil.GetAllExtensionsSet();
+            TestAllExtensions f = TestAllExtensions.CreateBuilder(e)
+                .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 999).Build();
+
+            CheckEqualsIsConsistent(a);
+            CheckEqualsIsConsistent(b);
+            CheckEqualsIsConsistent(c);
+            CheckEqualsIsConsistent(d);
+            CheckEqualsIsConsistent(e);
+            CheckEqualsIsConsistent(f);
+
+            CheckNotEqual(a, b);
+            CheckNotEqual(a, c);
+            CheckNotEqual(a, d);
+            CheckNotEqual(a, e);
+            CheckNotEqual(a, f);
+
+            CheckNotEqual(b, c);
+            CheckNotEqual(b, d);
+            CheckNotEqual(b, e);
+            CheckNotEqual(b, f);
+
+            CheckNotEqual(c, d);
+            CheckNotEqual(c, e);
+            CheckNotEqual(c, f);
+
+            CheckNotEqual(d, e);
+            CheckNotEqual(d, f);
+
+            CheckNotEqual(e, f);
+
+            // Deserializing into the TestEmptyMessage such that every field is an UnknownFieldSet.Field
+            TestEmptyMessage eUnknownFields = TestEmptyMessage.ParseFrom(e.ToByteArray());
+            TestEmptyMessage fUnknownFields = TestEmptyMessage.ParseFrom(f.ToByteArray());
+            CheckNotEqual(eUnknownFields, fUnknownFields);
+            CheckEqualsIsConsistent(eUnknownFields);
+            CheckEqualsIsConsistent(fUnknownFields);
+
+            // Subseqent reconstitutions should be identical
+            TestEmptyMessage eUnknownFields2 = TestEmptyMessage.ParseFrom(e.ToByteArray());
+            CheckEqualsIsConsistent(eUnknownFields, eUnknownFields2);
+        }
+
+        /// <summary>
+        /// Asserts that the given protos are equal and have the same hash code.
+        /// </summary>
+        private static void CheckEqualsIsConsistent(IMessage message)
+        {
+            // Object should be equal to itself.
+            Assert.AreEqual(message, message);
+
+            // Object should be equal to a dynamic copy of itself.
+            DynamicMessage dynamic = DynamicMessage.CreateBuilder(message).Build();
+            CheckEqualsIsConsistent(message, dynamic);
+        }
+
+        /// <summary>
+        /// Asserts that the given protos are equal and have the same hash code.
+        /// </summary>
+        private static void CheckEqualsIsConsistent(IMessage message1, IMessage message2)
+        {
+            Assert.AreEqual(message1, message2);
+            Assert.AreEqual(message2, message1);
+            Assert.AreEqual(message2.GetHashCode(), message1.GetHashCode());
+        }
+
+        /// <summary>
+        /// Asserts that the given protos are not equal and have different hash codes.
+        /// </summary>
+        /// <remarks>
+        /// It's valid for non-equal objects to have the same hash code, so
+        /// this test is stricter than it needs to be. However, this should happen
+        /// relatively rarely. (If this test fails, it's probably still due to a bug.)
+        /// </remarks>
+        private static void CheckNotEqual(IMessage m1, IMessage m2)
+        {
+            String equalsError = string.Format("{0} should not be equal to {1}", m1, m2);
+            Assert.IsFalse(m1.Equals(m2), equalsError);
+            Assert.IsFalse(m2.Equals(m1), equalsError);
+
+            Assert.IsFalse(m1.GetHashCode() == m2.GetHashCode(),
+                           string.Format("{0} should have a different hash code from {1}", m1, m2));
+        }
+
+        /// <summary>
+        /// Extends AbstractMessage and wraps some other message object.  The methods
+        /// of the Message interface which aren't explicitly implemented by
+        /// AbstractMessage are forwarded to the wrapped object.  This allows us to
+        /// test that AbstractMessage's implementations work even if the wrapped
+        /// object does not use them.
+        /// </summary>
+        private class AbstractMessageWrapper : AbstractMessage<AbstractMessageWrapper, AbstractMessageWrapper.Builder>
+        {
+            private readonly IMessage wrappedMessage;
+
+            public IMessage WrappedMessage
+            {
+                get { return wrappedMessage; }
+            }
+
+            public AbstractMessageWrapper(IMessage wrappedMessage)
+            {
+                this.wrappedMessage = wrappedMessage;
+            }
+
+            public override MessageDescriptor DescriptorForType
+            {
+                get { return wrappedMessage.DescriptorForType; }
+            }
+
+            public override AbstractMessageWrapper DefaultInstanceForType
+            {
+                get { return new AbstractMessageWrapper(wrappedMessage.WeakDefaultInstanceForType); }
+            }
+
+            public override IDictionary<FieldDescriptor, object> AllFields
+            {
+                get { return wrappedMessage.AllFields; }
+            }
+
+            public override bool HasField(FieldDescriptor field)
+            {
+                return wrappedMessage.HasField(field);
+            }
+
+            public override object this[FieldDescriptor field]
+            {
+                get { return wrappedMessage[field]; }
+            }
+
+            public override object this[FieldDescriptor field, int index]
+            {
+                get { return wrappedMessage[field, index]; }
+            }
+
+            public override int GetRepeatedFieldCount(FieldDescriptor field)
+            {
+                return wrappedMessage.GetRepeatedFieldCount(field);
+            }
+
+            public override UnknownFieldSet UnknownFields
+            {
+                get { return wrappedMessage.UnknownFields; }
+            }
+
+            public override Builder CreateBuilderForType()
+            {
+                return new Builder(wrappedMessage.WeakCreateBuilderForType());
+            }
+
+            public override Builder ToBuilder()
+            {
+                return new Builder(wrappedMessage.WeakToBuilder());
+            }
+
+            internal class Builder : AbstractBuilder<AbstractMessageWrapper, Builder>
+            {
+                private readonly IBuilder wrappedBuilder;
+
+                protected override Builder ThisBuilder
+                {
+                    get { return this; }
+                }
+
+                internal Builder(IBuilder wrappedBuilder)
+                {
+                    this.wrappedBuilder = wrappedBuilder;
+                }
+
+                public override Builder MergeFrom(AbstractMessageWrapper other)
+                {
+                    wrappedBuilder.WeakMergeFrom(other.wrappedMessage);
+                    return this;
+                }
+
+                public override bool IsInitialized
+                {
+                    get { return wrappedBuilder.IsInitialized; }
+                }
+
+                public override IDictionary<FieldDescriptor, object> AllFields
+                {
+                    get { return wrappedBuilder.AllFields; }
+                }
+
+                public override object this[FieldDescriptor field]
+                {
+                    get { return wrappedBuilder[field]; }
+                    set { wrappedBuilder[field] = value; }
+                }
+
+                public override MessageDescriptor DescriptorForType
+                {
+                    get { return wrappedBuilder.DescriptorForType; }
+                }
+
+                public override int GetRepeatedFieldCount(FieldDescriptor field)
+                {
+                    return wrappedBuilder.GetRepeatedFieldCount(field);
+                }
+
+                public override object this[FieldDescriptor field, int index]
+                {
+                    get { return wrappedBuilder[field, index]; }
+                    set { wrappedBuilder[field, index] = value; }
+                }
+
+                public override bool HasField(FieldDescriptor field)
+                {
+                    return wrappedBuilder.HasField(field);
+                }
+
+                public override UnknownFieldSet UnknownFields
+                {
+                    get { return wrappedBuilder.UnknownFields; }
+                    set { wrappedBuilder.UnknownFields = value; }
+                }
+
+                public override AbstractMessageWrapper Build()
+                {
+                    return new AbstractMessageWrapper(wrappedBuilder.WeakBuild());
+                }
+
+                public override AbstractMessageWrapper BuildPartial()
+                {
+                    return new AbstractMessageWrapper(wrappedBuilder.WeakBuildPartial());
+                }
+
+                public override Builder Clone()
+                {
+                    return new Builder(wrappedBuilder.WeakClone());
+                }
+
+                public override AbstractMessageWrapper DefaultInstanceForType
+                {
+                    get { return new AbstractMessageWrapper(wrappedBuilder.WeakDefaultInstanceForType); }
+                }
+
+                public override Builder ClearField(FieldDescriptor field)
+                {
+                    wrappedBuilder.WeakClearField(field);
+                    return this;
+                }
+
+                public override Builder AddRepeatedField(FieldDescriptor field, object value)
+                {
+                    wrappedBuilder.WeakAddRepeatedField(field, value);
+                    return this;
+                }
+
+                public override IBuilder CreateBuilderForField(FieldDescriptor field)
+                {
+                    wrappedBuilder.CreateBuilderForField(field);
+                    return this;
+                }
+
+                public override Builder MergeFrom(IMessage other)
+                {
+                    wrappedBuilder.WeakMergeFrom(other);
+                    return this;
+                }
+
+                public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry)
+                {
+                    wrappedBuilder.WeakMergeFrom(input, extensionRegistry);
+                    return this;
+                }
+            }
+        }
+    }
+}

+ 131 - 117
src/ProtocolBuffers.Test/ByteStringTest.cs

@@ -1,117 +1,131 @@
-#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;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class ByteStringTest {
-    [Test]
-    public void EmptyByteStringHasZeroSize() {
-      Assert.AreEqual(0, ByteString.Empty.Length);
-    }
-
-    [Test]
-    public void CopyFromStringWithExplicitEncoding() {
-      ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
-      Assert.AreEqual(4, bs.Length);
-      Assert.AreEqual(65, bs[0]);
-      Assert.AreEqual(0, bs[1]);
-      Assert.AreEqual(66, bs[2]);
-      Assert.AreEqual(0, bs[3]);
-    }
-
-    [Test]
-    public void IsEmptyWhenEmpty() {
-      Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
-    }
-
-    [Test]
-    public void IsEmptyWhenNotEmpty() {
-      Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
-    }
-
-    [Test]
-    public void CopyFromByteArrayCopiesContents() {
-      byte[] data = new byte[1];
-      data[0] = 10;
-      ByteString bs = ByteString.CopyFrom(data);
-      Assert.AreEqual(10, bs[0]);
-      data[0] = 5;
-      Assert.AreEqual(10, bs[0]);
-    }
-
-    [Test]
-    public void ToByteArrayCopiesContents() {
-      ByteString bs = ByteString.CopyFromUtf8("Hello");
-      byte[] data = bs.ToByteArray();
-      Assert.AreEqual('H', data[0]);
-      Assert.AreEqual('H', bs[0]);
-      data[0] = 0;
-      Assert.AreEqual(0, data[0]);
-      Assert.AreEqual('H', bs[0]);
-    }
-
-    [Test]
-    public void CopyFromUtf8UsesUtf8() {
-      ByteString bs = ByteString.CopyFromUtf8("\u20ac");
-      Assert.AreEqual(3, bs.Length);
-      Assert.AreEqual(0xe2, bs[0]);
-      Assert.AreEqual(0x82, bs[1]);
-      Assert.AreEqual(0xac, bs[2]);
-    }
-
-    [Test]
-    public void CopyFromPortion() {
-      byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6};
-      ByteString bs = ByteString.CopyFrom(data, 2, 3);
-      Assert.AreEqual(3, bs.Length);
-      Assert.AreEqual(2, bs[0]);
-      Assert.AreEqual(3, bs[1]);
-    }
-
-    [Test]
-    public void ToStringUtf8() {
-      ByteString bs = ByteString.CopyFromUtf8("\u20ac");
-      Assert.AreEqual("\u20ac", bs.ToStringUtf8());
-    }
-
-    [Test]
-    public void ToStringWithExplicitEncoding() {
-      ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
-      Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
-    }
-  }
-}
+#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;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class ByteStringTest
+    {
+        [Test]
+        public void EmptyByteStringHasZeroSize()
+        {
+            Assert.AreEqual(0, ByteString.Empty.Length);
+        }
+
+        [Test]
+        public void CopyFromStringWithExplicitEncoding()
+        {
+            ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
+            Assert.AreEqual(4, bs.Length);
+            Assert.AreEqual(65, bs[0]);
+            Assert.AreEqual(0, bs[1]);
+            Assert.AreEqual(66, bs[2]);
+            Assert.AreEqual(0, bs[3]);
+        }
+
+        [Test]
+        public void IsEmptyWhenEmpty()
+        {
+            Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
+        }
+
+        [Test]
+        public void IsEmptyWhenNotEmpty()
+        {
+            Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
+        }
+
+        [Test]
+        public void CopyFromByteArrayCopiesContents()
+        {
+            byte[] data = new byte[1];
+            data[0] = 10;
+            ByteString bs = ByteString.CopyFrom(data);
+            Assert.AreEqual(10, bs[0]);
+            data[0] = 5;
+            Assert.AreEqual(10, bs[0]);
+        }
+
+        [Test]
+        public void ToByteArrayCopiesContents()
+        {
+            ByteString bs = ByteString.CopyFromUtf8("Hello");
+            byte[] data = bs.ToByteArray();
+            Assert.AreEqual('H', data[0]);
+            Assert.AreEqual('H', bs[0]);
+            data[0] = 0;
+            Assert.AreEqual(0, data[0]);
+            Assert.AreEqual('H', bs[0]);
+        }
+
+        [Test]
+        public void CopyFromUtf8UsesUtf8()
+        {
+            ByteString bs = ByteString.CopyFromUtf8("\u20ac");
+            Assert.AreEqual(3, bs.Length);
+            Assert.AreEqual(0xe2, bs[0]);
+            Assert.AreEqual(0x82, bs[1]);
+            Assert.AreEqual(0xac, bs[2]);
+        }
+
+        [Test]
+        public void CopyFromPortion()
+        {
+            byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
+            ByteString bs = ByteString.CopyFrom(data, 2, 3);
+            Assert.AreEqual(3, bs.Length);
+            Assert.AreEqual(2, bs[0]);
+            Assert.AreEqual(3, bs[1]);
+        }
+
+        [Test]
+        public void ToStringUtf8()
+        {
+            ByteString bs = ByteString.CopyFromUtf8("\u20ac");
+            Assert.AreEqual("\u20ac", bs.ToStringUtf8());
+        }
+
+        [Test]
+        public void ToStringWithExplicitEncoding()
+        {
+            ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
+            Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
+        }
+    }
+}

+ 127 - 104
src/ProtocolBuffers.Test/CSharpOptionsTest.cs

@@ -1,104 +1,127 @@
-#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.DescriptorProtos;
-using Google.ProtocolBuffers.Descriptors;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class DescriptorUtilTest {
-    [Test]
-    public void ExplicitNamespace() {
-      FileDescriptorProto proto = new FileDescriptorProto.Builder {
-        Name = "x", Package = "pack", Options = new FileOptions.Builder().SetExtension(CSharpOptions.CSharpFileOptions,
-          new CSharpFileOptions.Builder { Namespace = "Foo.Bar" }.Build()).Build()
-      }.Build();
-      FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
-      Assert.AreEqual("Foo.Bar", descriptor.CSharpOptions.Namespace);
-    }
-
-    [Test]
-    public void NoNamespaceFallsBackToPackage() {
-      FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "x", Package = "pack" }.Build();
-      FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
-      Assert.AreEqual("pack", descriptor.CSharpOptions.Namespace);
-    }
-
-    [Test]
-    public void NoNamespaceOrPackageFallsBackToEmptyString() {
-      FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "x" }.Build();
-      FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
-      Assert.AreEqual("", descriptor.CSharpOptions.Namespace);
-    }
-
-    [Test]
-    public void ExplicitlyNamedFileClass() {
-      FileDescriptorProto proto = new FileDescriptorProto.Builder {
-        Name = "x", Options = new FileOptions.Builder().SetExtension(CSharpOptions.CSharpFileOptions,
-          new CSharpFileOptions.Builder { UmbrellaClassname = "Foo" }.Build()).Build()
-      }.Build();
-      FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
-      Assert.AreEqual("Foo", descriptor.CSharpOptions.UmbrellaClassname);
-    }
-
-    [Test]
-    public void ImplicitFileClassWithProtoSuffix() {
-      FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "foo_bar.proto" }.Build();
-      FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
-      Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
-    }
-
-    [Test]
-    public void ImplicitFileClassWithProtoDevelSuffix() {
-      FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "foo_bar.protodevel" }.Build();
-      FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
-      Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
-    }
-
-    [Test]
-    public void ImplicitFileClassWithNoSuffix() {
-      FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "foo_bar" }.Build();
-      FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
-      Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
-    }
-
-    [Test]
-    public void ImplicitFileClassWithDirectoryStructure() {
-      FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "x/y/foo_bar" }.Build();
-      FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
-      Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
-    }
-  }
-}
+#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.DescriptorProtos;
+using Google.ProtocolBuffers.Descriptors;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class DescriptorUtilTest
+    {
+        [Test]
+        public void ExplicitNamespace()
+        {
+            FileDescriptorProto proto = new FileDescriptorProto.Builder
+                                            {
+                                                Name = "x",
+                                                Package = "pack",
+                                                Options =
+                                                    new FileOptions.Builder().SetExtension(
+                                                        CSharpOptions.CSharpFileOptions,
+                                                        new CSharpFileOptions.Builder {Namespace = "Foo.Bar"}.Build()).
+                                                    Build()
+                                            }.Build();
+            FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
+            Assert.AreEqual("Foo.Bar", descriptor.CSharpOptions.Namespace);
+        }
+
+        [Test]
+        public void NoNamespaceFallsBackToPackage()
+        {
+            FileDescriptorProto proto = new FileDescriptorProto.Builder {Name = "x", Package = "pack"}.Build();
+            FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
+            Assert.AreEqual("pack", descriptor.CSharpOptions.Namespace);
+        }
+
+        [Test]
+        public void NoNamespaceOrPackageFallsBackToEmptyString()
+        {
+            FileDescriptorProto proto = new FileDescriptorProto.Builder {Name = "x"}.Build();
+            FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
+            Assert.AreEqual("", descriptor.CSharpOptions.Namespace);
+        }
+
+        [Test]
+        public void ExplicitlyNamedFileClass()
+        {
+            FileDescriptorProto proto = new FileDescriptorProto.Builder
+                                            {
+                                                Name = "x",
+                                                Options =
+                                                    new FileOptions.Builder().SetExtension(
+                                                        CSharpOptions.CSharpFileOptions,
+                                                        new CSharpFileOptions.Builder {UmbrellaClassname = "Foo"}.Build())
+                                                    .Build()
+                                            }.Build();
+            FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
+            Assert.AreEqual("Foo", descriptor.CSharpOptions.UmbrellaClassname);
+        }
+
+        [Test]
+        public void ImplicitFileClassWithProtoSuffix()
+        {
+            FileDescriptorProto proto = new FileDescriptorProto.Builder {Name = "foo_bar.proto"}.Build();
+            FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
+            Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
+        }
+
+        [Test]
+        public void ImplicitFileClassWithProtoDevelSuffix()
+        {
+            FileDescriptorProto proto = new FileDescriptorProto.Builder {Name = "foo_bar.protodevel"}.Build();
+            FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
+            Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
+        }
+
+        [Test]
+        public void ImplicitFileClassWithNoSuffix()
+        {
+            FileDescriptorProto proto = new FileDescriptorProto.Builder {Name = "foo_bar"}.Build();
+            FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
+            Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
+        }
+
+        [Test]
+        public void ImplicitFileClassWithDirectoryStructure()
+        {
+            FileDescriptorProto proto = new FileDescriptorProto.Builder {Name = "x/y/foo_bar"}.Build();
+            FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
+            Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
+        }
+    }
+}

+ 526 - 459
src/ProtocolBuffers.Test/CodedInputStreamTest.cs

@@ -1,459 +1,526 @@
-#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 Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-using System.Diagnostics;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class CodedInputStreamTest {
-
-    /// <summary>
-    /// Helper to construct a byte array from a bunch of bytes.  The inputs are
-    /// actually ints so that I can use hex notation and not get stupid errors
-    /// about precision.
-    /// </summary>
-    private static byte[] Bytes(params int[] bytesAsInts) {
-      byte[] bytes = new byte[bytesAsInts.Length];
-      for (int i = 0; i < bytesAsInts.Length; i++) {
-        bytes[i] = (byte)bytesAsInts[i];
-      }
-      return bytes;
-    }
-
-    /// <summary>
-    /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
-    /// </summary>
-    private static void AssertReadVarint(byte[] data, ulong value) {
-      CodedInputStream input = CodedInputStream.CreateInstance(data);
-      Assert.AreEqual((uint)value, input.ReadRawVarint32());
-
-      input = CodedInputStream.CreateInstance(data);
-      Assert.AreEqual(value, input.ReadRawVarint64());
-      Assert.IsTrue(input.IsAtEnd);
-
-      // Try different block sizes.
-      for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) {
-        input = CodedInputStream.CreateInstance(new SmallBlockInputStream(data, bufferSize));
-        Assert.AreEqual((uint)value, input.ReadRawVarint32());
-
-        input = CodedInputStream.CreateInstance(new SmallBlockInputStream(data, bufferSize));
-        Assert.AreEqual(value, input.ReadRawVarint64());
-        Assert.IsTrue(input.IsAtEnd);
-      }
-
-      // Try reading directly from a MemoryStream. We want to verify that it
-      // doesn't read past the end of the input, so write an extra byte - this
-      // lets us test the position at the end.
-      MemoryStream memoryStream = new MemoryStream();
-      memoryStream.Write(data, 0, data.Length);
-      memoryStream.WriteByte(0);
-      memoryStream.Position = 0;
-      Assert.AreEqual((uint)value, CodedInputStream.ReadRawVarint32(memoryStream));
-      Assert.AreEqual(data.Length, memoryStream.Position);
-    }
-
-    /// <summary>
-    /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
-    /// expects them to fail with an InvalidProtocolBufferException whose
-    /// description matches the given one.
-    /// </summary>
-    private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data) {
-      CodedInputStream input = CodedInputStream.CreateInstance(data);
-      try {
-        input.ReadRawVarint32();
-        Assert.Fail("Should have thrown an exception.");
-      } catch (InvalidProtocolBufferException e) {
-        Assert.AreEqual(expected.Message, e.Message);
-      }
-
-      input = CodedInputStream.CreateInstance(data);
-      try {
-        input.ReadRawVarint64();
-        Assert.Fail("Should have thrown an exception.");
-      } catch (InvalidProtocolBufferException e) {
-        Assert.AreEqual(expected.Message, e.Message);
-      }
-
-      // Make sure we get the same error when reading directly from a Stream.
-      try {
-        CodedInputStream.ReadRawVarint32(new MemoryStream(data));
-        Assert.Fail("Should have thrown an exception.");
-      } catch (InvalidProtocolBufferException e) {
-        Assert.AreEqual(expected.Message, e.Message);
-      }
-    }
-
-    [Test]
-    public void ReadVarint() {
-      AssertReadVarint(Bytes(0x00), 0);
-      AssertReadVarint(Bytes(0x01), 1);
-      AssertReadVarint(Bytes(0x7f), 127);
-      // 14882
-      AssertReadVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
-      // 2961488830
-      AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
-        (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
-        (0x0bL << 28));
-
-      // 64-bit
-      // 7256456126
-      AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
-        (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
-        (0x1bL << 28));
-      // 41256202580718336
-      AssertReadVarint(Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
-        (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
-        (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
-      // 11964378330978735131
-      AssertReadVarint(Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
-        (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
-        (0x3bUL << 28) | (0x56UL << 35) | (0x00UL << 42) |
-        (0x05UL << 49) | (0x26UL << 56) | (0x01UL << 63));
-
-      // Failures
-      AssertReadVarintFailure(
-        InvalidProtocolBufferException.MalformedVarint(),
-        Bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-              0x00));
-      AssertReadVarintFailure(
-        InvalidProtocolBufferException.TruncatedMessage(),
-        Bytes(0x80));
-    }
-
-    /// <summary>
-    /// Parses the given bytes using ReadRawLittleEndian32() and checks
-    /// that the result matches the given value.
-    /// </summary>
-    private static void AssertReadLittleEndian32(byte[] data, uint value) {
-      CodedInputStream input = CodedInputStream.CreateInstance(data);
-      Assert.AreEqual(value, input.ReadRawLittleEndian32());
-      Assert.IsTrue(input.IsAtEnd);
-
-      // Try different block sizes.
-      for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
-        input = CodedInputStream.CreateInstance(
-          new SmallBlockInputStream(data, blockSize));
-        Assert.AreEqual(value, input.ReadRawLittleEndian32());
-        Assert.IsTrue(input.IsAtEnd);
-      }
-    }
-
-    /// <summary>
-    /// Parses the given bytes using ReadRawLittleEndian64() and checks
-    /// that the result matches the given value.
-    /// </summary>
-    private static void AssertReadLittleEndian64(byte[] data, ulong value) {
-      CodedInputStream input = CodedInputStream.CreateInstance(data);
-      Assert.AreEqual(value, input.ReadRawLittleEndian64());
-      Assert.IsTrue(input.IsAtEnd);
-
-      // Try different block sizes.
-      for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
-        input = CodedInputStream.CreateInstance(
-          new SmallBlockInputStream(data, blockSize));
-        Assert.AreEqual(value, input.ReadRawLittleEndian64());
-        Assert.IsTrue(input.IsAtEnd);
-      }
-    }
-
-    [Test]
-    public void ReadLittleEndian() {
-      AssertReadLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
-      AssertReadLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
-
-      AssertReadLittleEndian64(Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
-        0x123456789abcdef0L);
-      AssertReadLittleEndian64(
-        Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678UL);
-    }
-
-    [Test]
-    public void DecodeZigZag32() {
-      Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0));
-      Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1));
-      Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2));
-      Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3));
-      Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE));
-      Assert.AreEqual(unchecked((int)0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF));
-      Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE));
-      Assert.AreEqual(unchecked((int)0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF));
-    }
-
-    [Test]
-    public void DecodeZigZag64() {
-      Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0));
-      Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1));
-      Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2));
-      Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3));
-      Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL));
-      Assert.AreEqual(unchecked((long)0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL));
-      Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL));
-      Assert.AreEqual(unchecked((long)0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL));
-      Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
-      Assert.AreEqual(unchecked((long)0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
-    }
-
-    [Test]
-    public void ReadWholeMessage() {
-      TestAllTypes message = TestUtil.GetAllSet();
-
-      byte[] rawBytes = message.ToByteArray();
-      Assert.AreEqual(rawBytes.Length, message.SerializedSize);
-      TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
-      TestUtil.AssertAllFieldsSet(message2);
-
-      // Try different block sizes.
-      for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
-        message2 = TestAllTypes.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
-        TestUtil.AssertAllFieldsSet(message2);
-      }
-    }
-
-    [Test]
-    public void SkipWholeMessage() {
-      TestAllTypes message = TestUtil.GetAllSet();
-      byte[] rawBytes = message.ToByteArray();
-
-      // Create two parallel inputs.  Parse one as unknown fields while using
-      // skipField() to skip each field on the other.  Expect the same tags.
-      CodedInputStream input1 = CodedInputStream.CreateInstance(rawBytes);
-      CodedInputStream input2 = CodedInputStream.CreateInstance(rawBytes);
-      UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder();
-
-      while (true) {
-        uint tag = input1.ReadTag();
-        Assert.AreEqual(tag, input2.ReadTag());
-        if (tag == 0) {
-          break;
-        }
-        unknownFields.MergeFieldFrom(tag, input1);
-        input2.SkipField(tag);
-      }
-    }
-
-    /// <summary>
-    /// Test that a bug in SkipRawBytes has been fixed: if the skip
-    /// skips exactly up to a limit, this should bnot break things
-    /// </summary>
-    [Test]
-    public void SkipRawBytesBug() {
-      byte[] rawBytes = new byte[] { 1, 2 };
-      CodedInputStream input = CodedInputStream.CreateInstance(rawBytes);
-
-      int limit = input.PushLimit(1);
-      input.SkipRawBytes(1);
-      input.PopLimit(limit);
-      Assert.AreEqual(2, input.ReadRawByte());
-    }
-
-    public void ReadHugeBlob() {
-      // Allocate and initialize a 1MB blob.
-      byte[] blob = new byte[1 << 20];
-      for (int i = 0; i < blob.Length; i++) {
-        blob[i] = (byte)i;
-      }
-
-      // Make a message containing it.
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TestUtil.SetAllFields(builder);
-      builder.SetOptionalBytes(ByteString.CopyFrom(blob));
-      TestAllTypes message = builder.Build();
-
-      // Serialize and parse it.  Make sure to parse from an InputStream, not
-      // directly from a ByteString, so that CodedInputStream uses buffered
-      // reading.
-      TestAllTypes message2 = TestAllTypes.ParseFrom(message.ToByteString().CreateCodedInput());
-
-      Assert.AreEqual(message.OptionalBytes, message2.OptionalBytes);
-
-      // Make sure all the other fields were parsed correctly.
-      TestAllTypes message3 = TestAllTypes.CreateBuilder(message2)
-        .SetOptionalBytes(TestUtil.GetAllSet().OptionalBytes)
-        .Build();
-      TestUtil.AssertAllFieldsSet(message3);
-    }
-
-    [Test]
-    public void ReadMaliciouslyLargeBlob() {
-      MemoryStream ms = new MemoryStream();
-      CodedOutputStream output = CodedOutputStream.CreateInstance(ms);
-
-      uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
-      output.WriteRawVarint32(tag);
-      output.WriteRawVarint32(0x7FFFFFFF);
-      output.WriteRawBytes(new byte[32]);  // Pad with a few random bytes.
-      output.Flush();
-      ms.Position = 0;
-
-      CodedInputStream input = CodedInputStream.CreateInstance(ms);
-      Assert.AreEqual(tag, input.ReadTag());
-
-      try {
-        input.ReadBytes();
-        Assert.Fail("Should have thrown an exception!");
-      } catch (InvalidProtocolBufferException) {
-        // success.
-      }
-    }
-    
-    private static TestRecursiveMessage MakeRecursiveMessage(int depth) {
-      if (depth == 0) {
-        return TestRecursiveMessage.CreateBuilder().SetI(5).Build();
-      } else {
-        return TestRecursiveMessage.CreateBuilder()
-          .SetA(MakeRecursiveMessage(depth - 1)).Build();
-      }
-    }
-
-    private static void AssertMessageDepth(TestRecursiveMessage message, int depth) {
-      if (depth == 0) {
-        Assert.IsFalse(message.HasA);
-        Assert.AreEqual(5, message.I);
-      } else {
-        Assert.IsTrue(message.HasA);
-        AssertMessageDepth(message.A, depth - 1);
-      }
-    }
-
-    [Test]
-    public void MaliciousRecursion() {
-      ByteString data64 = MakeRecursiveMessage(64).ToByteString();
-      ByteString data65 = MakeRecursiveMessage(65).ToByteString();
-
-      AssertMessageDepth(TestRecursiveMessage.ParseFrom(data64), 64);
-
-      try {
-        TestRecursiveMessage.ParseFrom(data65);
-        Assert.Fail("Should have thrown an exception!");
-      } catch (InvalidProtocolBufferException) {
-        // success.
-      }
-
-      CodedInputStream input = data64.CreateCodedInput();
-      input.SetRecursionLimit(8);
-      try {
-        TestRecursiveMessage.ParseFrom(input);
-        Assert.Fail("Should have thrown an exception!");
-      } catch (InvalidProtocolBufferException) {
-        // success.
-      }
-    }
-
-    [Test]
-    public void SizeLimit() {
-      // Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
-      // apply to the latter case.
-      MemoryStream ms = new MemoryStream(TestUtil.GetAllSet().ToByteString().ToByteArray());
-      CodedInputStream input = CodedInputStream.CreateInstance(ms);
-      input.SetSizeLimit(16);
-
-      try {
-        TestAllTypes.ParseFrom(input);
-        Assert.Fail("Should have thrown an exception!");
-      } catch (InvalidProtocolBufferException) {
-        // success.
-      }
-    }
-
-    [Test]
-    public void ResetSizeCounter() {
-      CodedInputStream input = CodedInputStream.CreateInstance(
-          new SmallBlockInputStream(new byte[256], 8));
-      input.SetSizeLimit(16);
-      input.ReadRawBytes(16);
-
-      try {
-        input.ReadRawByte();
-        Assert.Fail("Should have thrown an exception!");
-      } catch (InvalidProtocolBufferException) {
-        // Success.
-      }
-
-      input.ResetSizeCounter();
-      input.ReadRawByte();  // No exception thrown.
-
-      try {
-        input.ReadRawBytes(16);  // Hits limit again.
-        Assert.Fail("Should have thrown an exception!");
-      } catch (InvalidProtocolBufferException) {
-        // Success.
-      }
-    }
-
-    /// <summary>
-    /// Tests that if we read an string that contains invalid UTF-8, no exception
-    /// is thrown.  Instead, the invalid bytes are replaced with the Unicode
-    /// "replacement character" U+FFFD.
-    /// </summary>
-    [Test]
-    public void ReadInvalidUtf8()  {
-      MemoryStream ms = new MemoryStream();
-      CodedOutputStream output = CodedOutputStream.CreateInstance(ms);
-
-      uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
-      output.WriteRawVarint32(tag);
-      output.WriteRawVarint32(1);
-      output.WriteRawBytes(new byte[] { 0x80 });
-      output.Flush();
-      ms.Position = 0;
-
-      CodedInputStream input = CodedInputStream.CreateInstance(ms);
-      Assert.AreEqual(tag, input.ReadTag());
-      string text = input.ReadString();
-      Assert.AreEqual('\ufffd', text[0]);
-    }
-
-    /// <summary>
-    /// A stream which limits the number of bytes it reads at a time.
-    /// We use this to make sure that CodedInputStream doesn't screw up when
-    /// reading in small blocks.
-    /// </summary>
-    private sealed class SmallBlockInputStream : MemoryStream {
-      private readonly int blockSize;
-
-      public SmallBlockInputStream(byte[] data, int blockSize)
-        : base(data) {
-        this.blockSize = blockSize;
-      }
-
-      public override int Read(byte[] buffer, int offset, int count) {
-        return base.Read(buffer, offset, Math.Min(count, blockSize));
-      }
-    }
-  }
-}
+#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 Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+using System.Diagnostics;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class CodedInputStreamTest
+    {
+        /// <summary>
+        /// Helper to construct a byte array from a bunch of bytes.  The inputs are
+        /// actually ints so that I can use hex notation and not get stupid errors
+        /// about precision.
+        /// </summary>
+        private static byte[] Bytes(params int[] bytesAsInts)
+        {
+            byte[] bytes = new byte[bytesAsInts.Length];
+            for (int i = 0; i < bytesAsInts.Length; i++)
+            {
+                bytes[i] = (byte) bytesAsInts[i];
+            }
+            return bytes;
+        }
+
+        /// <summary>
+        /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
+        /// </summary>
+        private static void AssertReadVarint(byte[] data, ulong value)
+        {
+            CodedInputStream input = CodedInputStream.CreateInstance(data);
+            Assert.AreEqual((uint) value, input.ReadRawVarint32());
+
+            input = CodedInputStream.CreateInstance(data);
+            Assert.AreEqual(value, input.ReadRawVarint64());
+            Assert.IsTrue(input.IsAtEnd);
+
+            // Try different block sizes.
+            for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+            {
+                input = CodedInputStream.CreateInstance(new SmallBlockInputStream(data, bufferSize));
+                Assert.AreEqual((uint) value, input.ReadRawVarint32());
+
+                input = CodedInputStream.CreateInstance(new SmallBlockInputStream(data, bufferSize));
+                Assert.AreEqual(value, input.ReadRawVarint64());
+                Assert.IsTrue(input.IsAtEnd);
+            }
+
+            // Try reading directly from a MemoryStream. We want to verify that it
+            // doesn't read past the end of the input, so write an extra byte - this
+            // lets us test the position at the end.
+            MemoryStream memoryStream = new MemoryStream();
+            memoryStream.Write(data, 0, data.Length);
+            memoryStream.WriteByte(0);
+            memoryStream.Position = 0;
+            Assert.AreEqual((uint) value, CodedInputStream.ReadRawVarint32(memoryStream));
+            Assert.AreEqual(data.Length, memoryStream.Position);
+        }
+
+        /// <summary>
+        /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
+        /// expects them to fail with an InvalidProtocolBufferException whose
+        /// description matches the given one.
+        /// </summary>
+        private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data)
+        {
+            CodedInputStream input = CodedInputStream.CreateInstance(data);
+            try
+            {
+                input.ReadRawVarint32();
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (InvalidProtocolBufferException e)
+            {
+                Assert.AreEqual(expected.Message, e.Message);
+            }
+
+            input = CodedInputStream.CreateInstance(data);
+            try
+            {
+                input.ReadRawVarint64();
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (InvalidProtocolBufferException e)
+            {
+                Assert.AreEqual(expected.Message, e.Message);
+            }
+
+            // Make sure we get the same error when reading directly from a Stream.
+            try
+            {
+                CodedInputStream.ReadRawVarint32(new MemoryStream(data));
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (InvalidProtocolBufferException e)
+            {
+                Assert.AreEqual(expected.Message, e.Message);
+            }
+        }
+
+        [Test]
+        public void ReadVarint()
+        {
+            AssertReadVarint(Bytes(0x00), 0);
+            AssertReadVarint(Bytes(0x01), 1);
+            AssertReadVarint(Bytes(0x7f), 127);
+            // 14882
+            AssertReadVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+            // 2961488830
+            AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+                             (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+                             (0x0bL << 28));
+
+            // 64-bit
+            // 7256456126
+            AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+                             (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+                             (0x1bL << 28));
+            // 41256202580718336
+            AssertReadVarint(Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+                             (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+                             (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+            // 11964378330978735131
+            AssertReadVarint(Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+                             (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+                             (0x3bUL << 28) | (0x56UL << 35) | (0x00UL << 42) |
+                             (0x05UL << 49) | (0x26UL << 56) | (0x01UL << 63));
+
+            // Failures
+            AssertReadVarintFailure(
+                InvalidProtocolBufferException.MalformedVarint(),
+                Bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+                      0x00));
+            AssertReadVarintFailure(
+                InvalidProtocolBufferException.TruncatedMessage(),
+                Bytes(0x80));
+        }
+
+        /// <summary>
+        /// Parses the given bytes using ReadRawLittleEndian32() and checks
+        /// that the result matches the given value.
+        /// </summary>
+        private static void AssertReadLittleEndian32(byte[] data, uint value)
+        {
+            CodedInputStream input = CodedInputStream.CreateInstance(data);
+            Assert.AreEqual(value, input.ReadRawLittleEndian32());
+            Assert.IsTrue(input.IsAtEnd);
+
+            // Try different block sizes.
+            for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+            {
+                input = CodedInputStream.CreateInstance(
+                    new SmallBlockInputStream(data, blockSize));
+                Assert.AreEqual(value, input.ReadRawLittleEndian32());
+                Assert.IsTrue(input.IsAtEnd);
+            }
+        }
+
+        /// <summary>
+        /// Parses the given bytes using ReadRawLittleEndian64() and checks
+        /// that the result matches the given value.
+        /// </summary>
+        private static void AssertReadLittleEndian64(byte[] data, ulong value)
+        {
+            CodedInputStream input = CodedInputStream.CreateInstance(data);
+            Assert.AreEqual(value, input.ReadRawLittleEndian64());
+            Assert.IsTrue(input.IsAtEnd);
+
+            // Try different block sizes.
+            for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+            {
+                input = CodedInputStream.CreateInstance(
+                    new SmallBlockInputStream(data, blockSize));
+                Assert.AreEqual(value, input.ReadRawLittleEndian64());
+                Assert.IsTrue(input.IsAtEnd);
+            }
+        }
+
+        [Test]
+        public void ReadLittleEndian()
+        {
+            AssertReadLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+            AssertReadLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+            AssertReadLittleEndian64(Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
+                                     0x123456789abcdef0L);
+            AssertReadLittleEndian64(
+                Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678UL);
+        }
+
+        [Test]
+        public void DecodeZigZag32()
+        {
+            Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0));
+            Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1));
+            Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2));
+            Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3));
+            Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE));
+            Assert.AreEqual(unchecked((int) 0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF));
+            Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE));
+            Assert.AreEqual(unchecked((int) 0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF));
+        }
+
+        [Test]
+        public void DecodeZigZag64()
+        {
+            Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0));
+            Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1));
+            Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2));
+            Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3));
+            Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL));
+            Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL));
+            Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL));
+            Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL));
+            Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
+            Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
+        }
+
+        [Test]
+        public void ReadWholeMessage()
+        {
+            TestAllTypes message = TestUtil.GetAllSet();
+
+            byte[] rawBytes = message.ToByteArray();
+            Assert.AreEqual(rawBytes.Length, message.SerializedSize);
+            TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
+            TestUtil.AssertAllFieldsSet(message2);
+
+            // Try different block sizes.
+            for (int blockSize = 1; blockSize < 256; blockSize *= 2)
+            {
+                message2 = TestAllTypes.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
+                TestUtil.AssertAllFieldsSet(message2);
+            }
+        }
+
+        [Test]
+        public void SkipWholeMessage()
+        {
+            TestAllTypes message = TestUtil.GetAllSet();
+            byte[] rawBytes = message.ToByteArray();
+
+            // Create two parallel inputs.  Parse one as unknown fields while using
+            // skipField() to skip each field on the other.  Expect the same tags.
+            CodedInputStream input1 = CodedInputStream.CreateInstance(rawBytes);
+            CodedInputStream input2 = CodedInputStream.CreateInstance(rawBytes);
+            UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder();
+
+            while (true)
+            {
+                uint tag = input1.ReadTag();
+                Assert.AreEqual(tag, input2.ReadTag());
+                if (tag == 0)
+                {
+                    break;
+                }
+                unknownFields.MergeFieldFrom(tag, input1);
+                input2.SkipField(tag);
+            }
+        }
+
+        /// <summary>
+        /// Test that a bug in SkipRawBytes has been fixed: if the skip
+        /// skips exactly up to a limit, this should bnot break things
+        /// </summary>
+        [Test]
+        public void SkipRawBytesBug()
+        {
+            byte[] rawBytes = new byte[] {1, 2};
+            CodedInputStream input = CodedInputStream.CreateInstance(rawBytes);
+
+            int limit = input.PushLimit(1);
+            input.SkipRawBytes(1);
+            input.PopLimit(limit);
+            Assert.AreEqual(2, input.ReadRawByte());
+        }
+
+        public void ReadHugeBlob()
+        {
+            // Allocate and initialize a 1MB blob.
+            byte[] blob = new byte[1 << 20];
+            for (int i = 0; i < blob.Length; i++)
+            {
+                blob[i] = (byte) i;
+            }
+
+            // Make a message containing it.
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TestUtil.SetAllFields(builder);
+            builder.SetOptionalBytes(ByteString.CopyFrom(blob));
+            TestAllTypes message = builder.Build();
+
+            // Serialize and parse it.  Make sure to parse from an InputStream, not
+            // directly from a ByteString, so that CodedInputStream uses buffered
+            // reading.
+            TestAllTypes message2 = TestAllTypes.ParseFrom(message.ToByteString().CreateCodedInput());
+
+            Assert.AreEqual(message.OptionalBytes, message2.OptionalBytes);
+
+            // Make sure all the other fields were parsed correctly.
+            TestAllTypes message3 = TestAllTypes.CreateBuilder(message2)
+                .SetOptionalBytes(TestUtil.GetAllSet().OptionalBytes)
+                .Build();
+            TestUtil.AssertAllFieldsSet(message3);
+        }
+
+        [Test]
+        public void ReadMaliciouslyLargeBlob()
+        {
+            MemoryStream ms = new MemoryStream();
+            CodedOutputStream output = CodedOutputStream.CreateInstance(ms);
+
+            uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
+            output.WriteRawVarint32(tag);
+            output.WriteRawVarint32(0x7FFFFFFF);
+            output.WriteRawBytes(new byte[32]); // Pad with a few random bytes.
+            output.Flush();
+            ms.Position = 0;
+
+            CodedInputStream input = CodedInputStream.CreateInstance(ms);
+            Assert.AreEqual(tag, input.ReadTag());
+
+            try
+            {
+                input.ReadBytes();
+                Assert.Fail("Should have thrown an exception!");
+            }
+            catch (InvalidProtocolBufferException)
+            {
+                // success.
+            }
+        }
+
+        private static TestRecursiveMessage MakeRecursiveMessage(int depth)
+        {
+            if (depth == 0)
+            {
+                return TestRecursiveMessage.CreateBuilder().SetI(5).Build();
+            }
+            else
+            {
+                return TestRecursiveMessage.CreateBuilder()
+                    .SetA(MakeRecursiveMessage(depth - 1)).Build();
+            }
+        }
+
+        private static void AssertMessageDepth(TestRecursiveMessage message, int depth)
+        {
+            if (depth == 0)
+            {
+                Assert.IsFalse(message.HasA);
+                Assert.AreEqual(5, message.I);
+            }
+            else
+            {
+                Assert.IsTrue(message.HasA);
+                AssertMessageDepth(message.A, depth - 1);
+            }
+        }
+
+        [Test]
+        public void MaliciousRecursion()
+        {
+            ByteString data64 = MakeRecursiveMessage(64).ToByteString();
+            ByteString data65 = MakeRecursiveMessage(65).ToByteString();
+
+            AssertMessageDepth(TestRecursiveMessage.ParseFrom(data64), 64);
+
+            try
+            {
+                TestRecursiveMessage.ParseFrom(data65);
+                Assert.Fail("Should have thrown an exception!");
+            }
+            catch (InvalidProtocolBufferException)
+            {
+                // success.
+            }
+
+            CodedInputStream input = data64.CreateCodedInput();
+            input.SetRecursionLimit(8);
+            try
+            {
+                TestRecursiveMessage.ParseFrom(input);
+                Assert.Fail("Should have thrown an exception!");
+            }
+            catch (InvalidProtocolBufferException)
+            {
+                // success.
+            }
+        }
+
+        [Test]
+        public void SizeLimit()
+        {
+            // Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
+            // apply to the latter case.
+            MemoryStream ms = new MemoryStream(TestUtil.GetAllSet().ToByteString().ToByteArray());
+            CodedInputStream input = CodedInputStream.CreateInstance(ms);
+            input.SetSizeLimit(16);
+
+            try
+            {
+                TestAllTypes.ParseFrom(input);
+                Assert.Fail("Should have thrown an exception!");
+            }
+            catch (InvalidProtocolBufferException)
+            {
+                // success.
+            }
+        }
+
+        [Test]
+        public void ResetSizeCounter()
+        {
+            CodedInputStream input = CodedInputStream.CreateInstance(
+                new SmallBlockInputStream(new byte[256], 8));
+            input.SetSizeLimit(16);
+            input.ReadRawBytes(16);
+
+            try
+            {
+                input.ReadRawByte();
+                Assert.Fail("Should have thrown an exception!");
+            }
+            catch (InvalidProtocolBufferException)
+            {
+                // Success.
+            }
+
+            input.ResetSizeCounter();
+            input.ReadRawByte(); // No exception thrown.
+
+            try
+            {
+                input.ReadRawBytes(16); // Hits limit again.
+                Assert.Fail("Should have thrown an exception!");
+            }
+            catch (InvalidProtocolBufferException)
+            {
+                // Success.
+            }
+        }
+
+        /// <summary>
+        /// Tests that if we read an string that contains invalid UTF-8, no exception
+        /// is thrown.  Instead, the invalid bytes are replaced with the Unicode
+        /// "replacement character" U+FFFD.
+        /// </summary>
+        [Test]
+        public void ReadInvalidUtf8()
+        {
+            MemoryStream ms = new MemoryStream();
+            CodedOutputStream output = CodedOutputStream.CreateInstance(ms);
+
+            uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
+            output.WriteRawVarint32(tag);
+            output.WriteRawVarint32(1);
+            output.WriteRawBytes(new byte[] {0x80});
+            output.Flush();
+            ms.Position = 0;
+
+            CodedInputStream input = CodedInputStream.CreateInstance(ms);
+            Assert.AreEqual(tag, input.ReadTag());
+            string text = input.ReadString();
+            Assert.AreEqual('\ufffd', text[0]);
+        }
+
+        /// <summary>
+        /// A stream which limits the number of bytes it reads at a time.
+        /// We use this to make sure that CodedInputStream doesn't screw up when
+        /// reading in small blocks.
+        /// </summary>
+        private sealed class SmallBlockInputStream : MemoryStream
+        {
+            private readonly int blockSize;
+
+            public SmallBlockInputStream(byte[] data, int blockSize)
+                : base(data)
+            {
+                this.blockSize = blockSize;
+            }
+
+            public override int Read(byte[] buffer, int offset, int count)
+            {
+                return base.Read(buffer, offset, Math.Min(count, blockSize));
+            }
+        }
+    }
+}

+ 292 - 270
src/ProtocolBuffers.Test/CodedOutputStreamTest.cs

@@ -1,270 +1,292 @@
-#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 Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class CodedOutputStreamTest {
-
-    /// <summary>
-    /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
-    /// checks that the result matches the given bytes
-    /// </summary>
-    private static void AssertWriteVarint(byte[] data, ulong value) {
-      // Only do 32-bit write if the value fits in 32 bits.
-      if ((value >> 32) == 0) {
-        MemoryStream rawOutput = new MemoryStream();
-        CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
-        output.WriteRawVarint32((uint) value);
-        output.Flush();
-        Assert.AreEqual(data, rawOutput.ToArray());
-        // Also try computing size.
-        Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
-      }
-
-      {
-        MemoryStream rawOutput = new MemoryStream();
-        CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
-        output.WriteRawVarint64(value);
-        output.Flush();
-        Assert.AreEqual(data, rawOutput.ToArray());
-
-        // Also try computing size.
-        Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
-      }
-
-      // Try different buffer sizes.
-      for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) {
-        // Only do 32-bit write if the value fits in 32 bits.
-        if ((value >> 32) == 0) {
-          MemoryStream rawOutput = new MemoryStream();
-          CodedOutputStream output =
-            CodedOutputStream.CreateInstance(rawOutput, bufferSize);
-          output.WriteRawVarint32((uint) value);
-          output.Flush();
-          Assert.AreEqual(data, rawOutput.ToArray());
-        }
-
-        {
-          MemoryStream rawOutput = new MemoryStream();
-          CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput, bufferSize);
-          output.WriteRawVarint64(value);
-          output.Flush();
-          Assert.AreEqual(data, rawOutput.ToArray());
-        }
-      }
-    }
-
-    /// <summary>
-    /// Tests WriteRawVarint32() and WriteRawVarint64()
-    /// </summary>
-    [Test]
-    public void WriteVarint() {
-      AssertWriteVarint(new byte[] {0x00}, 0);
-      AssertWriteVarint(new byte[] {0x01}, 1);
-      AssertWriteVarint(new byte[] {0x7f}, 127);
-      // 14882
-      AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
-      // 2961488830
-      AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
-        (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
-        (0x0bL << 28));
-
-      // 64-bit
-      // 7256456126
-      AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
-        (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
-        (0x1bL << 28));
-      // 41256202580718336
-      AssertWriteVarint(
-        new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
-        (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
-        (0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
-      // 11964378330978735131
-      AssertWriteVarint(
-        new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
-        unchecked((ulong)
-        ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
-        (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
-        (0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
-    }
-
-    /// <summary>
-    /// Parses the given bytes using WriteRawLittleEndian32() and checks
-    /// that the result matches the given value.
-    /// </summary>
-    private static void AssertWriteLittleEndian32(byte[] data, uint value) {
-      MemoryStream rawOutput = new MemoryStream();
-      CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
-      output.WriteRawLittleEndian32(value);
-      output.Flush();
-      Assert.AreEqual(data, rawOutput.ToArray());
-
-      // Try different buffer sizes.
-      for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) {
-        rawOutput = new MemoryStream();
-        output = CodedOutputStream.CreateInstance(rawOutput, bufferSize);
-        output.WriteRawLittleEndian32(value);
-        output.Flush();
-        Assert.AreEqual(data, rawOutput.ToArray());
-      }
-    }
-
-    /// <summary>
-    /// Parses the given bytes using WriteRawLittleEndian64() and checks
-    /// that the result matches the given value.
-    /// </summary>
-    private static void AssertWriteLittleEndian64(byte[] data, ulong value) {
-      MemoryStream rawOutput = new MemoryStream();
-      CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
-      output.WriteRawLittleEndian64(value);
-      output.Flush();
-      Assert.AreEqual(data, rawOutput.ToArray());
-
-      // Try different block sizes.
-      for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
-        rawOutput = new MemoryStream();
-        output = CodedOutputStream.CreateInstance(rawOutput, blockSize);
-        output.WriteRawLittleEndian64(value);
-        output.Flush();
-        Assert.AreEqual(data, rawOutput.ToArray());
-      }
-    }
-
-    /// <summary>
-    /// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
-    /// </summary>
-    [Test]
-    public void WriteLittleEndian() {
-      AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
-      AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
-
-      AssertWriteLittleEndian64(
-        new byte[]{0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
-        0x123456789abcdef0L);
-      AssertWriteLittleEndian64(
-        new byte[]{0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
-        0x9abcdef012345678UL);
-    }
-
-    [Test]
-    public void WriteWholeMessage() {
-      TestAllTypes message = TestUtil.GetAllSet();
-
-      byte[] rawBytes = message.ToByteArray();
-      TestUtil.AssertEqualBytes(TestUtil.GoldenMessage.ToByteArray(), rawBytes);
-
-      // Try different block sizes.
-      for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
-        MemoryStream rawOutput = new MemoryStream();
-        CodedOutputStream output =
-          CodedOutputStream.CreateInstance(rawOutput, blockSize);
-        message.WriteTo(output);
-        output.Flush();
-        TestUtil.AssertEqualBytes(rawBytes, rawOutput.ToArray());
-      }
-    }
-
-    /// <summary>
-    /// Tests writing a whole message with every packed field type. Ensures the
-    /// wire format of packed fields is compatible with C++.
-    /// </summary>
-    [Test]
-    public void WriteWholePackedFieldsMessage() {
-      TestPackedTypes message = TestUtil.GetPackedSet();
-
-      byte[] rawBytes = message.ToByteArray();
-      TestUtil.AssertEqualBytes(TestUtil.GetGoldenPackedFieldsMessage().ToByteArray(),
-                       rawBytes);
-    }
-
-    [Test]
-    public void EncodeZigZag32() {
-      Assert.AreEqual(0, CodedOutputStream.EncodeZigZag32( 0));
-      Assert.AreEqual(1, CodedOutputStream.EncodeZigZag32(-1));
-      Assert.AreEqual(2, CodedOutputStream.EncodeZigZag32( 1));
-      Assert.AreEqual(3, CodedOutputStream.EncodeZigZag32(-2));
-      Assert.AreEqual(0x7FFFFFFE, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
-      Assert.AreEqual(0x7FFFFFFF, CodedOutputStream.EncodeZigZag32(unchecked((int)0xC0000000)));
-      Assert.AreEqual(0xFFFFFFFE, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
-      Assert.AreEqual(0xFFFFFFFF, CodedOutputStream.EncodeZigZag32(unchecked((int)0x80000000)));
-    }
-
-    [Test]
-    public void EncodeZigZag64() {
-      Assert.AreEqual(0, CodedOutputStream.EncodeZigZag64( 0));
-      Assert.AreEqual(1, CodedOutputStream.EncodeZigZag64(-1));
-      Assert.AreEqual(2, CodedOutputStream.EncodeZigZag64( 1));
-      Assert.AreEqual(3, CodedOutputStream.EncodeZigZag64(-2));
-      Assert.AreEqual(0x000000007FFFFFFEL,
-                   CodedOutputStream.EncodeZigZag64(unchecked((long)0x000000003FFFFFFFUL)));
-      Assert.AreEqual(0x000000007FFFFFFFL,
-                   CodedOutputStream.EncodeZigZag64(unchecked((long)0xFFFFFFFFC0000000UL)));
-      Assert.AreEqual(0x00000000FFFFFFFEL,
-                   CodedOutputStream.EncodeZigZag64(unchecked((long)0x000000007FFFFFFFUL)));
-      Assert.AreEqual(0x00000000FFFFFFFFL,
-                   CodedOutputStream.EncodeZigZag64(unchecked((long)0xFFFFFFFF80000000UL)));
-      Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
-                   CodedOutputStream.EncodeZigZag64(unchecked((long)0x7FFFFFFFFFFFFFFFUL)));
-      Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
-                   CodedOutputStream.EncodeZigZag64(unchecked((long)0x8000000000000000UL)));
-    }
-
-    [Test]
-    public void RoundTripZigZag32() {
-      // Some easier-to-verify round-trip tests.  The inputs (other than 0, 1, -1)
-      // were chosen semi-randomly via keyboard bashing.
-      Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
-      Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
-      Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
-      Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
-      Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
-    }
-     
-    [Test]
-    public void RoundTripZigZag64() {
-      Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
-      Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
-      Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
-      Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
-      Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
-
-      Assert.AreEqual(856912304801416L, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
-      Assert.AreEqual(-75123905439571256L, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
-    }
-  }
-}
+#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 Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class CodedOutputStreamTest
+    {
+        /// <summary>
+        /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
+        /// checks that the result matches the given bytes
+        /// </summary>
+        private static void AssertWriteVarint(byte[] data, ulong value)
+        {
+            // Only do 32-bit write if the value fits in 32 bits.
+            if ((value >> 32) == 0)
+            {
+                MemoryStream rawOutput = new MemoryStream();
+                CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
+                output.WriteRawVarint32((uint) value);
+                output.Flush();
+                Assert.AreEqual(data, rawOutput.ToArray());
+                // Also try computing size.
+                Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
+            }
+
+            {
+                MemoryStream rawOutput = new MemoryStream();
+                CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
+                output.WriteRawVarint64(value);
+                output.Flush();
+                Assert.AreEqual(data, rawOutput.ToArray());
+
+                // Also try computing size.
+                Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
+            }
+
+            // Try different buffer sizes.
+            for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+            {
+                // Only do 32-bit write if the value fits in 32 bits.
+                if ((value >> 32) == 0)
+                {
+                    MemoryStream rawOutput = new MemoryStream();
+                    CodedOutputStream output =
+                        CodedOutputStream.CreateInstance(rawOutput, bufferSize);
+                    output.WriteRawVarint32((uint) value);
+                    output.Flush();
+                    Assert.AreEqual(data, rawOutput.ToArray());
+                }
+
+                {
+                    MemoryStream rawOutput = new MemoryStream();
+                    CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput, bufferSize);
+                    output.WriteRawVarint64(value);
+                    output.Flush();
+                    Assert.AreEqual(data, rawOutput.ToArray());
+                }
+            }
+        }
+
+        /// <summary>
+        /// Tests WriteRawVarint32() and WriteRawVarint64()
+        /// </summary>
+        [Test]
+        public void WriteVarint()
+        {
+            AssertWriteVarint(new byte[] {0x00}, 0);
+            AssertWriteVarint(new byte[] {0x01}, 1);
+            AssertWriteVarint(new byte[] {0x7f}, 127);
+            // 14882
+            AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
+            // 2961488830
+            AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
+                              (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+                              (0x0bL << 28));
+
+            // 64-bit
+            // 7256456126
+            AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
+                              (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+                              (0x1bL << 28));
+            // 41256202580718336
+            AssertWriteVarint(
+                new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
+                (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+                (0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
+            // 11964378330978735131
+            AssertWriteVarint(
+                new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
+                unchecked((ulong)
+                          ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+                           (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
+                           (0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
+        }
+
+        /// <summary>
+        /// Parses the given bytes using WriteRawLittleEndian32() and checks
+        /// that the result matches the given value.
+        /// </summary>
+        private static void AssertWriteLittleEndian32(byte[] data, uint value)
+        {
+            MemoryStream rawOutput = new MemoryStream();
+            CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
+            output.WriteRawLittleEndian32(value);
+            output.Flush();
+            Assert.AreEqual(data, rawOutput.ToArray());
+
+            // Try different buffer sizes.
+            for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+            {
+                rawOutput = new MemoryStream();
+                output = CodedOutputStream.CreateInstance(rawOutput, bufferSize);
+                output.WriteRawLittleEndian32(value);
+                output.Flush();
+                Assert.AreEqual(data, rawOutput.ToArray());
+            }
+        }
+
+        /// <summary>
+        /// Parses the given bytes using WriteRawLittleEndian64() and checks
+        /// that the result matches the given value.
+        /// </summary>
+        private static void AssertWriteLittleEndian64(byte[] data, ulong value)
+        {
+            MemoryStream rawOutput = new MemoryStream();
+            CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
+            output.WriteRawLittleEndian64(value);
+            output.Flush();
+            Assert.AreEqual(data, rawOutput.ToArray());
+
+            // Try different block sizes.
+            for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+            {
+                rawOutput = new MemoryStream();
+                output = CodedOutputStream.CreateInstance(rawOutput, blockSize);
+                output.WriteRawLittleEndian64(value);
+                output.Flush();
+                Assert.AreEqual(data, rawOutput.ToArray());
+            }
+        }
+
+        /// <summary>
+        /// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
+        /// </summary>
+        [Test]
+        public void WriteLittleEndian()
+        {
+            AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
+            AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
+
+            AssertWriteLittleEndian64(
+                new byte[] {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
+                0x123456789abcdef0L);
+            AssertWriteLittleEndian64(
+                new byte[] {0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
+                0x9abcdef012345678UL);
+        }
+
+        [Test]
+        public void WriteWholeMessage()
+        {
+            TestAllTypes message = TestUtil.GetAllSet();
+
+            byte[] rawBytes = message.ToByteArray();
+            TestUtil.AssertEqualBytes(TestUtil.GoldenMessage.ToByteArray(), rawBytes);
+
+            // Try different block sizes.
+            for (int blockSize = 1; blockSize < 256; blockSize *= 2)
+            {
+                MemoryStream rawOutput = new MemoryStream();
+                CodedOutputStream output =
+                    CodedOutputStream.CreateInstance(rawOutput, blockSize);
+                message.WriteTo(output);
+                output.Flush();
+                TestUtil.AssertEqualBytes(rawBytes, rawOutput.ToArray());
+            }
+        }
+
+        /// <summary>
+        /// Tests writing a whole message with every packed field type. Ensures the
+        /// wire format of packed fields is compatible with C++.
+        /// </summary>
+        [Test]
+        public void WriteWholePackedFieldsMessage()
+        {
+            TestPackedTypes message = TestUtil.GetPackedSet();
+
+            byte[] rawBytes = message.ToByteArray();
+            TestUtil.AssertEqualBytes(TestUtil.GetGoldenPackedFieldsMessage().ToByteArray(),
+                                      rawBytes);
+        }
+
+        [Test]
+        public void EncodeZigZag32()
+        {
+            Assert.AreEqual(0, CodedOutputStream.EncodeZigZag32(0));
+            Assert.AreEqual(1, CodedOutputStream.EncodeZigZag32(-1));
+            Assert.AreEqual(2, CodedOutputStream.EncodeZigZag32(1));
+            Assert.AreEqual(3, CodedOutputStream.EncodeZigZag32(-2));
+            Assert.AreEqual(0x7FFFFFFE, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
+            Assert.AreEqual(0x7FFFFFFF, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
+            Assert.AreEqual(0xFFFFFFFE, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
+            Assert.AreEqual(0xFFFFFFFF, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
+        }
+
+        [Test]
+        public void EncodeZigZag64()
+        {
+            Assert.AreEqual(0, CodedOutputStream.EncodeZigZag64(0));
+            Assert.AreEqual(1, CodedOutputStream.EncodeZigZag64(-1));
+            Assert.AreEqual(2, CodedOutputStream.EncodeZigZag64(1));
+            Assert.AreEqual(3, CodedOutputStream.EncodeZigZag64(-2));
+            Assert.AreEqual(0x000000007FFFFFFEL,
+                            CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
+            Assert.AreEqual(0x000000007FFFFFFFL,
+                            CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
+            Assert.AreEqual(0x00000000FFFFFFFEL,
+                            CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
+            Assert.AreEqual(0x00000000FFFFFFFFL,
+                            CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
+            Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
+                            CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
+            Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
+                            CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
+        }
+
+        [Test]
+        public void RoundTripZigZag32()
+        {
+            // Some easier-to-verify round-trip tests.  The inputs (other than 0, 1, -1)
+            // were chosen semi-randomly via keyboard bashing.
+            Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
+            Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
+            Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
+            Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
+            Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
+        }
+
+        [Test]
+        public void RoundTripZigZag64()
+        {
+            Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
+            Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
+            Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
+            Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
+            Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
+
+            Assert.AreEqual(856912304801416L,
+                            CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
+            Assert.AreEqual(-75123905439571256L,
+                            CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
+        }
+    }
+}

+ 110 - 100
src/ProtocolBuffers.Test/Collections/PopsicleListTest.cs

@@ -1,100 +1,110 @@
-#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 NUnit.Framework;
-
-delegate void Action();
-
-
-namespace Google.ProtocolBuffers.Collections {
-  [TestFixture]
-  public class PopsicleListTest {
-
-    [Test]
-    public void MutatingOperationsOnFrozenList() {
-      PopsicleList<string> list = new PopsicleList<string>();
-      list.MakeReadOnly();
-      AssertNotSupported(() => list.Add(""));
-      AssertNotSupported(() => list.Clear());
-      AssertNotSupported(() => list.Insert(0, ""));
-      AssertNotSupported(() => list.Remove(""));
-      AssertNotSupported(() => list.RemoveAt(0));
-      AssertNotSupported(() => list.Add(new[] {"", ""}));
-    }
-
-    [Test]
-    public void NonMutatingOperationsOnFrozenList() {
-      PopsicleList<string> list = new PopsicleList<string>();
-      list.MakeReadOnly();
-      Assert.IsFalse(list.Contains(""));
-      Assert.AreEqual(0, list.Count);
-      list.CopyTo(new string[5], 0);
-      list.GetEnumerator();
-      Assert.AreEqual(-1, list.IndexOf(""));
-      Assert.IsTrue(list.IsReadOnly);
-    }
-
-    [Test]
-    public void MutatingOperationsOnFluidList() {
-      PopsicleList<string> list = new PopsicleList<string>();
-      list.Add("");
-      list.Clear();
-      list.Insert(0, "");
-      list.Remove("");
-      list.Add("x"); // Just to make the next call valid
-      list.RemoveAt(0);
-    }
-
-    [Test]
-    public void NonMutatingOperationsOnFluidList() {
-      PopsicleList<string> list = new PopsicleList<string>();
-      Assert.IsFalse(list.Contains(""));
-      Assert.AreEqual(0, list.Count);
-      list.CopyTo(new string[5], 0);
-      list.GetEnumerator();
-      Assert.AreEqual(-1, list.IndexOf(""));
-      Assert.IsFalse(list.IsReadOnly);
-    }
-
-    private static void AssertNotSupported(Action action) {
-      try {
-        action();
-        Assert.Fail("Expected NotSupportedException");
-      } catch (NotSupportedException) {
-        // Expected
-      }
-    }
-  }
-}
+#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 NUnit.Framework;
+
+internal delegate void Action();
+
+namespace Google.ProtocolBuffers.Collections
+{
+    [TestFixture]
+    public class PopsicleListTest
+    {
+        [Test]
+        public void MutatingOperationsOnFrozenList()
+        {
+            PopsicleList<string> list = new PopsicleList<string>();
+            list.MakeReadOnly();
+            AssertNotSupported(() => list.Add(""));
+            AssertNotSupported(() => list.Clear());
+            AssertNotSupported(() => list.Insert(0, ""));
+            AssertNotSupported(() => list.Remove(""));
+            AssertNotSupported(() => list.RemoveAt(0));
+            AssertNotSupported(() => list.Add(new[] {"", ""}));
+        }
+
+        [Test]
+        public void NonMutatingOperationsOnFrozenList()
+        {
+            PopsicleList<string> list = new PopsicleList<string>();
+            list.MakeReadOnly();
+            Assert.IsFalse(list.Contains(""));
+            Assert.AreEqual(0, list.Count);
+            list.CopyTo(new string[5], 0);
+            list.GetEnumerator();
+            Assert.AreEqual(-1, list.IndexOf(""));
+            Assert.IsTrue(list.IsReadOnly);
+        }
+
+        [Test]
+        public void MutatingOperationsOnFluidList()
+        {
+            PopsicleList<string> list = new PopsicleList<string>();
+            list.Add("");
+            list.Clear();
+            list.Insert(0, "");
+            list.Remove("");
+            list.Add("x"); // Just to make the next call valid
+            list.RemoveAt(0);
+        }
+
+        [Test]
+        public void NonMutatingOperationsOnFluidList()
+        {
+            PopsicleList<string> list = new PopsicleList<string>();
+            Assert.IsFalse(list.Contains(""));
+            Assert.AreEqual(0, list.Count);
+            list.CopyTo(new string[5], 0);
+            list.GetEnumerator();
+            Assert.AreEqual(-1, list.IndexOf(""));
+            Assert.IsFalse(list.IsReadOnly);
+        }
+
+        private static void AssertNotSupported(Action action)
+        {
+            try
+            {
+                action();
+                Assert.Fail("Expected NotSupportedException");
+            }
+            catch (NotSupportedException)
+            {
+                // Expected
+            }
+        }
+    }
+}

+ 72 - 65
src/ProtocolBuffers.Test/Descriptors/MessageDescriptorTest.cs

@@ -1,65 +1,72 @@
-#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 NUnit.Framework;
-using Google.ProtocolBuffers.TestProtos;
-
-namespace Google.ProtocolBuffers.Descriptors {
-
-  [TestFixture]
-  public class MessageDescriptorTest {
-    [Test]
-    public void FindPropertyWithDefaultName() {
-      Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.NormalFieldNumber),
-          OptionsMessage.Descriptor.FindFieldByPropertyName("Normal"));
-    }
-
-    [Test]
-    public void FindPropertyWithAutoModifiedName() {
-      Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.OptionsMessage_FieldNumber),
-          OptionsMessage.Descriptor.FindFieldByPropertyName("OptionsMessage_"));
-    }
-
-    [Test]
-    public void FindPropertyWithCustomizedName() {
-      Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.CustomNameFieldNumber),
-          OptionsMessage.Descriptor.FindFieldByPropertyName("CustomName"));
-    }
-
-    [Test]
-    public void FindPropertyWithInvalidName() {
-      Assert.IsNull(OptionsMessage.Descriptor.FindFieldByPropertyName("Bogus"));
-    }
-  }
-}
+#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 NUnit.Framework;
+using Google.ProtocolBuffers.TestProtos;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    [TestFixture]
+    public class MessageDescriptorTest
+    {
+        [Test]
+        public void FindPropertyWithDefaultName()
+        {
+            Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.NormalFieldNumber),
+                           OptionsMessage.Descriptor.FindFieldByPropertyName("Normal"));
+        }
+
+        [Test]
+        public void FindPropertyWithAutoModifiedName()
+        {
+            Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.OptionsMessage_FieldNumber),
+                           OptionsMessage.Descriptor.FindFieldByPropertyName("OptionsMessage_"));
+        }
+
+        [Test]
+        public void FindPropertyWithCustomizedName()
+        {
+            Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.CustomNameFieldNumber),
+                           OptionsMessage.Descriptor.FindFieldByPropertyName("CustomName"));
+        }
+
+        [Test]
+        public void FindPropertyWithInvalidName()
+        {
+            Assert.IsNull(OptionsMessage.Descriptor.FindFieldByPropertyName("Bogus"));
+        }
+    }
+}

+ 350 - 325
src/ProtocolBuffers.Test/DescriptorsTest.cs

@@ -1,327 +1,352 @@
-#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;
-using Google.ProtocolBuffers.Descriptors;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the
-  /// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...)
-  /// </summary>
-  [TestFixture]
-  public class DescriptorsTest {
-    
-    [Test]
-    public void FileDescriptor()  {
-      FileDescriptor file = UnitTestProtoFile.Descriptor;
-
-      Assert.AreEqual("google/protobuf/unittest.proto", file.Name);
-      Assert.AreEqual("protobuf_unittest", file.Package);
-
-      Assert.AreEqual("UnittestProto", file.Options.JavaOuterClassname);
-      Assert.AreEqual("google/protobuf/unittest.proto", file.Proto.Name);
-
-// TODO(jonskeet): Either change to expect 2 dependencies, or don't emit them.
-//      Assert.AreEqual(2, file.Dependencies.Count);
-      Assert.AreEqual(UnitTestImportProtoFile.Descriptor, file.Dependencies[1]);
-
-      MessageDescriptor messageType = TestAllTypes.Descriptor;
-      Assert.AreEqual(messageType, file.MessageTypes[0]);
-      Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
-      Assert.IsNull(file.FindTypeByName<MessageDescriptor>("NoSuchType"));
-      Assert.IsNull(file.FindTypeByName<MessageDescriptor>("protobuf_unittest.TestAllTypes"));
-      for (int i = 0; i < file.MessageTypes.Count; i++) {
-        Assert.AreEqual(i, file.MessageTypes[i].Index);
-      }
-
-      Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum"));
-      Assert.IsNull(file.FindTypeByName<EnumDescriptor>("NoSuchType"));
-      Assert.IsNull(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum"));
-      Assert.AreEqual(1, UnitTestImportProtoFile.Descriptor.EnumTypes.Count);
-      Assert.AreEqual("ImportEnum", UnitTestImportProtoFile.Descriptor.EnumTypes[0].Name);
-      for (int i = 0; i < file.EnumTypes.Count; i++) {
-        Assert.AreEqual(i, file.EnumTypes[i].Index);
-      }
-
-      ServiceDescriptor service = TestGenericService.Descriptor;
-      Assert.AreEqual(service, UnitTestGenericServices.Descriptor.Services[0]);
-      Assert.AreEqual(service, UnitTestGenericServices.Descriptor.FindTypeByName<ServiceDescriptor>("TestGenericService"));
-      Assert.IsNull(UnitTestGenericServices.Descriptor.FindTypeByName<ServiceDescriptor>("NoSuchType"));
-      Assert.IsNull(UnitTestGenericServices.Descriptor.FindTypeByName<ServiceDescriptor>("protobuf_unittest.TestGenericService"));
-      Assert.AreEqual(0, UnitTestImportProtoFile.Descriptor.Services.Count);
-      for (int i = 0; i < file.Services.Count; i++) {
-        Assert.AreEqual(i, file.Services[i].Index);
-      }
-
-      FieldDescriptor extension = UnitTestProtoFile.OptionalInt32Extension.Descriptor;
-      Assert.AreEqual(extension, file.Extensions[0]);
-      Assert.AreEqual(extension, file.FindTypeByName<FieldDescriptor>("optional_int32_extension"));
-      Assert.IsNull(file.FindTypeByName<FieldDescriptor>("no_such_ext"));
-      Assert.IsNull(file.FindTypeByName<FieldDescriptor>("protobuf_unittest.optional_int32_extension"));
-      Assert.AreEqual(0, UnitTestImportProtoFile.Descriptor.Extensions.Count);
-      for (int i = 0; i < file.Extensions.Count; i++) {
-        Assert.AreEqual(i, file.Extensions[i].Index);
-      }
-    }
-
-    [Test]
-    public void MessageDescriptor() {
-      MessageDescriptor messageType = TestAllTypes.Descriptor;
-      MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor;
-
-      Assert.AreEqual("TestAllTypes", messageType.Name);
-      Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
-      Assert.AreEqual(UnitTestProtoFile.Descriptor, messageType.File);
-      Assert.IsNull(messageType.ContainingType);
-      Assert.AreEqual(DescriptorProtos.MessageOptions.DefaultInstance, messageType.Options);
-      Assert.AreEqual("TestAllTypes", messageType.Proto.Name);
-
-      Assert.AreEqual("NestedMessage", nestedType.Name);
-      Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName);
-      Assert.AreEqual(UnitTestProtoFile.Descriptor, nestedType.File);
-      Assert.AreEqual(messageType, nestedType.ContainingType);
-
-      FieldDescriptor field = messageType.Fields[0];
-      Assert.AreEqual("optional_int32", field.Name);
-      Assert.AreEqual(field, messageType.FindDescriptor<FieldDescriptor>("optional_int32"));
-      Assert.IsNull(messageType.FindDescriptor<FieldDescriptor>("no_such_field"));
-      Assert.AreEqual(field, messageType.FindFieldByNumber(1));
-      Assert.IsNull(messageType.FindFieldByNumber(571283));
-      for (int i = 0; i < messageType.Fields.Count; i++) {
-        Assert.AreEqual(i, messageType.Fields[i].Index);
-      }
-
-      Assert.AreEqual(nestedType, messageType.NestedTypes[0]);
-      Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage"));
-      Assert.IsNull(messageType.FindDescriptor<MessageDescriptor>("NoSuchType"));
-      for (int i = 0; i < messageType.NestedTypes.Count; i++) {
-        Assert.AreEqual(i, messageType.NestedTypes[i].Index);
-      }
-
-      Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum"));
-      Assert.IsNull(messageType.FindDescriptor<EnumDescriptor>("NoSuchType"));
-      for (int i = 0; i < messageType.EnumTypes.Count; i++) {
-        Assert.AreEqual(i, messageType.EnumTypes[i].Index);
-      }
-    }
-
-    [Test]
-    public void FieldDescriptor() {
-      MessageDescriptor messageType = TestAllTypes.Descriptor;
-      FieldDescriptor primitiveField = messageType.FindDescriptor<FieldDescriptor>("optional_int32");
-      FieldDescriptor enumField = messageType.FindDescriptor<FieldDescriptor>("optional_nested_enum");
-      FieldDescriptor messageField = messageType.FindDescriptor<FieldDescriptor>("optional_foreign_message");
-      FieldDescriptor cordField = messageType.FindDescriptor<FieldDescriptor>("optional_cord");
-      FieldDescriptor extension = UnitTestProtoFile.OptionalInt32Extension.Descriptor;
-      FieldDescriptor nestedExtension = TestRequired.Single.Descriptor;
-
-      Assert.AreEqual("optional_int32", primitiveField.Name);
-      Assert.AreEqual("protobuf_unittest.TestAllTypes.optional_int32",
-                   primitiveField.FullName);
-      Assert.AreEqual(1, primitiveField.FieldNumber);
-      Assert.AreEqual(messageType, primitiveField.ContainingType);
-      Assert.AreEqual(UnitTestProtoFile.Descriptor, primitiveField.File);
-      Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
-      Assert.AreEqual(MappedType.Int32, primitiveField.MappedType);
-      Assert.AreEqual(DescriptorProtos.FieldOptions.DefaultInstance, primitiveField.Options);
-      Assert.IsFalse(primitiveField.IsExtension);
-      Assert.AreEqual("optional_int32", primitiveField.Proto.Name);
-
-      Assert.AreEqual("optional_nested_enum", enumField.Name);
-      Assert.AreEqual(FieldType.Enum, enumField.FieldType);
-      Assert.AreEqual(MappedType.Enum, enumField.MappedType);
-      // Assert.AreEqual(TestAllTypes.Types.NestedEnum.Descriptor, enumField.EnumType);
-
-      Assert.AreEqual("optional_foreign_message", messageField.Name);
-      Assert.AreEqual(FieldType.Message, messageField.FieldType);
-      Assert.AreEqual(MappedType.Message, messageField.MappedType);
-      Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType);
-
-      Assert.AreEqual("optional_cord", cordField.Name);
-      Assert.AreEqual(FieldType.String, cordField.FieldType);
-      Assert.AreEqual(MappedType.String, cordField.MappedType);
-      Assert.AreEqual(DescriptorProtos.FieldOptions.Types.CType.CORD, cordField.Options.Ctype);
-
-      Assert.AreEqual("optional_int32_extension", extension.Name);
-      Assert.AreEqual("protobuf_unittest.optional_int32_extension", extension.FullName);
-      Assert.AreEqual(1, extension.FieldNumber);
-      Assert.AreEqual(TestAllExtensions.Descriptor, extension.ContainingType);
-      Assert.AreEqual(UnitTestProtoFile.Descriptor, extension.File);
-      Assert.AreEqual(FieldType.Int32, extension.FieldType);
-      Assert.AreEqual(MappedType.Int32, extension.MappedType);
-      Assert.AreEqual(DescriptorProtos.FieldOptions.DefaultInstance,
-                   extension.Options);
-      Assert.IsTrue(extension.IsExtension);
-      Assert.AreEqual(null, extension.ExtensionScope);
-      Assert.AreEqual("optional_int32_extension", extension.Proto.Name);
-
-      Assert.AreEqual("single", nestedExtension.Name);
-      Assert.AreEqual("protobuf_unittest.TestRequired.single",
-                   nestedExtension.FullName);
-      Assert.AreEqual(TestRequired.Descriptor,
-                   nestedExtension.ExtensionScope);
-    }
-
-    [Test]
-    public void FieldDescriptorLabel() {
-      FieldDescriptor requiredField =
-        TestRequired.Descriptor.FindDescriptor<FieldDescriptor>("a");
-      FieldDescriptor optionalField =
-        TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_int32");
-      FieldDescriptor repeatedField =
-        TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32");
-
-      Assert.IsTrue(requiredField.IsRequired);
-      Assert.IsFalse(requiredField.IsRepeated);
-      Assert.IsFalse(optionalField.IsRequired);
-      Assert.IsFalse(optionalField.IsRepeated);
-      Assert.IsFalse(repeatedField.IsRequired);
-      Assert.IsTrue(repeatedField.IsRepeated);
-    }
-
-    [Test]
-    public void FieldDescriptorDefault() {
-      MessageDescriptor d = TestAllTypes.Descriptor;
-      Assert.IsFalse(d.FindDescriptor<FieldDescriptor>("optional_int32").HasDefaultValue);
-      Assert.AreEqual(0, d.FindDescriptor<FieldDescriptor>("optional_int32").DefaultValue);
-      Assert.IsTrue(d.FindDescriptor<FieldDescriptor>("default_int32").HasDefaultValue);
-      Assert.AreEqual(41, d.FindDescriptor<FieldDescriptor>("default_int32").DefaultValue);
-
-      d = TestExtremeDefaultValues.Descriptor;
-      Assert.AreEqual(ByteString.CopyFrom("\u0000\u0001\u0007\b\f\n\r\t\u000b\\\'\"\u00fe", Encoding.GetEncoding(28591)),
-        d.FindDescriptor<FieldDescriptor>("escaped_bytes").DefaultValue);
-      Assert.AreEqual(uint.MaxValue, d.FindDescriptor<FieldDescriptor>("large_uint32").DefaultValue);
-      Assert.AreEqual(ulong.MaxValue, d.FindDescriptor<FieldDescriptor>("large_uint64").DefaultValue);
-    }
-
-    [Test]
-    public void EnumDescriptor()  {
-      // Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
-      EnumDescriptor enumType = UnitTestProtoFile.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
-      EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
-
-      Assert.AreEqual("ForeignEnum", enumType.Name);
-      Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName);
-      Assert.AreEqual(UnitTestProtoFile.Descriptor, enumType.File);
-      Assert.IsNull(enumType.ContainingType);
-      Assert.AreEqual(DescriptorProtos.EnumOptions.DefaultInstance,
-                   enumType.Options);
-
-      Assert.AreEqual("NestedEnum", nestedType.Name);
-      Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum",
-                   nestedType.FullName);
-      Assert.AreEqual(UnitTestProtoFile.Descriptor, nestedType.File);
-      Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
-
-      EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO");
-      Assert.AreEqual(value, enumType.Values[0]);
-      Assert.AreEqual("FOREIGN_FOO", value.Name);
-      Assert.AreEqual(4, value.Number);
-      Assert.AreEqual((int) ForeignEnum.FOREIGN_FOO, value.Number);
-      Assert.AreEqual(value, enumType.FindValueByNumber(4));
-      Assert.IsNull(enumType.FindValueByName("NO_SUCH_VALUE"));
-      for (int i = 0; i < enumType.Values.Count; i++) {
-        Assert.AreEqual(i, enumType.Values[i].Index);
-      }
-    }
-
-    [Test]
-    public void ServiceDescriptor() {
-      ServiceDescriptor service = TestGenericService.Descriptor;
-
-      Assert.AreEqual("TestGenericService", service.Name);
-      Assert.AreEqual("protobuf_unittest.TestGenericService", service.FullName);
-      Assert.AreEqual(UnitTestGenericServices.Descriptor, service.File);
-
-      Assert.AreEqual(2, service.Methods.Count);
-
-      MethodDescriptor fooMethod = service.Methods[0];
-      Assert.AreEqual("Foo", fooMethod.Name);
-      Assert.AreEqual(FooRequest.Descriptor, fooMethod.InputType);
-      Assert.AreEqual(FooResponse.Descriptor, fooMethod.OutputType);
-      Assert.AreEqual(fooMethod, service.FindMethodByName("Foo"));
-
-      MethodDescriptor barMethod = service.Methods[1];
-      Assert.AreEqual("Bar", barMethod.Name);
-      Assert.AreEqual(BarRequest.Descriptor, barMethod.InputType);
-      Assert.AreEqual(BarResponse.Descriptor, barMethod.OutputType);
-      Assert.AreEqual(barMethod, service.FindMethodByName("Bar"));
-
-      Assert.IsNull(service.FindMethodByName("NoSuchMethod"));
-
-      for (int i = 0; i < service.Methods.Count; i++) {
-        Assert.AreEqual(i, service.Methods[i].Index);
-      }
-    }
-
-    [Test]
-    public void CustomOptions() {
-      MessageDescriptor descriptor = TestMessageWithCustomOptions.Descriptor;
-      Assert.IsTrue(descriptor.Options.HasExtension(UnitTestCustomOptionsProtoFile.MessageOpt1));
-      Assert.AreEqual(-56, descriptor.Options.GetExtension(UnitTestCustomOptionsProtoFile.MessageOpt1));
-
-
-      FieldDescriptor field = descriptor.FindFieldByName("field1");
-      Assert.IsNotNull(field);
-
-      Assert.IsTrue(field.Options.HasExtension(UnitTestCustomOptionsProtoFile.FieldOpt1));
-      Assert.AreEqual(8765432109L, field.Options.GetExtension(UnitTestCustomOptionsProtoFile.FieldOpt1));
-
-      // TODO: Write out enum descriptors
-      /*
-      EnumDescriptor enumType = TestMessageWithCustomOptions.Types.
-        UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor();
-
-      Assert.IsTrue(
-        enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1));
-      Assert.AreEqual(Integer.valueOf(-789),
-        enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1));
+#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;
+using Google.ProtocolBuffers.Descriptors;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the
+    /// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...)
+    /// </summary>
+    [TestFixture]
+    public class DescriptorsTest
+    {
+        [Test]
+        public void FileDescriptor()
+        {
+            FileDescriptor file = UnitTestProtoFile.Descriptor;
+
+            Assert.AreEqual("google/protobuf/unittest.proto", file.Name);
+            Assert.AreEqual("protobuf_unittest", file.Package);
+
+            Assert.AreEqual("UnittestProto", file.Options.JavaOuterClassname);
+            Assert.AreEqual("google/protobuf/unittest.proto", file.Proto.Name);
+
+// TODO(jonskeet): Either change to expect 2 dependencies, or don't emit them.
+//      Assert.AreEqual(2, file.Dependencies.Count);
+            Assert.AreEqual(UnitTestImportProtoFile.Descriptor, file.Dependencies[1]);
+
+            MessageDescriptor messageType = TestAllTypes.Descriptor;
+            Assert.AreEqual(messageType, file.MessageTypes[0]);
+            Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
+            Assert.IsNull(file.FindTypeByName<MessageDescriptor>("NoSuchType"));
+            Assert.IsNull(file.FindTypeByName<MessageDescriptor>("protobuf_unittest.TestAllTypes"));
+            for (int i = 0; i < file.MessageTypes.Count; i++)
+            {
+                Assert.AreEqual(i, file.MessageTypes[i].Index);
+            }
+
+            Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum"));
+            Assert.IsNull(file.FindTypeByName<EnumDescriptor>("NoSuchType"));
+            Assert.IsNull(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum"));
+            Assert.AreEqual(1, UnitTestImportProtoFile.Descriptor.EnumTypes.Count);
+            Assert.AreEqual("ImportEnum", UnitTestImportProtoFile.Descriptor.EnumTypes[0].Name);
+            for (int i = 0; i < file.EnumTypes.Count; i++)
+            {
+                Assert.AreEqual(i, file.EnumTypes[i].Index);
+            }
+
+            ServiceDescriptor service = TestGenericService.Descriptor;
+            Assert.AreEqual(service, UnitTestGenericServices.Descriptor.Services[0]);
+            Assert.AreEqual(service,
+                            UnitTestGenericServices.Descriptor.FindTypeByName<ServiceDescriptor>("TestGenericService"));
+            Assert.IsNull(UnitTestGenericServices.Descriptor.FindTypeByName<ServiceDescriptor>("NoSuchType"));
+            Assert.IsNull(
+                UnitTestGenericServices.Descriptor.FindTypeByName<ServiceDescriptor>(
+                    "protobuf_unittest.TestGenericService"));
+            Assert.AreEqual(0, UnitTestImportProtoFile.Descriptor.Services.Count);
+            for (int i = 0; i < file.Services.Count; i++)
+            {
+                Assert.AreEqual(i, file.Services[i].Index);
+            }
+
+            FieldDescriptor extension = UnitTestProtoFile.OptionalInt32Extension.Descriptor;
+            Assert.AreEqual(extension, file.Extensions[0]);
+            Assert.AreEqual(extension, file.FindTypeByName<FieldDescriptor>("optional_int32_extension"));
+            Assert.IsNull(file.FindTypeByName<FieldDescriptor>("no_such_ext"));
+            Assert.IsNull(file.FindTypeByName<FieldDescriptor>("protobuf_unittest.optional_int32_extension"));
+            Assert.AreEqual(0, UnitTestImportProtoFile.Descriptor.Extensions.Count);
+            for (int i = 0; i < file.Extensions.Count; i++)
+            {
+                Assert.AreEqual(i, file.Extensions[i].Index);
+            }
+        }
+
+        [Test]
+        public void MessageDescriptor()
+        {
+            MessageDescriptor messageType = TestAllTypes.Descriptor;
+            MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor;
+
+            Assert.AreEqual("TestAllTypes", messageType.Name);
+            Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
+            Assert.AreEqual(UnitTestProtoFile.Descriptor, messageType.File);
+            Assert.IsNull(messageType.ContainingType);
+            Assert.AreEqual(DescriptorProtos.MessageOptions.DefaultInstance, messageType.Options);
+            Assert.AreEqual("TestAllTypes", messageType.Proto.Name);
+
+            Assert.AreEqual("NestedMessage", nestedType.Name);
+            Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName);
+            Assert.AreEqual(UnitTestProtoFile.Descriptor, nestedType.File);
+            Assert.AreEqual(messageType, nestedType.ContainingType);
+
+            FieldDescriptor field = messageType.Fields[0];
+            Assert.AreEqual("optional_int32", field.Name);
+            Assert.AreEqual(field, messageType.FindDescriptor<FieldDescriptor>("optional_int32"));
+            Assert.IsNull(messageType.FindDescriptor<FieldDescriptor>("no_such_field"));
+            Assert.AreEqual(field, messageType.FindFieldByNumber(1));
+            Assert.IsNull(messageType.FindFieldByNumber(571283));
+            for (int i = 0; i < messageType.Fields.Count; i++)
+            {
+                Assert.AreEqual(i, messageType.Fields[i].Index);
+            }
+
+            Assert.AreEqual(nestedType, messageType.NestedTypes[0]);
+            Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage"));
+            Assert.IsNull(messageType.FindDescriptor<MessageDescriptor>("NoSuchType"));
+            for (int i = 0; i < messageType.NestedTypes.Count; i++)
+            {
+                Assert.AreEqual(i, messageType.NestedTypes[i].Index);
+            }
+
+            Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum"));
+            Assert.IsNull(messageType.FindDescriptor<EnumDescriptor>("NoSuchType"));
+            for (int i = 0; i < messageType.EnumTypes.Count; i++)
+            {
+                Assert.AreEqual(i, messageType.EnumTypes[i].Index);
+            }
+        }
+
+        [Test]
+        public void FieldDescriptor()
+        {
+            MessageDescriptor messageType = TestAllTypes.Descriptor;
+            FieldDescriptor primitiveField = messageType.FindDescriptor<FieldDescriptor>("optional_int32");
+            FieldDescriptor enumField = messageType.FindDescriptor<FieldDescriptor>("optional_nested_enum");
+            FieldDescriptor messageField = messageType.FindDescriptor<FieldDescriptor>("optional_foreign_message");
+            FieldDescriptor cordField = messageType.FindDescriptor<FieldDescriptor>("optional_cord");
+            FieldDescriptor extension = UnitTestProtoFile.OptionalInt32Extension.Descriptor;
+            FieldDescriptor nestedExtension = TestRequired.Single.Descriptor;
+
+            Assert.AreEqual("optional_int32", primitiveField.Name);
+            Assert.AreEqual("protobuf_unittest.TestAllTypes.optional_int32",
+                            primitiveField.FullName);
+            Assert.AreEqual(1, primitiveField.FieldNumber);
+            Assert.AreEqual(messageType, primitiveField.ContainingType);
+            Assert.AreEqual(UnitTestProtoFile.Descriptor, primitiveField.File);
+            Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
+            Assert.AreEqual(MappedType.Int32, primitiveField.MappedType);
+            Assert.AreEqual(DescriptorProtos.FieldOptions.DefaultInstance, primitiveField.Options);
+            Assert.IsFalse(primitiveField.IsExtension);
+            Assert.AreEqual("optional_int32", primitiveField.Proto.Name);
+
+            Assert.AreEqual("optional_nested_enum", enumField.Name);
+            Assert.AreEqual(FieldType.Enum, enumField.FieldType);
+            Assert.AreEqual(MappedType.Enum, enumField.MappedType);
+            // Assert.AreEqual(TestAllTypes.Types.NestedEnum.Descriptor, enumField.EnumType);
+
+            Assert.AreEqual("optional_foreign_message", messageField.Name);
+            Assert.AreEqual(FieldType.Message, messageField.FieldType);
+            Assert.AreEqual(MappedType.Message, messageField.MappedType);
+            Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType);
+
+            Assert.AreEqual("optional_cord", cordField.Name);
+            Assert.AreEqual(FieldType.String, cordField.FieldType);
+            Assert.AreEqual(MappedType.String, cordField.MappedType);
+            Assert.AreEqual(DescriptorProtos.FieldOptions.Types.CType.CORD, cordField.Options.Ctype);
+
+            Assert.AreEqual("optional_int32_extension", extension.Name);
+            Assert.AreEqual("protobuf_unittest.optional_int32_extension", extension.FullName);
+            Assert.AreEqual(1, extension.FieldNumber);
+            Assert.AreEqual(TestAllExtensions.Descriptor, extension.ContainingType);
+            Assert.AreEqual(UnitTestProtoFile.Descriptor, extension.File);
+            Assert.AreEqual(FieldType.Int32, extension.FieldType);
+            Assert.AreEqual(MappedType.Int32, extension.MappedType);
+            Assert.AreEqual(DescriptorProtos.FieldOptions.DefaultInstance,
+                            extension.Options);
+            Assert.IsTrue(extension.IsExtension);
+            Assert.AreEqual(null, extension.ExtensionScope);
+            Assert.AreEqual("optional_int32_extension", extension.Proto.Name);
+
+            Assert.AreEqual("single", nestedExtension.Name);
+            Assert.AreEqual("protobuf_unittest.TestRequired.single",
+                            nestedExtension.FullName);
+            Assert.AreEqual(TestRequired.Descriptor,
+                            nestedExtension.ExtensionScope);
+        }
+
+        [Test]
+        public void FieldDescriptorLabel()
+        {
+            FieldDescriptor requiredField =
+                TestRequired.Descriptor.FindDescriptor<FieldDescriptor>("a");
+            FieldDescriptor optionalField =
+                TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_int32");
+            FieldDescriptor repeatedField =
+                TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32");
+
+            Assert.IsTrue(requiredField.IsRequired);
+            Assert.IsFalse(requiredField.IsRepeated);
+            Assert.IsFalse(optionalField.IsRequired);
+            Assert.IsFalse(optionalField.IsRepeated);
+            Assert.IsFalse(repeatedField.IsRequired);
+            Assert.IsTrue(repeatedField.IsRepeated);
+        }
+
+        [Test]
+        public void FieldDescriptorDefault()
+        {
+            MessageDescriptor d = TestAllTypes.Descriptor;
+            Assert.IsFalse(d.FindDescriptor<FieldDescriptor>("optional_int32").HasDefaultValue);
+            Assert.AreEqual(0, d.FindDescriptor<FieldDescriptor>("optional_int32").DefaultValue);
+            Assert.IsTrue(d.FindDescriptor<FieldDescriptor>("default_int32").HasDefaultValue);
+            Assert.AreEqual(41, d.FindDescriptor<FieldDescriptor>("default_int32").DefaultValue);
+
+            d = TestExtremeDefaultValues.Descriptor;
+            Assert.AreEqual(
+                ByteString.CopyFrom("\u0000\u0001\u0007\b\f\n\r\t\u000b\\\'\"\u00fe", Encoding.GetEncoding(28591)),
+                d.FindDescriptor<FieldDescriptor>("escaped_bytes").DefaultValue);
+            Assert.AreEqual(uint.MaxValue, d.FindDescriptor<FieldDescriptor>("large_uint32").DefaultValue);
+            Assert.AreEqual(ulong.MaxValue, d.FindDescriptor<FieldDescriptor>("large_uint64").DefaultValue);
+        }
+
+        [Test]
+        public void EnumDescriptor()
+        {
+            // Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
+            EnumDescriptor enumType = UnitTestProtoFile.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
+            EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
+
+            Assert.AreEqual("ForeignEnum", enumType.Name);
+            Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName);
+            Assert.AreEqual(UnitTestProtoFile.Descriptor, enumType.File);
+            Assert.IsNull(enumType.ContainingType);
+            Assert.AreEqual(DescriptorProtos.EnumOptions.DefaultInstance,
+                            enumType.Options);
+
+            Assert.AreEqual("NestedEnum", nestedType.Name);
+            Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum",
+                            nestedType.FullName);
+            Assert.AreEqual(UnitTestProtoFile.Descriptor, nestedType.File);
+            Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
+
+            EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO");
+            Assert.AreEqual(value, enumType.Values[0]);
+            Assert.AreEqual("FOREIGN_FOO", value.Name);
+            Assert.AreEqual(4, value.Number);
+            Assert.AreEqual((int) ForeignEnum.FOREIGN_FOO, value.Number);
+            Assert.AreEqual(value, enumType.FindValueByNumber(4));
+            Assert.IsNull(enumType.FindValueByName("NO_SUCH_VALUE"));
+            for (int i = 0; i < enumType.Values.Count; i++)
+            {
+                Assert.AreEqual(i, enumType.Values[i].Index);
+            }
+        }
+
+        [Test]
+        public void ServiceDescriptor()
+        {
+            ServiceDescriptor service = TestGenericService.Descriptor;
+
+            Assert.AreEqual("TestGenericService", service.Name);
+            Assert.AreEqual("protobuf_unittest.TestGenericService", service.FullName);
+            Assert.AreEqual(UnitTestGenericServices.Descriptor, service.File);
+
+            Assert.AreEqual(2, service.Methods.Count);
+
+            MethodDescriptor fooMethod = service.Methods[0];
+            Assert.AreEqual("Foo", fooMethod.Name);
+            Assert.AreEqual(FooRequest.Descriptor, fooMethod.InputType);
+            Assert.AreEqual(FooResponse.Descriptor, fooMethod.OutputType);
+            Assert.AreEqual(fooMethod, service.FindMethodByName("Foo"));
+
+            MethodDescriptor barMethod = service.Methods[1];
+            Assert.AreEqual("Bar", barMethod.Name);
+            Assert.AreEqual(BarRequest.Descriptor, barMethod.InputType);
+            Assert.AreEqual(BarResponse.Descriptor, barMethod.OutputType);
+            Assert.AreEqual(barMethod, service.FindMethodByName("Bar"));
+
+            Assert.IsNull(service.FindMethodByName("NoSuchMethod"));
+
+            for (int i = 0; i < service.Methods.Count; i++)
+            {
+                Assert.AreEqual(i, service.Methods[i].Index);
+            }
+        }
+
+        [Test]
+        public void CustomOptions()
+        {
+            MessageDescriptor descriptor = TestMessageWithCustomOptions.Descriptor;
+            Assert.IsTrue(descriptor.Options.HasExtension(UnitTestCustomOptionsProtoFile.MessageOpt1));
+            Assert.AreEqual(-56, descriptor.Options.GetExtension(UnitTestCustomOptionsProtoFile.MessageOpt1));
+
+
+            FieldDescriptor field = descriptor.FindFieldByName("field1");
+            Assert.IsNotNull(field);
+
+            Assert.IsTrue(field.Options.HasExtension(UnitTestCustomOptionsProtoFile.FieldOpt1));
+            Assert.AreEqual(8765432109L, field.Options.GetExtension(UnitTestCustomOptionsProtoFile.FieldOpt1));
+
+            // TODO: Write out enum descriptors
+            /*
+      EnumDescriptor enumType = TestMessageWithCustomOptions.Types.
+        UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor();
+
+      Assert.IsTrue(
+        enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1));
+      Assert.AreEqual(Integer.valueOf(-789),
+        enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1));
         */
 
-      ServiceDescriptor service = TestGenericServiceWithCustomOptions.Descriptor;
-
-      Assert.IsTrue(service.Options.HasExtension(UnitTestCustomOptionsProtoFile.ServiceOpt1));
-      Assert.AreEqual(-9876543210L, service.Options.GetExtension(UnitTestCustomOptionsProtoFile.ServiceOpt1));
-
-      MethodDescriptor method = service.FindMethodByName("Foo");
-      Assert.IsNotNull(method);
-
-      Assert.IsTrue(method.Options.HasExtension(UnitTestCustomOptionsProtoFile.MethodOpt1));
-      Assert.AreEqual(MethodOpt1.METHODOPT1_VAL2, method.Options.GetExtension(UnitTestCustomOptionsProtoFile.MethodOpt1));
-    }
-  }
-}
+            ServiceDescriptor service = TestGenericServiceWithCustomOptions.Descriptor;
+
+            Assert.IsTrue(service.Options.HasExtension(UnitTestCustomOptionsProtoFile.ServiceOpt1));
+            Assert.AreEqual(-9876543210L, service.Options.GetExtension(UnitTestCustomOptionsProtoFile.ServiceOpt1));
+
+            MethodDescriptor method = service.FindMethodByName("Foo");
+            Assert.IsNotNull(method);
+
+            Assert.IsTrue(method.Options.HasExtension(UnitTestCustomOptionsProtoFile.MethodOpt1));
+            Assert.AreEqual(MethodOpt1.METHODOPT1_VAL2,
+                            method.Options.GetExtension(UnitTestCustomOptionsProtoFile.MethodOpt1));
+        }
+    }
+}

+ 237 - 215
src/ProtocolBuffers.Test/DynamicMessageTest.cs

@@ -1,215 +1,237 @@
-#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.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class DynamicMessageTest {
-
-    private ReflectionTester reflectionTester;
-    private ReflectionTester extensionsReflectionTester;
-    private ReflectionTester packedReflectionTester;
-
-    [SetUp]
-    public void SetUp() {
-      reflectionTester = ReflectionTester.CreateTestAllTypesInstance();
-      extensionsReflectionTester = ReflectionTester.CreateTestAllExtensionsInstance();
-      packedReflectionTester = ReflectionTester.CreateTestPackedTypesInstance();
-    }
-
-    [Test]
-    public void DynamicMessageAccessors() {
-      IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
-      reflectionTester.SetAllFieldsViaReflection(builder);
-      IMessage message = builder.WeakBuild();
-      reflectionTester.AssertAllFieldsSetViaReflection(message);
-    }
-
-    [Test]
-    public void DoubleBuildError() {
-      DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
-      builder.Build();
-      try {
-        builder.Build();
-        Assert.Fail("Should have thrown exception.");
-      } catch (InvalidOperationException) {
-        // Success.
-      }
-    }
-
-    [Test]
-    public void DynamicMessageSettersRejectNull() {
-      IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
-      reflectionTester.AssertReflectionSettersRejectNull(builder);
-      }
-
-    [Test]
-    public void DynamicMessageExtensionAccessors() {
-      // We don't need to extensively test DynamicMessage's handling of
-      // extensions because, frankly, it doesn't do anything special with them.
-      // It treats them just like any other fields.
-      IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
-      extensionsReflectionTester.SetAllFieldsViaReflection(builder);
-      IMessage message = builder.WeakBuild();
-      extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
-    }
-
-    [Test]
-    public void DynamicMessageExtensionSettersRejectNull() {
-      IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
-      extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
-      }
-
-    [Test]
-    public void DynamicMessageRepeatedSetters() {
-      IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
-      reflectionTester.SetAllFieldsViaReflection(builder);
-      reflectionTester.ModifyRepeatedFieldsViaReflection(builder);
-      IMessage message = builder.WeakBuild();
-      reflectionTester.AssertRepeatedFieldsModifiedViaReflection(message);
-    }
-
-    [Test]
-    public void DynamicMessageRepeatedSettersRejectNull() {
-      IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
-      reflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
-    }
-
-    [Test]
-    public void DynamicMessageDefaults() {
-      reflectionTester.AssertClearViaReflection(DynamicMessage.GetDefaultInstance(TestAllTypes.Descriptor));
-      reflectionTester.AssertClearViaReflection(DynamicMessage.CreateBuilder(TestAllTypes.Descriptor).Build());
-    }
-
-    [Test]
-    public void DynamicMessageSerializedSize() {
-      TestAllTypes message = TestUtil.GetAllSet();
-
-      IBuilder dynamicBuilder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
-      reflectionTester.SetAllFieldsViaReflection(dynamicBuilder);
-      IMessage dynamicMessage = dynamicBuilder.WeakBuild();
-
-      Assert.AreEqual(message.SerializedSize, dynamicMessage.SerializedSize);
-    }
-
-    [Test]
-    public void DynamicMessageSerialization() {
-      IBuilder builder =  DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
-      reflectionTester.SetAllFieldsViaReflection(builder);
-      IMessage message = builder.WeakBuild();
-
-      ByteString rawBytes = message.ToByteString();
-      TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
-
-      TestUtil.AssertAllFieldsSet(message2);
-
-      // In fact, the serialized forms should be exactly the same, byte-for-byte.
-      Assert.AreEqual(TestUtil.GetAllSet().ToByteString(), rawBytes);
-    }
-
-    [Test]
-    public void DynamicMessageParsing() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TestUtil.SetAllFields(builder);
-      TestAllTypes message = builder.Build();
-
-      ByteString rawBytes = message.ToByteString();
-
-      IMessage message2 = DynamicMessage.ParseFrom(TestAllTypes.Descriptor, rawBytes);
-      reflectionTester.AssertAllFieldsSetViaReflection(message2);
-    }
-
-    [Test]
-      public void DynamicMessagePackedSerialization() {
-    IBuilder builder = DynamicMessage.CreateBuilder(TestPackedTypes.Descriptor);
-    packedReflectionTester.SetPackedFieldsViaReflection(builder);
-    IMessage message = builder.WeakBuild();
-
-    ByteString rawBytes = message.ToByteString();
-    TestPackedTypes message2 = TestPackedTypes.ParseFrom(rawBytes);
-
-    TestUtil.AssertPackedFieldsSet(message2);
-
-    // In fact, the serialized forms should be exactly the same, byte-for-byte.
-    Assert.AreEqual(TestUtil.GetPackedSet().ToByteString(), rawBytes);
-    }
-
-    [Test]
-  public void testDynamicMessagePackedParsing() {
-    TestPackedTypes.Builder builder = TestPackedTypes.CreateBuilder();
-    TestUtil.SetPackedFields(builder);
-    TestPackedTypes message = builder.Build();
-
-    ByteString rawBytes = message.ToByteString();
-
-    IMessage message2 = DynamicMessage.ParseFrom(TestPackedTypes.Descriptor, rawBytes);
-    packedReflectionTester.AssertPackedFieldsSetViaReflection(message2);
-  }
-
-    [Test]
-    public void DynamicMessageCopy() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TestUtil.SetAllFields(builder);
-      TestAllTypes message = builder.Build();
-
-      DynamicMessage copy = DynamicMessage.CreateBuilder(message).Build();
-      reflectionTester.AssertAllFieldsSetViaReflection(copy);
-    }
-
-    [Test]
-    public void ToBuilder() {
-      DynamicMessage.Builder builder =
-          DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
-      reflectionTester.SetAllFieldsViaReflection(builder);
-      int unknownFieldNum = 9;
-      ulong unknownFieldVal = 90;
-      builder.SetUnknownFields(UnknownFieldSet.CreateBuilder()
-          .AddField(unknownFieldNum,
-              UnknownField.CreateBuilder().AddVarint(unknownFieldVal).Build())
-          .Build());
-      DynamicMessage message = builder.Build();
-
-      DynamicMessage derived = message.ToBuilder().Build();
-      reflectionTester.AssertAllFieldsSetViaReflection(derived);
-
-      IList<ulong> values = derived.UnknownFields.FieldDictionary[unknownFieldNum].VarintList;
-      Assert.AreEqual(1, values.Count);
-      Assert.AreEqual(unknownFieldVal, values[0]);
-    }
-  }
-}
+#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.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class DynamicMessageTest
+    {
+        private ReflectionTester reflectionTester;
+        private ReflectionTester extensionsReflectionTester;
+        private ReflectionTester packedReflectionTester;
+
+        [SetUp]
+        public void SetUp()
+        {
+            reflectionTester = ReflectionTester.CreateTestAllTypesInstance();
+            extensionsReflectionTester = ReflectionTester.CreateTestAllExtensionsInstance();
+            packedReflectionTester = ReflectionTester.CreateTestPackedTypesInstance();
+        }
+
+        [Test]
+        public void DynamicMessageAccessors()
+        {
+            IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
+            reflectionTester.SetAllFieldsViaReflection(builder);
+            IMessage message = builder.WeakBuild();
+            reflectionTester.AssertAllFieldsSetViaReflection(message);
+        }
+
+        [Test]
+        public void DoubleBuildError()
+        {
+            DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
+            builder.Build();
+            try
+            {
+                builder.Build();
+                Assert.Fail("Should have thrown exception.");
+            }
+            catch (InvalidOperationException)
+            {
+                // Success.
+            }
+        }
+
+        [Test]
+        public void DynamicMessageSettersRejectNull()
+        {
+            IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
+            reflectionTester.AssertReflectionSettersRejectNull(builder);
+        }
+
+        [Test]
+        public void DynamicMessageExtensionAccessors()
+        {
+            // We don't need to extensively test DynamicMessage's handling of
+            // extensions because, frankly, it doesn't do anything special with them.
+            // It treats them just like any other fields.
+            IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
+            extensionsReflectionTester.SetAllFieldsViaReflection(builder);
+            IMessage message = builder.WeakBuild();
+            extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
+        }
+
+        [Test]
+        public void DynamicMessageExtensionSettersRejectNull()
+        {
+            IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
+            extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
+        }
+
+        [Test]
+        public void DynamicMessageRepeatedSetters()
+        {
+            IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
+            reflectionTester.SetAllFieldsViaReflection(builder);
+            reflectionTester.ModifyRepeatedFieldsViaReflection(builder);
+            IMessage message = builder.WeakBuild();
+            reflectionTester.AssertRepeatedFieldsModifiedViaReflection(message);
+        }
+
+        [Test]
+        public void DynamicMessageRepeatedSettersRejectNull()
+        {
+            IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
+            reflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
+        }
+
+        [Test]
+        public void DynamicMessageDefaults()
+        {
+            reflectionTester.AssertClearViaReflection(DynamicMessage.GetDefaultInstance(TestAllTypes.Descriptor));
+            reflectionTester.AssertClearViaReflection(DynamicMessage.CreateBuilder(TestAllTypes.Descriptor).Build());
+        }
+
+        [Test]
+        public void DynamicMessageSerializedSize()
+        {
+            TestAllTypes message = TestUtil.GetAllSet();
+
+            IBuilder dynamicBuilder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
+            reflectionTester.SetAllFieldsViaReflection(dynamicBuilder);
+            IMessage dynamicMessage = dynamicBuilder.WeakBuild();
+
+            Assert.AreEqual(message.SerializedSize, dynamicMessage.SerializedSize);
+        }
+
+        [Test]
+        public void DynamicMessageSerialization()
+        {
+            IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
+            reflectionTester.SetAllFieldsViaReflection(builder);
+            IMessage message = builder.WeakBuild();
+
+            ByteString rawBytes = message.ToByteString();
+            TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
+
+            TestUtil.AssertAllFieldsSet(message2);
+
+            // In fact, the serialized forms should be exactly the same, byte-for-byte.
+            Assert.AreEqual(TestUtil.GetAllSet().ToByteString(), rawBytes);
+        }
+
+        [Test]
+        public void DynamicMessageParsing()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TestUtil.SetAllFields(builder);
+            TestAllTypes message = builder.Build();
+
+            ByteString rawBytes = message.ToByteString();
+
+            IMessage message2 = DynamicMessage.ParseFrom(TestAllTypes.Descriptor, rawBytes);
+            reflectionTester.AssertAllFieldsSetViaReflection(message2);
+        }
+
+        [Test]
+        public void DynamicMessagePackedSerialization()
+        {
+            IBuilder builder = DynamicMessage.CreateBuilder(TestPackedTypes.Descriptor);
+            packedReflectionTester.SetPackedFieldsViaReflection(builder);
+            IMessage message = builder.WeakBuild();
+
+            ByteString rawBytes = message.ToByteString();
+            TestPackedTypes message2 = TestPackedTypes.ParseFrom(rawBytes);
+
+            TestUtil.AssertPackedFieldsSet(message2);
+
+            // In fact, the serialized forms should be exactly the same, byte-for-byte.
+            Assert.AreEqual(TestUtil.GetPackedSet().ToByteString(), rawBytes);
+        }
+
+        [Test]
+        public void testDynamicMessagePackedParsing()
+        {
+            TestPackedTypes.Builder builder = TestPackedTypes.CreateBuilder();
+            TestUtil.SetPackedFields(builder);
+            TestPackedTypes message = builder.Build();
+
+            ByteString rawBytes = message.ToByteString();
+
+            IMessage message2 = DynamicMessage.ParseFrom(TestPackedTypes.Descriptor, rawBytes);
+            packedReflectionTester.AssertPackedFieldsSetViaReflection(message2);
+        }
+
+        [Test]
+        public void DynamicMessageCopy()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TestUtil.SetAllFields(builder);
+            TestAllTypes message = builder.Build();
+
+            DynamicMessage copy = DynamicMessage.CreateBuilder(message).Build();
+            reflectionTester.AssertAllFieldsSetViaReflection(copy);
+        }
+
+        [Test]
+        public void ToBuilder()
+        {
+            DynamicMessage.Builder builder =
+                DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
+            reflectionTester.SetAllFieldsViaReflection(builder);
+            int unknownFieldNum = 9;
+            ulong unknownFieldVal = 90;
+            builder.SetUnknownFields(UnknownFieldSet.CreateBuilder()
+                                         .AddField(unknownFieldNum,
+                                                   UnknownField.CreateBuilder().AddVarint(unknownFieldVal).Build())
+                                         .Build());
+            DynamicMessage message = builder.Build();
+
+            DynamicMessage derived = message.ToBuilder().Build();
+            reflectionTester.AssertAllFieldsSetViaReflection(derived);
+
+            IList<ulong> values = derived.UnknownFields.FieldDictionary[unknownFieldNum].VarintList;
+            Assert.AreEqual(1, values.Count);
+            Assert.AreEqual(unknownFieldVal, values[0]);
+        }
+    }
+}

+ 202 - 192
src/ProtocolBuffers.Test/ExtendableMessageTest.cs

@@ -1,192 +1,202 @@
-#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 ExtendableMessageTest {
-
-    [Test, ExpectedException(typeof(ArgumentException))]
-    public void ExtensionWriterInvalidExtension() {
-      TestPackedExtensions.CreateBuilder()[UnitTestProtoFile.OptionalForeignMessageExtension.Descriptor] =
-        ForeignMessage.DefaultInstance;
-    }
-
-    [Test]
-    public void ExtensionWriterTest() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder()
-        .SetExtension(UnitTestProtoFile.DefaultBoolExtension, true)
-        .SetExtension(UnitTestProtoFile.DefaultBytesExtension, ByteString.CopyFromUtf8("123"))
-        .SetExtension(UnitTestProtoFile.DefaultCordExtension, "123")
-        .SetExtension(UnitTestProtoFile.DefaultDoubleExtension, 123)
-        .SetExtension(UnitTestProtoFile.DefaultFixed32Extension, 123u)
-        .SetExtension(UnitTestProtoFile.DefaultFixed64Extension, 123u)
-        .SetExtension(UnitTestProtoFile.DefaultFloatExtension, 123)
-        .SetExtension(UnitTestProtoFile.DefaultForeignEnumExtension, ForeignEnum.FOREIGN_BAZ)
-        .SetExtension(UnitTestProtoFile.DefaultImportEnumExtension, ImportEnum.IMPORT_BAZ)
-        .SetExtension(UnitTestProtoFile.DefaultInt32Extension, 123)
-        .SetExtension(UnitTestProtoFile.DefaultInt64Extension, 123)
-        .SetExtension(UnitTestProtoFile.DefaultNestedEnumExtension, TestAllTypes.Types.NestedEnum.FOO)
-        .SetExtension(UnitTestProtoFile.DefaultSfixed32Extension, 123)
-        .SetExtension(UnitTestProtoFile.DefaultSfixed64Extension, 123)
-        .SetExtension(UnitTestProtoFile.DefaultSint32Extension, 123)
-        .SetExtension(UnitTestProtoFile.DefaultSint64Extension, 123)
-        .SetExtension(UnitTestProtoFile.DefaultStringExtension, "123")
-        .SetExtension(UnitTestProtoFile.DefaultStringPieceExtension, "123")
-        .SetExtension(UnitTestProtoFile.DefaultUint32Extension, 123u)
-        .SetExtension(UnitTestProtoFile.DefaultUint64Extension, 123u)
-        //Optional
-        .SetExtension(UnitTestProtoFile.OptionalBoolExtension, true)
-        .SetExtension(UnitTestProtoFile.OptionalBytesExtension, ByteString.CopyFromUtf8("123"))
-        .SetExtension(UnitTestProtoFile.OptionalCordExtension, "123")
-        .SetExtension(UnitTestProtoFile.OptionalDoubleExtension, 123)
-        .SetExtension(UnitTestProtoFile.OptionalFixed32Extension, 123u)
-        .SetExtension(UnitTestProtoFile.OptionalFixed64Extension, 123u)
-        .SetExtension(UnitTestProtoFile.OptionalFloatExtension, 123)
-        .SetExtension(UnitTestProtoFile.OptionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ)
-        .SetExtension(UnitTestProtoFile.OptionalImportEnumExtension, ImportEnum.IMPORT_BAZ)
-        .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 123)
-        .SetExtension(UnitTestProtoFile.OptionalInt64Extension, 123)
-        .SetExtension(UnitTestProtoFile.OptionalNestedEnumExtension, TestAllTypes.Types.NestedEnum.FOO)
-        .SetExtension(UnitTestProtoFile.OptionalSfixed32Extension, 123)
-        .SetExtension(UnitTestProtoFile.OptionalSfixed64Extension, 123)
-        .SetExtension(UnitTestProtoFile.OptionalSint32Extension, 123)
-        .SetExtension(UnitTestProtoFile.OptionalSint64Extension, 123)
-        .SetExtension(UnitTestProtoFile.OptionalStringExtension, "123")
-        .SetExtension(UnitTestProtoFile.OptionalStringPieceExtension, "123")
-        .SetExtension(UnitTestProtoFile.OptionalUint32Extension, 123u)
-        .SetExtension(UnitTestProtoFile.OptionalUint64Extension, 123u)
-        //Repeated
-        .AddExtension(UnitTestProtoFile.RepeatedBoolExtension, true)
-        .AddExtension(UnitTestProtoFile.RepeatedBytesExtension, ByteString.CopyFromUtf8("123"))
-        .AddExtension(UnitTestProtoFile.RepeatedCordExtension, "123")
-        .AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 123)
-        .AddExtension(UnitTestProtoFile.RepeatedFixed32Extension, 123u)
-        .AddExtension(UnitTestProtoFile.RepeatedFixed64Extension, 123u)
-        .AddExtension(UnitTestProtoFile.RepeatedFloatExtension, 123)
-        .AddExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ)
-        .AddExtension(UnitTestProtoFile.RepeatedImportEnumExtension, ImportEnum.IMPORT_BAZ)
-        .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 123)
-        .AddExtension(UnitTestProtoFile.RepeatedInt64Extension, 123)
-        .AddExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, TestAllTypes.Types.NestedEnum.FOO)
-        .AddExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 123)
-        .AddExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 123)
-        .AddExtension(UnitTestProtoFile.RepeatedSint32Extension, 123)
-        .AddExtension(UnitTestProtoFile.RepeatedSint64Extension, 123)
-        .AddExtension(UnitTestProtoFile.RepeatedStringExtension, "123")
-        .AddExtension(UnitTestProtoFile.RepeatedStringPieceExtension, "123")
-        .AddExtension(UnitTestProtoFile.RepeatedUint32Extension, 123u)
-        .AddExtension(UnitTestProtoFile.RepeatedUint64Extension, 123u)
-        ;
-      TestAllExtensions msg = builder.Build();
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      UnitTestProtoFile.RegisterAllExtensions(registry);
-
-      TestAllExtensions.Builder copyBuilder = TestAllExtensions.CreateBuilder().MergeFrom(msg.ToByteArray(), registry);
-      TestAllExtensions copy = copyBuilder.Build();
-
-      Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
-
-      Assert.AreEqual(true, copy.GetExtension(UnitTestProtoFile.DefaultBoolExtension));
-      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestProtoFile.DefaultBytesExtension));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.DefaultCordExtension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultDoubleExtension));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.DefaultFixed32Extension));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.DefaultFixed64Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultFloatExtension));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, copy.GetExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
-      Assert.AreEqual(ImportEnum.IMPORT_BAZ, copy.GetExtension(UnitTestProtoFile.DefaultImportEnumExtension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultInt32Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultInt64Extension));
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, copy.GetExtension(UnitTestProtoFile.DefaultNestedEnumExtension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultSfixed32Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultSfixed64Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultSint32Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultSint64Extension));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.DefaultStringExtension));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.DefaultStringPieceExtension));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.DefaultUint32Extension));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.DefaultUint64Extension));
-
-      Assert.AreEqual(true, copy.GetExtension(UnitTestProtoFile.OptionalBoolExtension));
-      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestProtoFile.OptionalBytesExtension));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.OptionalCordExtension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalDoubleExtension));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.OptionalFixed32Extension));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.OptionalFixed64Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalFloatExtension));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, copy.GetExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
-      Assert.AreEqual(ImportEnum.IMPORT_BAZ, copy.GetExtension(UnitTestProtoFile.OptionalImportEnumExtension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalInt64Extension));
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, copy.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalSfixed32Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalSfixed64Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalSint32Extension));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalSint64Extension));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.OptionalStringExtension));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.OptionalStringPieceExtension));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.OptionalUint32Extension));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.OptionalUint64Extension));
-
-      Assert.AreEqual(true, copy.GetExtension(UnitTestProtoFile.RepeatedBoolExtension, 0));
-      Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 0));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedFloatExtension, 0));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, copy.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 0));
-      Assert.AreEqual(ImportEnum.IMPORT_BAZ, copy.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedInt32Extension, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedInt64Extension, 0));
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, copy.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedSint32Extension, 0));
-      Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedSint64Extension, 0));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.RepeatedStringExtension, 0));
-      Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.RepeatedUint32Extension, 0));
-      Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.RepeatedUint64Extension, 0));
-    }
-
-  }
-}
+#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 ExtendableMessageTest
+    {
+        [Test, ExpectedException(typeof (ArgumentException))]
+        public void ExtensionWriterInvalidExtension()
+        {
+            TestPackedExtensions.CreateBuilder()[UnitTestProtoFile.OptionalForeignMessageExtension.Descriptor] =
+                ForeignMessage.DefaultInstance;
+        }
+
+        [Test]
+        public void ExtensionWriterTest()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder()
+                .SetExtension(UnitTestProtoFile.DefaultBoolExtension, true)
+                .SetExtension(UnitTestProtoFile.DefaultBytesExtension, ByteString.CopyFromUtf8("123"))
+                .SetExtension(UnitTestProtoFile.DefaultCordExtension, "123")
+                .SetExtension(UnitTestProtoFile.DefaultDoubleExtension, 123)
+                .SetExtension(UnitTestProtoFile.DefaultFixed32Extension, 123u)
+                .SetExtension(UnitTestProtoFile.DefaultFixed64Extension, 123u)
+                .SetExtension(UnitTestProtoFile.DefaultFloatExtension, 123)
+                .SetExtension(UnitTestProtoFile.DefaultForeignEnumExtension, ForeignEnum.FOREIGN_BAZ)
+                .SetExtension(UnitTestProtoFile.DefaultImportEnumExtension, ImportEnum.IMPORT_BAZ)
+                .SetExtension(UnitTestProtoFile.DefaultInt32Extension, 123)
+                .SetExtension(UnitTestProtoFile.DefaultInt64Extension, 123)
+                .SetExtension(UnitTestProtoFile.DefaultNestedEnumExtension, TestAllTypes.Types.NestedEnum.FOO)
+                .SetExtension(UnitTestProtoFile.DefaultSfixed32Extension, 123)
+                .SetExtension(UnitTestProtoFile.DefaultSfixed64Extension, 123)
+                .SetExtension(UnitTestProtoFile.DefaultSint32Extension, 123)
+                .SetExtension(UnitTestProtoFile.DefaultSint64Extension, 123)
+                .SetExtension(UnitTestProtoFile.DefaultStringExtension, "123")
+                .SetExtension(UnitTestProtoFile.DefaultStringPieceExtension, "123")
+                .SetExtension(UnitTestProtoFile.DefaultUint32Extension, 123u)
+                .SetExtension(UnitTestProtoFile.DefaultUint64Extension, 123u)
+                //Optional
+                .SetExtension(UnitTestProtoFile.OptionalBoolExtension, true)
+                .SetExtension(UnitTestProtoFile.OptionalBytesExtension, ByteString.CopyFromUtf8("123"))
+                .SetExtension(UnitTestProtoFile.OptionalCordExtension, "123")
+                .SetExtension(UnitTestProtoFile.OptionalDoubleExtension, 123)
+                .SetExtension(UnitTestProtoFile.OptionalFixed32Extension, 123u)
+                .SetExtension(UnitTestProtoFile.OptionalFixed64Extension, 123u)
+                .SetExtension(UnitTestProtoFile.OptionalFloatExtension, 123)
+                .SetExtension(UnitTestProtoFile.OptionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ)
+                .SetExtension(UnitTestProtoFile.OptionalImportEnumExtension, ImportEnum.IMPORT_BAZ)
+                .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 123)
+                .SetExtension(UnitTestProtoFile.OptionalInt64Extension, 123)
+                .SetExtension(UnitTestProtoFile.OptionalNestedEnumExtension, TestAllTypes.Types.NestedEnum.FOO)
+                .SetExtension(UnitTestProtoFile.OptionalSfixed32Extension, 123)
+                .SetExtension(UnitTestProtoFile.OptionalSfixed64Extension, 123)
+                .SetExtension(UnitTestProtoFile.OptionalSint32Extension, 123)
+                .SetExtension(UnitTestProtoFile.OptionalSint64Extension, 123)
+                .SetExtension(UnitTestProtoFile.OptionalStringExtension, "123")
+                .SetExtension(UnitTestProtoFile.OptionalStringPieceExtension, "123")
+                .SetExtension(UnitTestProtoFile.OptionalUint32Extension, 123u)
+                .SetExtension(UnitTestProtoFile.OptionalUint64Extension, 123u)
+                //Repeated
+                .AddExtension(UnitTestProtoFile.RepeatedBoolExtension, true)
+                .AddExtension(UnitTestProtoFile.RepeatedBytesExtension, ByteString.CopyFromUtf8("123"))
+                .AddExtension(UnitTestProtoFile.RepeatedCordExtension, "123")
+                .AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 123)
+                .AddExtension(UnitTestProtoFile.RepeatedFixed32Extension, 123u)
+                .AddExtension(UnitTestProtoFile.RepeatedFixed64Extension, 123u)
+                .AddExtension(UnitTestProtoFile.RepeatedFloatExtension, 123)
+                .AddExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ)
+                .AddExtension(UnitTestProtoFile.RepeatedImportEnumExtension, ImportEnum.IMPORT_BAZ)
+                .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 123)
+                .AddExtension(UnitTestProtoFile.RepeatedInt64Extension, 123)
+                .AddExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, TestAllTypes.Types.NestedEnum.FOO)
+                .AddExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 123)
+                .AddExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 123)
+                .AddExtension(UnitTestProtoFile.RepeatedSint32Extension, 123)
+                .AddExtension(UnitTestProtoFile.RepeatedSint64Extension, 123)
+                .AddExtension(UnitTestProtoFile.RepeatedStringExtension, "123")
+                .AddExtension(UnitTestProtoFile.RepeatedStringPieceExtension, "123")
+                .AddExtension(UnitTestProtoFile.RepeatedUint32Extension, 123u)
+                .AddExtension(UnitTestProtoFile.RepeatedUint64Extension, 123u)
+                ;
+            TestAllExtensions msg = builder.Build();
+
+            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+            UnitTestProtoFile.RegisterAllExtensions(registry);
+
+            TestAllExtensions.Builder copyBuilder = TestAllExtensions.CreateBuilder().MergeFrom(msg.ToByteArray(),
+                                                                                                registry);
+            TestAllExtensions copy = copyBuilder.Build();
+
+            Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());
+
+            Assert.AreEqual(true, copy.GetExtension(UnitTestProtoFile.DefaultBoolExtension));
+            Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestProtoFile.DefaultBytesExtension));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.DefaultCordExtension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultDoubleExtension));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.DefaultFixed32Extension));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.DefaultFixed64Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultFloatExtension));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, copy.GetExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
+            Assert.AreEqual(ImportEnum.IMPORT_BAZ, copy.GetExtension(UnitTestProtoFile.DefaultImportEnumExtension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultInt32Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultInt64Extension));
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO,
+                            copy.GetExtension(UnitTestProtoFile.DefaultNestedEnumExtension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultSfixed32Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultSfixed64Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultSint32Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.DefaultSint64Extension));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.DefaultStringExtension));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.DefaultStringPieceExtension));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.DefaultUint32Extension));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.DefaultUint64Extension));
+
+            Assert.AreEqual(true, copy.GetExtension(UnitTestProtoFile.OptionalBoolExtension));
+            Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestProtoFile.OptionalBytesExtension));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.OptionalCordExtension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalDoubleExtension));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.OptionalFixed32Extension));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.OptionalFixed64Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalFloatExtension));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, copy.GetExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
+            Assert.AreEqual(ImportEnum.IMPORT_BAZ, copy.GetExtension(UnitTestProtoFile.OptionalImportEnumExtension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalInt64Extension));
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO,
+                            copy.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalSfixed32Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalSfixed64Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalSint32Extension));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.OptionalSint64Extension));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.OptionalStringExtension));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.OptionalStringPieceExtension));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.OptionalUint32Extension));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.OptionalUint64Extension));
+
+            Assert.AreEqual(true, copy.GetExtension(UnitTestProtoFile.RepeatedBoolExtension, 0));
+            Assert.AreEqual(ByteString.CopyFromUtf8("123"),
+                            copy.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 0));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 0));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 0));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 0));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 0));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedFloatExtension, 0));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ,
+                            copy.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 0));
+            Assert.AreEqual(ImportEnum.IMPORT_BAZ, copy.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 0));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedInt32Extension, 0));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedInt64Extension, 0));
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO,
+                            copy.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 0));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 0));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 0));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedSint32Extension, 0));
+            Assert.AreEqual(123, copy.GetExtension(UnitTestProtoFile.RepeatedSint64Extension, 0));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.RepeatedStringExtension, 0));
+            Assert.AreEqual("123", copy.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 0));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.RepeatedUint32Extension, 0));
+            Assert.AreEqual(123u, copy.GetExtension(UnitTestProtoFile.RepeatedUint64Extension, 0));
+        }
+    }
+}

+ 538 - 465
src/ProtocolBuffers.Test/GeneratedMessageTest.cs

@@ -1,465 +1,538 @@
-#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.Collections;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class GeneratedMessageTest {
-    ReflectionTester reflectionTester;
-    ReflectionTester extensionsReflectionTester;
-    
-    [SetUp]
-    public void SetUp() {
-      reflectionTester = ReflectionTester.CreateTestAllTypesInstance();
-      extensionsReflectionTester = ReflectionTester.CreateTestAllExtensionsInstance();
-    }
-
-    [Test]
-    public void RepeatedAddPrimitiveBeforeBuild() {
-      TestAllTypes message = new TestAllTypes.Builder { RepeatedInt32List = { 1, 2, 3 } }.Build();
-      TestUtil.AssertEqual(new int[]{1, 2, 3}, message.RepeatedInt32List);
-    }
-
-    [Test]
-    public void AddPrimitiveFailsAfterBuild() {
-      TestAllTypes.Builder builder = new TestAllTypes.Builder();
-      IList<int> list = builder.RepeatedInt32List;
-      list.Add(1); // Fine
-      builder.Build();
-
-      try {
-        list.Add(2);
-        Assert.Fail("List should be frozen");
-      } catch (NotSupportedException) {
-        // Expected
-      }
-    }
-
-    [Test]
-    public void RepeatedAddMessageBeforeBuild() {
-      TestAllTypes message = new TestAllTypes.Builder {
-          RepeatedNestedMessageList = { new TestAllTypes.Types.NestedMessage.Builder { Bb = 10 }.Build() } }.Build();
-      Assert.AreEqual(1, message.RepeatedNestedMessageCount);
-      Assert.AreEqual(10, message.RepeatedNestedMessageList[0].Bb);
-    }
-
-    [Test]
-    public void AddMessageFailsAfterBuild() {
-      TestAllTypes.Builder builder = new TestAllTypes.Builder();
-      IList<TestAllTypes.Types.NestedMessage> list = builder.RepeatedNestedMessageList;
-      builder.Build();
-
-      try {
-        list.Add(new TestAllTypes.Types.NestedMessage.Builder { Bb = 10 }.Build());
-        Assert.Fail("List should be frozen");
-      } catch (NotSupportedException) {
-        // Expected
-      }
-    }
-
-    [Test]
-    public void DoubleBuildError() {
-      TestAllTypes.Builder builder = new TestAllTypes.Builder();
-      builder.Build();
-      try {
-        builder.Build();
-        Assert.Fail("Should have thrown exception.");
-      } catch (InvalidOperationException) {
-        // Success.
-      }
-    }
-
-    [Test]
-    public void DefaultInstance() {
-      Assert.AreSame(TestAllTypes.DefaultInstance, TestAllTypes.DefaultInstance.DefaultInstanceForType);
-      Assert.AreSame(TestAllTypes.DefaultInstance, TestAllTypes.CreateBuilder().DefaultInstanceForType);
-    }
-
-    [Test]
-    public void Accessors() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TestUtil.SetAllFields(builder);
-      TestAllTypes message = builder.Build();
-      TestUtil.AssertAllFieldsSet(message);
-    }
-
-    [Test]
-    public void SettersRejectNull() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TestUtil.AssertArgumentNullException(() => builder.SetOptionalString(null));
-      TestUtil.AssertArgumentNullException(() => builder.SetOptionalBytes(null));
-      TestUtil.AssertArgumentNullException(() => builder.SetOptionalNestedMessage((TestAllTypes.Types.NestedMessage)null));
-      TestUtil.AssertArgumentNullException(() => builder.SetOptionalNestedMessage((TestAllTypes.Types.NestedMessage.Builder)null));
-      TestUtil.AssertArgumentNullException(() => builder.AddRepeatedString(null));
-      TestUtil.AssertArgumentNullException(() => builder.AddRepeatedBytes(null));
-      TestUtil.AssertArgumentNullException(() => builder.AddRepeatedNestedMessage((TestAllTypes.Types.NestedMessage)null));
-      TestUtil.AssertArgumentNullException(() => builder.AddRepeatedNestedMessage((TestAllTypes.Types.NestedMessage.Builder)null));
-    }
-
-    [Test]
-    public void RepeatedSetters() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TestUtil.SetAllFields(builder);
-      TestUtil.ModifyRepeatedFields(builder);
-      TestAllTypes message = builder.Build();
-      TestUtil.AssertRepeatedFieldsModified(message);
-    }
-
-    [Test]
-    public void RepeatedAppend() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-
-      builder.AddRangeRepeatedInt32(new int[]{1, 2, 3, 4});
-      builder.AddRangeRepeatedForeignEnum((new ForeignEnum[] { ForeignEnum.FOREIGN_BAZ }));
-
-      ForeignMessage foreignMessage = ForeignMessage.CreateBuilder().SetC(12).Build();
-      builder.AddRangeRepeatedForeignMessage(new ForeignMessage[] {foreignMessage});
-
-      TestAllTypes message = builder.Build();
-      TestUtil.AssertEqual(message.RepeatedInt32List, new int[]{1, 2, 3, 4});
-      TestUtil.AssertEqual(message.RepeatedForeignEnumList, new ForeignEnum[] {ForeignEnum.FOREIGN_BAZ});
-      Assert.AreEqual(1, message.RepeatedForeignMessageCount);
-      Assert.AreEqual(12, message.GetRepeatedForeignMessage(0).C);
-    }
-
-    [Test]
-    public void RepeatedAppendRejectsNull() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-
-      ForeignMessage foreignMessage = ForeignMessage.CreateBuilder().SetC(12).Build();
-      TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignMessage(new[] { foreignMessage, null }));
-      TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignMessage(null));
-      TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignEnum(null));
-      TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedString(new[] { "one", null }));
-      TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedBytes(new[] { TestUtil.ToBytes("one"), null }));
-    }
-
-    [Test]
-    public void SettingForeignMessageUsingBuilder() {
-      TestAllTypes message = TestAllTypes.CreateBuilder()
-          // Pass builder for foreign message instance.
-          .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(123))
-          .Build();
-      TestAllTypes expectedMessage = TestAllTypes.CreateBuilder()
-          // Create expected version passing foreign message instance explicitly.
-          .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(123).Build())
-          .Build();
-      Assert.AreEqual(expectedMessage, message);
-    }
-
-    [Test]
-    public void SettingRepeatedForeignMessageUsingBuilder() {
-      TestAllTypes message = TestAllTypes.CreateBuilder()
-          // Pass builder for foreign message instance.
-          .AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(456))
-          .Build();
-      TestAllTypes expectedMessage = TestAllTypes.CreateBuilder()
-          // Create expected version passing foreign message instance explicitly.
-          .AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(456).Build())
-          .Build();
-      Assert.AreEqual(expectedMessage, message);
-    }
-
-    [Test]
-    public void SettingRepeatedValuesUsingRangeInCollectionInitializer() {
-      int[] values = { 1, 2, 3 };
-      TestAllTypes message = new TestAllTypes.Builder {
-        RepeatedSint32List = { values }
-      }.Build();
-      Assert.IsTrue(Lists.Equals(values, message.RepeatedSint32List));
-    }
-
-    [Test]
-    public void SettingRepeatedValuesUsingIndividualValuesInCollectionInitializer() {
-      TestAllTypes message = new TestAllTypes.Builder {
-        RepeatedSint32List = { 6, 7 }
-      }.Build();
-      Assert.IsTrue(Lists.Equals(new int[] { 6, 7 }, message.RepeatedSint32List));
-    }
-    
-    [Test]
-    public void Defaults() {
-      TestUtil.AssertClear(TestAllTypes.DefaultInstance);
-      TestUtil.AssertClear(TestAllTypes.CreateBuilder().Build());
-
-      Assert.AreEqual("\u1234", TestExtremeDefaultValues.DefaultInstance.Utf8String);
-    }
-
-    [Test]
-    public void ReflectionGetters() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TestUtil.SetAllFields(builder);
-      TestAllTypes message = builder.Build();
-      reflectionTester.AssertAllFieldsSetViaReflection(message);
-    }
-
-    [Test]
-    public void ReflectionSetters() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      reflectionTester.SetAllFieldsViaReflection(builder);
-      TestAllTypes message = builder.Build();
-      TestUtil.AssertAllFieldsSet(message);
-    }
-
-    [Test]
-    public void ReflectionSettersRejectNull() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      reflectionTester.AssertReflectionSettersRejectNull(builder);
-    }
-    [Test]
-    public void ReflectionRepeatedSetters() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      reflectionTester.SetAllFieldsViaReflection(builder);
-      reflectionTester.ModifyRepeatedFieldsViaReflection(builder);
-      TestAllTypes message = builder.Build();
-      TestUtil.AssertRepeatedFieldsModified(message);
-    }
-
-    [Test]
-    public void TestReflectionRepeatedSettersRejectNull() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      reflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
-    }
-
-    [Test]
-    public void ReflectionDefaults() {
-      TestUtil.TestInMultipleCultures(() => {
-        reflectionTester.AssertClearViaReflection(TestAllTypes.DefaultInstance);
-        reflectionTester.AssertClearViaReflection(TestAllTypes.CreateBuilder().Build());
-      });
-    }
-    // =================================================================
-    // Extensions.
-
-    [Test]
-    public void ExtensionAccessors() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      TestUtil.SetAllExtensions(builder);
-      TestAllExtensions message = builder.Build();
-      TestUtil.AssertAllExtensionsSet(message);
-    }
-
-    [Test]
-    public void ExtensionRepeatedSetters() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      TestUtil.SetAllExtensions(builder);
-      TestUtil.ModifyRepeatedExtensions(builder);
-      TestAllExtensions message = builder.Build();
-      TestUtil.AssertRepeatedExtensionsModified(message);
-    }
-
-    [Test]
-    public void ExtensionDefaults() {
-      TestUtil.AssertExtensionsClear(TestAllExtensions.DefaultInstance);
-      TestUtil.AssertExtensionsClear(TestAllExtensions.CreateBuilder().Build());
-    }
-
-    [Test]
-    public void ExtensionReflectionGetters() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      TestUtil.SetAllExtensions(builder);
-      TestAllExtensions message = builder.Build();
-      extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
-    }
-
-    [Test]
-    public void ExtensionReflectionSetters() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      extensionsReflectionTester.SetAllFieldsViaReflection(builder);
-      TestAllExtensions message = builder.Build();
-      TestUtil.AssertAllExtensionsSet(message);
-    }
-
-    [Test]
-    public void ExtensionReflectionSettersRejectNull() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
-    }
-
-    [Test]
-    public void ExtensionReflectionRepeatedSetters() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      extensionsReflectionTester.SetAllFieldsViaReflection(builder);
-      extensionsReflectionTester.ModifyRepeatedFieldsViaReflection(builder);
-      TestAllExtensions message = builder.Build();
-      TestUtil.AssertRepeatedExtensionsModified(message);
-    }
-
-    [Test]
-    public void ExtensionReflectionRepeatedSettersRejectNull() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      extensionsReflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
-    }
-
-    [Test]
-    public void ExtensionReflectionDefaults() {
-      TestUtil.TestInMultipleCultures(() => {
-        extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.DefaultInstance);
-        extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.CreateBuilder().Build());
-      });
-    }    
-    
-    [Test]
-    public void ClearExtension() {
-      // ClearExtension() is not actually used in TestUtil, so try it manually.
-      Assert.IsFalse(TestAllExtensions.CreateBuilder()
-          .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1)
-          .ClearExtension(UnitTestProtoFile.OptionalInt32Extension)
-          .HasExtension(UnitTestProtoFile.OptionalInt32Extension));
-      Assert.AreEqual(0, TestAllExtensions.CreateBuilder()
-          .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 1)
-          .ClearExtension(UnitTestProtoFile.RepeatedInt32Extension)
-          .GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
-    }
-
-    [Test]
-    public void ExtensionMergeFrom() {
-      TestAllExtensions original = TestAllExtensions.CreateBuilder()
-          .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1).Build();
-      TestAllExtensions merged =
-          TestAllExtensions.CreateBuilder().MergeFrom(original).Build();
-      Assert.IsTrue((merged.HasExtension(UnitTestProtoFile.OptionalInt32Extension)));
-      Assert.AreEqual(1, (int)merged.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
-    }    
-
-    /* Removed multiple files option for the moment
-    [Test]
-    public void MultipleFilesOption() {
-      // We mostly just want to check that things compile.
-      MessageWithNoOuter message = MessageWithNoOuter.CreateBuilder()
-          .SetNested(MessageWithNoOuter.Types.NestedMessage.CreateBuilder().SetI(1))
-          .AddForeign(TestAllTypes.CreateBuilder().SetOptionalInt32(1))
-          .SetNestedEnum(MessageWithNoOuter.Types.NestedEnum.BAZ)
-          .SetForeignEnum(EnumWithNoOuter.BAR)
-          .Build();
-      Assert.AreEqual(message, MessageWithNoOuter.ParseFrom(message.ToByteString()));
-
-      Assert.AreEqual(MultiFileProto.Descriptor, MessageWithNoOuter.Descriptor.File);
-
-      FieldDescriptor field = MessageWithNoOuter.Descriptor.FindDescriptor<FieldDescriptor>("foreign_enum");
-      Assert.AreEqual(MultiFileProto.Descriptor.FindTypeByName<EnumDescriptor>("EnumWithNoOuter")
-        .FindValueByNumber((int)EnumWithNoOuter.BAR), message[field]);
-
-      Assert.AreEqual(MultiFileProto.Descriptor, ServiceWithNoOuter.Descriptor.File);
-
-      Assert.IsFalse(TestAllExtensions.DefaultInstance.HasExtension(MultiFileProto.ExtensionWithOuter));
-    }*/
-
-    [Test]
-    public void OptionalFieldWithRequiredSubfieldsOptimizedForSize() {      
-      TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.DefaultInstance;
-      Assert.IsTrue(message.IsInitialized);
-
-      message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
-          TestRequiredOptimizedForSize.CreateBuilder().BuildPartial()
-          ).BuildPartial();
-      Assert.IsFalse(message.IsInitialized);
-
-      message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
-          TestRequiredOptimizedForSize.CreateBuilder().SetX(5).BuildPartial()
-          ).BuildPartial();
-      Assert.IsTrue(message.IsInitialized);
-    }
-
-    [Test]
-    public void OptimizedForSizeMergeUsesAllFieldsFromTarget() {
-      TestOptimizedForSize withFieldSet = new TestOptimizedForSize.Builder { I = 10 }.Build();
-      TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
-      builder.MergeFrom(withFieldSet);
-      TestOptimizedForSize built = builder.Build();
-      Assert.AreEqual(10, built.I);
-    }
-
-    [Test]
-    public void UninitializedExtensionInOptimizedForSizeMakesMessageUninitialized() {
-      TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
-      builder.SetExtension(TestOptimizedForSize.TestExtension2,
-          new TestRequiredOptimizedForSize.Builder().BuildPartial());
-      Assert.IsFalse(builder.IsInitialized);
-      Assert.IsFalse(builder.BuildPartial().IsInitialized);
-
-      builder = new TestOptimizedForSize.Builder();
-      builder.SetExtension(TestOptimizedForSize.TestExtension2,
-          new TestRequiredOptimizedForSize.Builder { X = 10 }.BuildPartial());
-      Assert.IsTrue(builder.IsInitialized);
-      Assert.IsTrue(builder.BuildPartial().IsInitialized);
-    }
-
-    [Test]
-    public void ToBuilder() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TestUtil.SetAllFields(builder);
-      TestAllTypes message = builder.Build();
-      TestUtil.AssertAllFieldsSet(message.ToBuilder().Build());
-    }
-
-    [Test]
-    public void FieldConstantValues() {
-      Assert.AreEqual(TestAllTypes.Types.NestedMessage.BbFieldNumber, 1);
-      Assert.AreEqual(TestAllTypes.OptionalInt32FieldNumber, 1);
-      Assert.AreEqual(TestAllTypes.OptionalGroupFieldNumber, 16);
-      Assert.AreEqual(TestAllTypes.OptionalNestedMessageFieldNumber, 18);
-      Assert.AreEqual(TestAllTypes.OptionalNestedEnumFieldNumber, 21);
-      Assert.AreEqual(TestAllTypes.RepeatedInt32FieldNumber, 31);
-      Assert.AreEqual(TestAllTypes.RepeatedGroupFieldNumber, 46);
-      Assert.AreEqual(TestAllTypes.RepeatedNestedMessageFieldNumber, 48);
-      Assert.AreEqual(TestAllTypes.RepeatedNestedEnumFieldNumber, 51);
-    }
-
-    [Test]
-    public void ExtensionConstantValues() {
-      Assert.AreEqual(TestRequired.SingleFieldNumber, 1000);
-      Assert.AreEqual(TestRequired.MultiFieldNumber, 1001);
-      Assert.AreEqual(UnitTestProtoFile.OptionalInt32ExtensionFieldNumber, 1);
-      Assert.AreEqual(UnitTestProtoFile.OptionalGroupExtensionFieldNumber, 16);
-      Assert.AreEqual(UnitTestProtoFile.OptionalNestedMessageExtensionFieldNumber, 18);
-      Assert.AreEqual(UnitTestProtoFile.OptionalNestedEnumExtensionFieldNumber, 21);
-      Assert.AreEqual(UnitTestProtoFile.RepeatedInt32ExtensionFieldNumber, 31);
-      Assert.AreEqual(UnitTestProtoFile.RepeatedGroupExtensionFieldNumber, 46);
-      Assert.AreEqual(UnitTestProtoFile.RepeatedNestedMessageExtensionFieldNumber, 48);
-      Assert.AreEqual(UnitTestProtoFile.RepeatedNestedEnumExtensionFieldNumber, 51);
-    }
-
-    [Test]
-    public void EmptyPackedValue() {
-      TestPackedTypes empty = new TestPackedTypes.Builder().Build();
-      Assert.AreEqual(0, empty.SerializedSize);
-    }
-  }
-}
+#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.Collections;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class GeneratedMessageTest
+    {
+        private ReflectionTester reflectionTester;
+        private ReflectionTester extensionsReflectionTester;
+
+        [SetUp]
+        public void SetUp()
+        {
+            reflectionTester = ReflectionTester.CreateTestAllTypesInstance();
+            extensionsReflectionTester = ReflectionTester.CreateTestAllExtensionsInstance();
+        }
+
+        [Test]
+        public void RepeatedAddPrimitiveBeforeBuild()
+        {
+            TestAllTypes message = new TestAllTypes.Builder {RepeatedInt32List = {1, 2, 3}}.Build();
+            TestUtil.AssertEqual(new int[] {1, 2, 3}, message.RepeatedInt32List);
+        }
+
+        [Test]
+        public void AddPrimitiveFailsAfterBuild()
+        {
+            TestAllTypes.Builder builder = new TestAllTypes.Builder();
+            IList<int> list = builder.RepeatedInt32List;
+            list.Add(1); // Fine
+            builder.Build();
+
+            try
+            {
+                list.Add(2);
+                Assert.Fail("List should be frozen");
+            }
+            catch (NotSupportedException)
+            {
+                // Expected
+            }
+        }
+
+        [Test]
+        public void RepeatedAddMessageBeforeBuild()
+        {
+            TestAllTypes message = new TestAllTypes.Builder
+                                       {
+                                           RepeatedNestedMessageList =
+                                               {new TestAllTypes.Types.NestedMessage.Builder {Bb = 10}.Build()}
+                                       }.Build();
+            Assert.AreEqual(1, message.RepeatedNestedMessageCount);
+            Assert.AreEqual(10, message.RepeatedNestedMessageList[0].Bb);
+        }
+
+        [Test]
+        public void AddMessageFailsAfterBuild()
+        {
+            TestAllTypes.Builder builder = new TestAllTypes.Builder();
+            IList<TestAllTypes.Types.NestedMessage> list = builder.RepeatedNestedMessageList;
+            builder.Build();
+
+            try
+            {
+                list.Add(new TestAllTypes.Types.NestedMessage.Builder {Bb = 10}.Build());
+                Assert.Fail("List should be frozen");
+            }
+            catch (NotSupportedException)
+            {
+                // Expected
+            }
+        }
+
+        [Test]
+        public void DoubleBuildError()
+        {
+            TestAllTypes.Builder builder = new TestAllTypes.Builder();
+            builder.Build();
+            try
+            {
+                builder.Build();
+                Assert.Fail("Should have thrown exception.");
+            }
+            catch (InvalidOperationException)
+            {
+                // Success.
+            }
+        }
+
+        [Test]
+        public void DefaultInstance()
+        {
+            Assert.AreSame(TestAllTypes.DefaultInstance, TestAllTypes.DefaultInstance.DefaultInstanceForType);
+            Assert.AreSame(TestAllTypes.DefaultInstance, TestAllTypes.CreateBuilder().DefaultInstanceForType);
+        }
+
+        [Test]
+        public void Accessors()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TestUtil.SetAllFields(builder);
+            TestAllTypes message = builder.Build();
+            TestUtil.AssertAllFieldsSet(message);
+        }
+
+        [Test]
+        public void SettersRejectNull()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TestUtil.AssertArgumentNullException(() => builder.SetOptionalString(null));
+            TestUtil.AssertArgumentNullException(() => builder.SetOptionalBytes(null));
+            TestUtil.AssertArgumentNullException(
+                () => builder.SetOptionalNestedMessage((TestAllTypes.Types.NestedMessage) null));
+            TestUtil.AssertArgumentNullException(
+                () => builder.SetOptionalNestedMessage((TestAllTypes.Types.NestedMessage.Builder) null));
+            TestUtil.AssertArgumentNullException(() => builder.AddRepeatedString(null));
+            TestUtil.AssertArgumentNullException(() => builder.AddRepeatedBytes(null));
+            TestUtil.AssertArgumentNullException(
+                () => builder.AddRepeatedNestedMessage((TestAllTypes.Types.NestedMessage) null));
+            TestUtil.AssertArgumentNullException(
+                () => builder.AddRepeatedNestedMessage((TestAllTypes.Types.NestedMessage.Builder) null));
+        }
+
+        [Test]
+        public void RepeatedSetters()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TestUtil.SetAllFields(builder);
+            TestUtil.ModifyRepeatedFields(builder);
+            TestAllTypes message = builder.Build();
+            TestUtil.AssertRepeatedFieldsModified(message);
+        }
+
+        [Test]
+        public void RepeatedAppend()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+
+            builder.AddRangeRepeatedInt32(new int[] {1, 2, 3, 4});
+            builder.AddRangeRepeatedForeignEnum((new ForeignEnum[] {ForeignEnum.FOREIGN_BAZ}));
+
+            ForeignMessage foreignMessage = ForeignMessage.CreateBuilder().SetC(12).Build();
+            builder.AddRangeRepeatedForeignMessage(new ForeignMessage[] {foreignMessage});
+
+            TestAllTypes message = builder.Build();
+            TestUtil.AssertEqual(message.RepeatedInt32List, new int[] {1, 2, 3, 4});
+            TestUtil.AssertEqual(message.RepeatedForeignEnumList, new ForeignEnum[] {ForeignEnum.FOREIGN_BAZ});
+            Assert.AreEqual(1, message.RepeatedForeignMessageCount);
+            Assert.AreEqual(12, message.GetRepeatedForeignMessage(0).C);
+        }
+
+        [Test]
+        public void RepeatedAppendRejectsNull()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+
+            ForeignMessage foreignMessage = ForeignMessage.CreateBuilder().SetC(12).Build();
+            TestUtil.AssertArgumentNullException(
+                () => builder.AddRangeRepeatedForeignMessage(new[] {foreignMessage, null}));
+            TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignMessage(null));
+            TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignEnum(null));
+            TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedString(new[] {"one", null}));
+            TestUtil.AssertArgumentNullException(
+                () => builder.AddRangeRepeatedBytes(new[] {TestUtil.ToBytes("one"), null}));
+        }
+
+        [Test]
+        public void SettingForeignMessageUsingBuilder()
+        {
+            TestAllTypes message = TestAllTypes.CreateBuilder()
+                // Pass builder for foreign message instance.
+                .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(123))
+                .Build();
+            TestAllTypes expectedMessage = TestAllTypes.CreateBuilder()
+                // Create expected version passing foreign message instance explicitly.
+                .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(123).Build())
+                .Build();
+            Assert.AreEqual(expectedMessage, message);
+        }
+
+        [Test]
+        public void SettingRepeatedForeignMessageUsingBuilder()
+        {
+            TestAllTypes message = TestAllTypes.CreateBuilder()
+                // Pass builder for foreign message instance.
+                .AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(456))
+                .Build();
+            TestAllTypes expectedMessage = TestAllTypes.CreateBuilder()
+                // Create expected version passing foreign message instance explicitly.
+                .AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(456).Build())
+                .Build();
+            Assert.AreEqual(expectedMessage, message);
+        }
+
+        [Test]
+        public void SettingRepeatedValuesUsingRangeInCollectionInitializer()
+        {
+            int[] values = {1, 2, 3};
+            TestAllTypes message = new TestAllTypes.Builder
+                                       {
+                                           RepeatedSint32List = {values}
+                                       }.Build();
+            Assert.IsTrue(Lists.Equals(values, message.RepeatedSint32List));
+        }
+
+        [Test]
+        public void SettingRepeatedValuesUsingIndividualValuesInCollectionInitializer()
+        {
+            TestAllTypes message = new TestAllTypes.Builder
+                                       {
+                                           RepeatedSint32List = {6, 7}
+                                       }.Build();
+            Assert.IsTrue(Lists.Equals(new int[] {6, 7}, message.RepeatedSint32List));
+        }
+
+        [Test]
+        public void Defaults()
+        {
+            TestUtil.AssertClear(TestAllTypes.DefaultInstance);
+            TestUtil.AssertClear(TestAllTypes.CreateBuilder().Build());
+
+            Assert.AreEqual("\u1234", TestExtremeDefaultValues.DefaultInstance.Utf8String);
+        }
+
+        [Test]
+        public void ReflectionGetters()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TestUtil.SetAllFields(builder);
+            TestAllTypes message = builder.Build();
+            reflectionTester.AssertAllFieldsSetViaReflection(message);
+        }
+
+        [Test]
+        public void ReflectionSetters()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            reflectionTester.SetAllFieldsViaReflection(builder);
+            TestAllTypes message = builder.Build();
+            TestUtil.AssertAllFieldsSet(message);
+        }
+
+        [Test]
+        public void ReflectionSettersRejectNull()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            reflectionTester.AssertReflectionSettersRejectNull(builder);
+        }
+
+        [Test]
+        public void ReflectionRepeatedSetters()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            reflectionTester.SetAllFieldsViaReflection(builder);
+            reflectionTester.ModifyRepeatedFieldsViaReflection(builder);
+            TestAllTypes message = builder.Build();
+            TestUtil.AssertRepeatedFieldsModified(message);
+        }
+
+        [Test]
+        public void TestReflectionRepeatedSettersRejectNull()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            reflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
+        }
+
+        [Test]
+        public void ReflectionDefaults()
+        {
+            TestUtil.TestInMultipleCultures(() =>
+                                                {
+                                                    reflectionTester.AssertClearViaReflection(
+                                                        TestAllTypes.DefaultInstance);
+                                                    reflectionTester.AssertClearViaReflection(
+                                                        TestAllTypes.CreateBuilder().Build());
+                                                });
+        }
+
+        // =================================================================
+        // Extensions.
+
+        [Test]
+        public void ExtensionAccessors()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            TestUtil.SetAllExtensions(builder);
+            TestAllExtensions message = builder.Build();
+            TestUtil.AssertAllExtensionsSet(message);
+        }
+
+        [Test]
+        public void ExtensionRepeatedSetters()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            TestUtil.SetAllExtensions(builder);
+            TestUtil.ModifyRepeatedExtensions(builder);
+            TestAllExtensions message = builder.Build();
+            TestUtil.AssertRepeatedExtensionsModified(message);
+        }
+
+        [Test]
+        public void ExtensionDefaults()
+        {
+            TestUtil.AssertExtensionsClear(TestAllExtensions.DefaultInstance);
+            TestUtil.AssertExtensionsClear(TestAllExtensions.CreateBuilder().Build());
+        }
+
+        [Test]
+        public void ExtensionReflectionGetters()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            TestUtil.SetAllExtensions(builder);
+            TestAllExtensions message = builder.Build();
+            extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
+        }
+
+        [Test]
+        public void ExtensionReflectionSetters()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            extensionsReflectionTester.SetAllFieldsViaReflection(builder);
+            TestAllExtensions message = builder.Build();
+            TestUtil.AssertAllExtensionsSet(message);
+        }
+
+        [Test]
+        public void ExtensionReflectionSettersRejectNull()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
+        }
+
+        [Test]
+        public void ExtensionReflectionRepeatedSetters()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            extensionsReflectionTester.SetAllFieldsViaReflection(builder);
+            extensionsReflectionTester.ModifyRepeatedFieldsViaReflection(builder);
+            TestAllExtensions message = builder.Build();
+            TestUtil.AssertRepeatedExtensionsModified(message);
+        }
+
+        [Test]
+        public void ExtensionReflectionRepeatedSettersRejectNull()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            extensionsReflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
+        }
+
+        [Test]
+        public void ExtensionReflectionDefaults()
+        {
+            TestUtil.TestInMultipleCultures(() =>
+                                                {
+                                                    extensionsReflectionTester.AssertClearViaReflection(
+                                                        TestAllExtensions.DefaultInstance);
+                                                    extensionsReflectionTester.AssertClearViaReflection(
+                                                        TestAllExtensions.CreateBuilder().Build());
+                                                });
+        }
+
+        [Test]
+        public void ClearExtension()
+        {
+            // ClearExtension() is not actually used in TestUtil, so try it manually.
+            Assert.IsFalse(TestAllExtensions.CreateBuilder()
+                               .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1)
+                               .ClearExtension(UnitTestProtoFile.OptionalInt32Extension)
+                               .HasExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.AreEqual(0, TestAllExtensions.CreateBuilder()
+                                   .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 1)
+                                   .ClearExtension(UnitTestProtoFile.RepeatedInt32Extension)
+                                   .GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
+        }
+
+        [Test]
+        public void ExtensionMergeFrom()
+        {
+            TestAllExtensions original = TestAllExtensions.CreateBuilder()
+                .SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1).Build();
+            TestAllExtensions merged =
+                TestAllExtensions.CreateBuilder().MergeFrom(original).Build();
+            Assert.IsTrue((merged.HasExtension(UnitTestProtoFile.OptionalInt32Extension)));
+            Assert.AreEqual(1, (int) merged.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
+        }
+
+        /* Removed multiple files option for the moment
+    [Test]
+    public void MultipleFilesOption() {
+      // We mostly just want to check that things compile.
+      MessageWithNoOuter message = MessageWithNoOuter.CreateBuilder()
+          .SetNested(MessageWithNoOuter.Types.NestedMessage.CreateBuilder().SetI(1))
+          .AddForeign(TestAllTypes.CreateBuilder().SetOptionalInt32(1))
+          .SetNestedEnum(MessageWithNoOuter.Types.NestedEnum.BAZ)
+          .SetForeignEnum(EnumWithNoOuter.BAR)
+          .Build();
+      Assert.AreEqual(message, MessageWithNoOuter.ParseFrom(message.ToByteString()));
+
+      Assert.AreEqual(MultiFileProto.Descriptor, MessageWithNoOuter.Descriptor.File);
+
+      FieldDescriptor field = MessageWithNoOuter.Descriptor.FindDescriptor<FieldDescriptor>("foreign_enum");
+      Assert.AreEqual(MultiFileProto.Descriptor.FindTypeByName<EnumDescriptor>("EnumWithNoOuter")
+        .FindValueByNumber((int)EnumWithNoOuter.BAR), message[field]);
+
+      Assert.AreEqual(MultiFileProto.Descriptor, ServiceWithNoOuter.Descriptor.File);
+
+      Assert.IsFalse(TestAllExtensions.DefaultInstance.HasExtension(MultiFileProto.ExtensionWithOuter));
+    }*/
+
+        [Test]
+        public void OptionalFieldWithRequiredSubfieldsOptimizedForSize()
+        {
+            TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.DefaultInstance;
+            Assert.IsTrue(message.IsInitialized);
+
+            message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
+                TestRequiredOptimizedForSize.CreateBuilder().BuildPartial()
+                ).BuildPartial();
+            Assert.IsFalse(message.IsInitialized);
+
+            message = TestOptionalOptimizedForSize.CreateBuilder().SetO(
+                TestRequiredOptimizedForSize.CreateBuilder().SetX(5).BuildPartial()
+                ).BuildPartial();
+            Assert.IsTrue(message.IsInitialized);
+        }
+
+        [Test]
+        public void OptimizedForSizeMergeUsesAllFieldsFromTarget()
+        {
+            TestOptimizedForSize withFieldSet = new TestOptimizedForSize.Builder {I = 10}.Build();
+            TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
+            builder.MergeFrom(withFieldSet);
+            TestOptimizedForSize built = builder.Build();
+            Assert.AreEqual(10, built.I);
+        }
+
+        [Test]
+        public void UninitializedExtensionInOptimizedForSizeMakesMessageUninitialized()
+        {
+            TestOptimizedForSize.Builder builder = new TestOptimizedForSize.Builder();
+            builder.SetExtension(TestOptimizedForSize.TestExtension2,
+                                 new TestRequiredOptimizedForSize.Builder().BuildPartial());
+            Assert.IsFalse(builder.IsInitialized);
+            Assert.IsFalse(builder.BuildPartial().IsInitialized);
+
+            builder = new TestOptimizedForSize.Builder();
+            builder.SetExtension(TestOptimizedForSize.TestExtension2,
+                                 new TestRequiredOptimizedForSize.Builder {X = 10}.BuildPartial());
+            Assert.IsTrue(builder.IsInitialized);
+            Assert.IsTrue(builder.BuildPartial().IsInitialized);
+        }
+
+        [Test]
+        public void ToBuilder()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TestUtil.SetAllFields(builder);
+            TestAllTypes message = builder.Build();
+            TestUtil.AssertAllFieldsSet(message.ToBuilder().Build());
+        }
+
+        [Test]
+        public void FieldConstantValues()
+        {
+            Assert.AreEqual(TestAllTypes.Types.NestedMessage.BbFieldNumber, 1);
+            Assert.AreEqual(TestAllTypes.OptionalInt32FieldNumber, 1);
+            Assert.AreEqual(TestAllTypes.OptionalGroupFieldNumber, 16);
+            Assert.AreEqual(TestAllTypes.OptionalNestedMessageFieldNumber, 18);
+            Assert.AreEqual(TestAllTypes.OptionalNestedEnumFieldNumber, 21);
+            Assert.AreEqual(TestAllTypes.RepeatedInt32FieldNumber, 31);
+            Assert.AreEqual(TestAllTypes.RepeatedGroupFieldNumber, 46);
+            Assert.AreEqual(TestAllTypes.RepeatedNestedMessageFieldNumber, 48);
+            Assert.AreEqual(TestAllTypes.RepeatedNestedEnumFieldNumber, 51);
+        }
+
+        [Test]
+        public void ExtensionConstantValues()
+        {
+            Assert.AreEqual(TestRequired.SingleFieldNumber, 1000);
+            Assert.AreEqual(TestRequired.MultiFieldNumber, 1001);
+            Assert.AreEqual(UnitTestProtoFile.OptionalInt32ExtensionFieldNumber, 1);
+            Assert.AreEqual(UnitTestProtoFile.OptionalGroupExtensionFieldNumber, 16);
+            Assert.AreEqual(UnitTestProtoFile.OptionalNestedMessageExtensionFieldNumber, 18);
+            Assert.AreEqual(UnitTestProtoFile.OptionalNestedEnumExtensionFieldNumber, 21);
+            Assert.AreEqual(UnitTestProtoFile.RepeatedInt32ExtensionFieldNumber, 31);
+            Assert.AreEqual(UnitTestProtoFile.RepeatedGroupExtensionFieldNumber, 46);
+            Assert.AreEqual(UnitTestProtoFile.RepeatedNestedMessageExtensionFieldNumber, 48);
+            Assert.AreEqual(UnitTestProtoFile.RepeatedNestedEnumExtensionFieldNumber, 51);
+        }
+
+        [Test]
+        public void EmptyPackedValue()
+        {
+            TestPackedTypes empty = new TestPackedTypes.Builder().Build();
+            Assert.AreEqual(0, empty.SerializedSize);
+        }
+    }
+}

+ 91 - 83
src/ProtocolBuffers.Test/MessageStreamIteratorTest.cs

@@ -1,83 +1,91 @@
-#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.Collections.Generic;
-using System.IO;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-using NestedMessage = Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class MessageStreamIteratorTest {
-
-    [Test]
-    public void ThreeMessagesInMemory() {
-      MemoryStream stream = new MemoryStream(MessageStreamWriterTest.ThreeMessageData);      
-      IEnumerable<NestedMessage> iterator = MessageStreamIterator<NestedMessage>.FromStreamProvider(() => stream);
-      List<NestedMessage> messages = new List<NestedMessage>(iterator);
-
-      Assert.AreEqual(3, messages.Count);
-      Assert.AreEqual(5, messages[0].Bb);
-      Assert.AreEqual(1500, messages[1].Bb);
-      Assert.IsFalse(messages[2].HasBb);
-    }
-
-    [Test]
-    public void ManyMessagesShouldNotTriggerSizeAlert() {
-      int messageSize = TestUtil.GetAllSet().SerializedSize;
-      // Enough messages to trigger the alert unless we've reset the size
-      // Note that currently we need to make this big enough to copy two whole buffers,
-      // as otherwise when we refill the buffer the second type, the alert triggers instantly.
-      int correctCount = (CodedInputStream.BufferSize * 2) / messageSize + 1;
-      using (MemoryStream stream = new MemoryStream()) {
-        MessageStreamWriter<TestAllTypes> writer = new MessageStreamWriter<TestAllTypes>(stream);
-        for (int i = 0; i < correctCount; i++) {
-          writer.Write(TestUtil.GetAllSet());
-        }
-        writer.Flush();
-
-        stream.Position = 0;
-
-        int count = 0;
-        foreach (var message in MessageStreamIterator<TestAllTypes>.FromStreamProvider(() => stream)
-          .WithSizeLimit(CodedInputStream.BufferSize * 2)) {
-          count++;
-          TestUtil.AssertAllFieldsSet(message);
-        }
-        Assert.AreEqual(correctCount, count);
-      }
-    }
-  }
-}
+#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.Collections.Generic;
+using System.IO;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+using NestedMessage = Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class MessageStreamIteratorTest
+    {
+        [Test]
+        public void ThreeMessagesInMemory()
+        {
+            MemoryStream stream = new MemoryStream(MessageStreamWriterTest.ThreeMessageData);
+            IEnumerable<NestedMessage> iterator = MessageStreamIterator<NestedMessage>.FromStreamProvider(() => stream);
+            List<NestedMessage> messages = new List<NestedMessage>(iterator);
+
+            Assert.AreEqual(3, messages.Count);
+            Assert.AreEqual(5, messages[0].Bb);
+            Assert.AreEqual(1500, messages[1].Bb);
+            Assert.IsFalse(messages[2].HasBb);
+        }
+
+        [Test]
+        public void ManyMessagesShouldNotTriggerSizeAlert()
+        {
+            int messageSize = TestUtil.GetAllSet().SerializedSize;
+            // Enough messages to trigger the alert unless we've reset the size
+            // Note that currently we need to make this big enough to copy two whole buffers,
+            // as otherwise when we refill the buffer the second type, the alert triggers instantly.
+            int correctCount = (CodedInputStream.BufferSize*2)/messageSize + 1;
+            using (MemoryStream stream = new MemoryStream())
+            {
+                MessageStreamWriter<TestAllTypes> writer = new MessageStreamWriter<TestAllTypes>(stream);
+                for (int i = 0; i < correctCount; i++)
+                {
+                    writer.Write(TestUtil.GetAllSet());
+                }
+                writer.Flush();
+
+                stream.Position = 0;
+
+                int count = 0;
+                foreach (var message in MessageStreamIterator<TestAllTypes>.FromStreamProvider(() => stream)
+                    .WithSizeLimit(CodedInputStream.BufferSize*2))
+                {
+                    count++;
+                    TestUtil.AssertAllFieldsSet(message);
+                }
+                Assert.AreEqual(correctCount, count);
+            }
+        }
+    }
+}

+ 79 - 70
src/ProtocolBuffers.Test/MessageStreamWriterTest.cs

@@ -1,70 +1,79 @@
-#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 NestedMessage = Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class MessageStreamWriterTest {
-
-    internal static readonly byte[] ThreeMessageData = new byte[] {
-        (1 << 3) | 2, 2, // Field 1, 2 bytes long (first message)
-        (1 << 3) | 0, 5, // Field 1, value 5
-        (1 << 3) | 2, 3, // Field 1, 3 bytes long (second message)
-        (1 << 3) | 0, (1500 & 0x7f) | 0x80, 1500 >> 7, // Field 1, value 1500
-        (1 << 3) | 2, 0, // Field 1, no data (third message)
-    };
-
-    [Test]
-    public void ThreeMessages() {
-      NestedMessage message1 = new NestedMessage.Builder { Bb = 5 }.Build();
-      NestedMessage message2 = new NestedMessage.Builder { Bb = 1500 }.Build();
-      NestedMessage message3 = new NestedMessage.Builder().Build();
-
-      byte[] data;
-      using (MemoryStream stream = new MemoryStream()) {
-        MessageStreamWriter<NestedMessage> writer = new MessageStreamWriter<NestedMessage>(stream);
-        writer.Write(message1);
-        writer.Write(message2);
-        writer.Write(message3);
-        writer.Flush();
-        data = stream.ToArray();
-      }
-
-      TestUtil.AssertEqualBytes(ThreeMessageData, 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.IO;
+using NUnit.Framework;
+using NestedMessage = Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class MessageStreamWriterTest
+    {
+        internal static readonly byte[] ThreeMessageData = new byte[]
+                                                               {
+                                                                   (1 << 3) | 2, 2,
+                                                                   // Field 1, 2 bytes long (first message)
+                                                                   (1 << 3) | 0, 5, // Field 1, value 5
+                                                                   (1 << 3) | 2, 3,
+                                                                   // Field 1, 3 bytes long (second message)
+                                                                   (1 << 3) | 0, (1500 & 0x7f) | 0x80, 1500 >> 7,
+                                                                   // Field 1, value 1500
+                                                                   (1 << 3) | 2, 0, // Field 1, no data (third message)
+                                                               };
+
+        [Test]
+        public void ThreeMessages()
+        {
+            NestedMessage message1 = new NestedMessage.Builder {Bb = 5}.Build();
+            NestedMessage message2 = new NestedMessage.Builder {Bb = 1500}.Build();
+            NestedMessage message3 = new NestedMessage.Builder().Build();
+
+            byte[] data;
+            using (MemoryStream stream = new MemoryStream())
+            {
+                MessageStreamWriter<NestedMessage> writer = new MessageStreamWriter<NestedMessage>(stream);
+                writer.Write(message1);
+                writer.Write(message2);
+                writer.Write(message3);
+                writer.Flush();
+                data = stream.ToArray();
+            }
+
+            TestUtil.AssertEqualBytes(ThreeMessageData, data);
+        }
+    }
+}

+ 380 - 329
src/ProtocolBuffers.Test/MessageTest.cs

@@ -1,329 +1,380 @@
-#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 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 MessageTest {
-    // =================================================================
-    // Message-merging tests.
-
-    private static readonly TestAllTypes MergeSource = new TestAllTypes.Builder { 
-        OptionalInt32 = 1, 
-        OptionalString = "foo", 
-        OptionalForeignMessage = ForeignMessage.DefaultInstance,
-    }.AddRepeatedString("bar").Build();
-
-    private static readonly TestAllTypes MergeDest = new TestAllTypes.Builder {
-        OptionalInt64 = 2,
-        OptionalString = "baz",
-        OptionalForeignMessage = new ForeignMessage.Builder { C=3 }.Build(),
-    }.AddRepeatedString("qux").Build();
-
-    private const string MergeResultText =
-        "optional_int32: 1\n" +
-        "optional_int64: 2\n" +
-        "optional_string: \"foo\"\n" +
-        "optional_foreign_message {\n" +
-        "  c: 3\n" +
-        "}\n" +
-        "repeated_string: \"qux\"\n" +
-        "repeated_string: \"bar\"\n";
-
-    [Test]
-    public void MergeFrom() {
-      TestAllTypes result = TestAllTypes.CreateBuilder(MergeDest).MergeFrom(MergeSource).Build();
-
-      Assert.AreEqual(MergeResultText, result.ToString());
-    }
-
-    /// <summary>
-    /// Test merging a DynamicMessage into a GeneratedMessage. 
-    /// As long as they have the same descriptor, this should work, but it is an
-    /// entirely different code path.
-    /// </summary>
-    [Test]
-    public void MergeFromDynamic() {
-      TestAllTypes result = (TestAllTypes) TestAllTypes.CreateBuilder(MergeDest)
-          .MergeFrom(DynamicMessage.CreateBuilder(MergeSource).Build())
-          .Build();
-
-      Assert.AreEqual(MergeResultText, result.ToString());
-    }
-
-    /// <summary>
-    /// Test merging two DynamicMessages.
-    /// </summary>
-    [Test]
-    public void DynamicMergeFrom() {
-      DynamicMessage result = (DynamicMessage) DynamicMessage.CreateBuilder(MergeDest)
-          .MergeFrom((DynamicMessage) DynamicMessage.CreateBuilder(MergeSource).Build())
-          .Build();
-
-      Assert.AreEqual(MergeResultText, result.ToString());
-    }
-
-    // =================================================================
-    // Required-field-related tests.
-
-    private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;
-    private static readonly TestRequired TestRequiredInitialized = new TestRequired.Builder {
-        A = 1, B = 2, C = 3
-    }.Build();
-
-    [Test]
-    public void Initialization() {
-      TestRequired.Builder builder = TestRequired.CreateBuilder();
-
-      Assert.IsFalse(builder.IsInitialized);
-      builder.A = 1;
-      Assert.IsFalse(builder.IsInitialized);
-      builder.B = 1;
-      Assert.IsFalse(builder.IsInitialized);
-      builder.C = 1;
-      Assert.IsTrue(builder.IsInitialized);
-    }
-
-    [Test]
-    public void RequiredForeign() {
-      TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
-
-      Assert.IsTrue(builder.IsInitialized);
-
-      builder.SetOptionalMessage(TestRequiredUninitialized);
-      Assert.IsFalse(builder.IsInitialized);
-
-      builder.SetOptionalMessage(TestRequiredInitialized);
-      Assert.IsTrue(builder.IsInitialized);
-
-      builder.AddRepeatedMessage(TestRequiredUninitialized);
-      Assert.IsFalse(builder.IsInitialized);
-
-      builder.SetRepeatedMessage(0, TestRequiredInitialized);
-      Assert.IsTrue(builder.IsInitialized);
-    }
-
-    [Test]
-    public void RequiredExtension() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-
-      Assert.IsTrue(builder.IsInitialized);
-
-      builder.SetExtension(TestRequired.Single, TestRequiredUninitialized);
-      Assert.IsFalse(builder.IsInitialized);
-
-      builder.SetExtension(TestRequired.Single, TestRequiredInitialized);
-      Assert.IsTrue(builder.IsInitialized);
-
-      builder.AddExtension(TestRequired.Multi, TestRequiredUninitialized);
-      Assert.IsFalse(builder.IsInitialized);
-
-      builder.SetExtension(TestRequired.Multi, 0, TestRequiredInitialized);
-      Assert.IsTrue(builder.IsInitialized);
-    }
-
-    [Test]
-    public void RequiredDynamic() {
-      MessageDescriptor descriptor = TestRequired.Descriptor;
-      DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
-
-      Assert.IsFalse(builder.IsInitialized);
-      builder[descriptor.FindDescriptor<FieldDescriptor>("a")] = 1;
-      Assert.IsFalse(builder.IsInitialized);
-      builder[descriptor.FindDescriptor<FieldDescriptor>("b")] = 1;
-      Assert.IsFalse(builder.IsInitialized);
-      builder[descriptor.FindDescriptor<FieldDescriptor>("c")] = 1;
-      Assert.IsTrue(builder.IsInitialized);
-    }
-
-    [Test]
-    public void RequiredDynamicForeign() {
-      MessageDescriptor descriptor = TestRequiredForeign.Descriptor;
-      DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
-
-      Assert.IsTrue(builder.IsInitialized);
-
-      builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredUninitialized;
-      Assert.IsFalse(builder.IsInitialized);
-
-      builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredInitialized;
-      Assert.IsTrue(builder.IsInitialized);
-
-      builder.AddRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), TestRequiredUninitialized);
-      Assert.IsFalse(builder.IsInitialized);
-
-      builder.SetRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), 0, TestRequiredInitialized);
-      Assert.IsTrue(builder.IsInitialized);
-    }
-
-    [Test]
-    public void UninitializedException() {
-      try {
-        TestRequired.CreateBuilder().Build();
-        Assert.Fail("Should have thrown an exception.");
-      } catch (UninitializedMessageException e) {
-        Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
-      }
-    }
-
-    [Test]
-    public void BuildPartial() {
-      // We're mostly testing that no exception is thrown.
-      TestRequired message = TestRequired.CreateBuilder().BuildPartial();
-      Assert.IsFalse(message.IsInitialized);
-    }
-
-    [Test]
-    public void NestedUninitializedException() {
-      try {
-        TestRequiredForeign.CreateBuilder()
-          .SetOptionalMessage(TestRequiredUninitialized)
-          .AddRepeatedMessage(TestRequiredUninitialized)
-          .AddRepeatedMessage(TestRequiredUninitialized)
-          .Build();
-        Assert.Fail("Should have thrown an exception.");
-      } catch (UninitializedMessageException e) {
-        Assert.AreEqual(
-          "Message missing required fields: " +
-          "optional_message.a, " +
-          "optional_message.b, " +
-          "optional_message.c, " +
-          "repeated_message[0].a, " +
-          "repeated_message[0].b, " +
-          "repeated_message[0].c, " +
-          "repeated_message[1].a, " +
-          "repeated_message[1].b, " +
-          "repeated_message[1].c",
-          e.Message);
-      }
-    }
-
-    [Test]
-    public void BuildNestedPartial() {
-      // We're mostly testing that no exception is thrown.
-      TestRequiredForeign message =
-        TestRequiredForeign.CreateBuilder()
-          .SetOptionalMessage(TestRequiredUninitialized)
-          .AddRepeatedMessage(TestRequiredUninitialized)
-          .AddRepeatedMessage(TestRequiredUninitialized)
-          .BuildPartial();
-      Assert.IsFalse(message.IsInitialized);
-    }
-
-    [Test]
-    public void ParseUnititialized() {
-      try {
-        TestRequired.ParseFrom(ByteString.Empty);
-        Assert.Fail("Should have thrown an exception.");
-      } catch (InvalidProtocolBufferException e) {
-        Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
-      }
-    }
-
-    [Test]
-    public void ParseNestedUnititialized() {
-      ByteString data =
-        TestRequiredForeign.CreateBuilder()
-          .SetOptionalMessage(TestRequiredUninitialized)
-          .AddRepeatedMessage(TestRequiredUninitialized)
-          .AddRepeatedMessage(TestRequiredUninitialized)
-          .BuildPartial().ToByteString();
-
-      try {
-        TestRequiredForeign.ParseFrom(data);
-        Assert.Fail("Should have thrown an exception.");
-      } catch (InvalidProtocolBufferException e) {
-        Assert.AreEqual(
-          "Message missing required fields: " +
-          "optional_message.a, " +
-          "optional_message.b, " +
-          "optional_message.c, " +
-          "repeated_message[0].a, " +
-          "repeated_message[0].b, " +
-          "repeated_message[0].c, " +
-          "repeated_message[1].a, " +
-          "repeated_message[1].b, " +
-          "repeated_message[1].c",
-          e.Message);
-      }
-    }
-
-    [Test]
-    public void DynamicUninitializedException() {
-      try {
-        DynamicMessage.CreateBuilder(TestRequired.Descriptor).Build();
-        Assert.Fail("Should have thrown an exception.");
-      } catch (UninitializedMessageException e) {
-        Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
-      }
-    }
-
-    [Test]
-    public void DynamicBuildPartial() {
-      // We're mostly testing that no exception is thrown.
-      DynamicMessage message = DynamicMessage.CreateBuilder(TestRequired.Descriptor).BuildPartial();
-      Assert.IsFalse(message.Initialized);
-    }
-
-    [Test]
-    public void DynamicParseUnititialized() {
-      try {
-        MessageDescriptor descriptor = TestRequired.Descriptor;
-        DynamicMessage.ParseFrom(descriptor, ByteString.Empty);
-        Assert.Fail("Should have thrown an exception.");
-      } catch (InvalidProtocolBufferException e) {
-        Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
-      }
-    }
-
-    [Test]
-    public void PackedTypesWrittenDirectlyToStream() {
-      TestPackedTypes message = new TestPackedTypes.Builder {PackedInt32List = {0, 1, 2}}.Build();
-      MemoryStream stream = new MemoryStream();
-      message.WriteTo(stream);
-      stream.Position = 0;
-      TestPackedTypes readMessage = TestPackedTypes.ParseFrom(stream);
-      Assert.AreEqual(message, readMessage);
-    }
-  }
-
-}
+#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 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 MessageTest
+    {
+        // =================================================================
+        // Message-merging tests.
+
+        private static readonly TestAllTypes MergeSource = new TestAllTypes.Builder
+                                                               {
+                                                                   OptionalInt32 = 1,
+                                                                   OptionalString = "foo",
+                                                                   OptionalForeignMessage =
+                                                                       ForeignMessage.DefaultInstance,
+                                                               }.AddRepeatedString("bar").Build();
+
+        private static readonly TestAllTypes MergeDest = new TestAllTypes.Builder
+                                                             {
+                                                                 OptionalInt64 = 2,
+                                                                 OptionalString = "baz",
+                                                                 OptionalForeignMessage =
+                                                                     new ForeignMessage.Builder {C = 3}.Build(),
+                                                             }.AddRepeatedString("qux").Build();
+
+        private const string MergeResultText =
+            "optional_int32: 1\n" +
+            "optional_int64: 2\n" +
+            "optional_string: \"foo\"\n" +
+            "optional_foreign_message {\n" +
+            "  c: 3\n" +
+            "}\n" +
+            "repeated_string: \"qux\"\n" +
+            "repeated_string: \"bar\"\n";
+
+        [Test]
+        public void MergeFrom()
+        {
+            TestAllTypes result = TestAllTypes.CreateBuilder(MergeDest).MergeFrom(MergeSource).Build();
+
+            Assert.AreEqual(MergeResultText, result.ToString());
+        }
+
+        /// <summary>
+        /// Test merging a DynamicMessage into a GeneratedMessage. 
+        /// As long as they have the same descriptor, this should work, but it is an
+        /// entirely different code path.
+        /// </summary>
+        [Test]
+        public void MergeFromDynamic()
+        {
+            TestAllTypes result = (TestAllTypes) TestAllTypes.CreateBuilder(MergeDest)
+                                                     .MergeFrom(DynamicMessage.CreateBuilder(MergeSource).Build())
+                                                     .Build();
+
+            Assert.AreEqual(MergeResultText, result.ToString());
+        }
+
+        /// <summary>
+        /// Test merging two DynamicMessages.
+        /// </summary>
+        [Test]
+        public void DynamicMergeFrom()
+        {
+            DynamicMessage result = (DynamicMessage) DynamicMessage.CreateBuilder(MergeDest)
+                                                         .MergeFrom(
+                                                             (DynamicMessage)
+                                                             DynamicMessage.CreateBuilder(MergeSource).Build())
+                                                         .Build();
+
+            Assert.AreEqual(MergeResultText, result.ToString());
+        }
+
+        // =================================================================
+        // Required-field-related tests.
+
+        private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;
+
+        private static readonly TestRequired TestRequiredInitialized = new TestRequired.Builder
+                                                                           {
+                                                                               A = 1,
+                                                                               B = 2,
+                                                                               C = 3
+                                                                           }.Build();
+
+        [Test]
+        public void Initialization()
+        {
+            TestRequired.Builder builder = TestRequired.CreateBuilder();
+
+            Assert.IsFalse(builder.IsInitialized);
+            builder.A = 1;
+            Assert.IsFalse(builder.IsInitialized);
+            builder.B = 1;
+            Assert.IsFalse(builder.IsInitialized);
+            builder.C = 1;
+            Assert.IsTrue(builder.IsInitialized);
+        }
+
+        [Test]
+        public void RequiredForeign()
+        {
+            TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
+
+            Assert.IsTrue(builder.IsInitialized);
+
+            builder.SetOptionalMessage(TestRequiredUninitialized);
+            Assert.IsFalse(builder.IsInitialized);
+
+            builder.SetOptionalMessage(TestRequiredInitialized);
+            Assert.IsTrue(builder.IsInitialized);
+
+            builder.AddRepeatedMessage(TestRequiredUninitialized);
+            Assert.IsFalse(builder.IsInitialized);
+
+            builder.SetRepeatedMessage(0, TestRequiredInitialized);
+            Assert.IsTrue(builder.IsInitialized);
+        }
+
+        [Test]
+        public void RequiredExtension()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+
+            Assert.IsTrue(builder.IsInitialized);
+
+            builder.SetExtension(TestRequired.Single, TestRequiredUninitialized);
+            Assert.IsFalse(builder.IsInitialized);
+
+            builder.SetExtension(TestRequired.Single, TestRequiredInitialized);
+            Assert.IsTrue(builder.IsInitialized);
+
+            builder.AddExtension(TestRequired.Multi, TestRequiredUninitialized);
+            Assert.IsFalse(builder.IsInitialized);
+
+            builder.SetExtension(TestRequired.Multi, 0, TestRequiredInitialized);
+            Assert.IsTrue(builder.IsInitialized);
+        }
+
+        [Test]
+        public void RequiredDynamic()
+        {
+            MessageDescriptor descriptor = TestRequired.Descriptor;
+            DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
+
+            Assert.IsFalse(builder.IsInitialized);
+            builder[descriptor.FindDescriptor<FieldDescriptor>("a")] = 1;
+            Assert.IsFalse(builder.IsInitialized);
+            builder[descriptor.FindDescriptor<FieldDescriptor>("b")] = 1;
+            Assert.IsFalse(builder.IsInitialized);
+            builder[descriptor.FindDescriptor<FieldDescriptor>("c")] = 1;
+            Assert.IsTrue(builder.IsInitialized);
+        }
+
+        [Test]
+        public void RequiredDynamicForeign()
+        {
+            MessageDescriptor descriptor = TestRequiredForeign.Descriptor;
+            DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
+
+            Assert.IsTrue(builder.IsInitialized);
+
+            builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredUninitialized;
+            Assert.IsFalse(builder.IsInitialized);
+
+            builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredInitialized;
+            Assert.IsTrue(builder.IsInitialized);
+
+            builder.AddRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"),
+                                     TestRequiredUninitialized);
+            Assert.IsFalse(builder.IsInitialized);
+
+            builder.SetRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), 0,
+                                     TestRequiredInitialized);
+            Assert.IsTrue(builder.IsInitialized);
+        }
+
+        [Test]
+        public void UninitializedException()
+        {
+            try
+            {
+                TestRequired.CreateBuilder().Build();
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (UninitializedMessageException e)
+            {
+                Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
+            }
+        }
+
+        [Test]
+        public void BuildPartial()
+        {
+            // We're mostly testing that no exception is thrown.
+            TestRequired message = TestRequired.CreateBuilder().BuildPartial();
+            Assert.IsFalse(message.IsInitialized);
+        }
+
+        [Test]
+        public void NestedUninitializedException()
+        {
+            try
+            {
+                TestRequiredForeign.CreateBuilder()
+                    .SetOptionalMessage(TestRequiredUninitialized)
+                    .AddRepeatedMessage(TestRequiredUninitialized)
+                    .AddRepeatedMessage(TestRequiredUninitialized)
+                    .Build();
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (UninitializedMessageException e)
+            {
+                Assert.AreEqual(
+                    "Message missing required fields: " +
+                    "optional_message.a, " +
+                    "optional_message.b, " +
+                    "optional_message.c, " +
+                    "repeated_message[0].a, " +
+                    "repeated_message[0].b, " +
+                    "repeated_message[0].c, " +
+                    "repeated_message[1].a, " +
+                    "repeated_message[1].b, " +
+                    "repeated_message[1].c",
+                    e.Message);
+            }
+        }
+
+        [Test]
+        public void BuildNestedPartial()
+        {
+            // We're mostly testing that no exception is thrown.
+            TestRequiredForeign message =
+                TestRequiredForeign.CreateBuilder()
+                    .SetOptionalMessage(TestRequiredUninitialized)
+                    .AddRepeatedMessage(TestRequiredUninitialized)
+                    .AddRepeatedMessage(TestRequiredUninitialized)
+                    .BuildPartial();
+            Assert.IsFalse(message.IsInitialized);
+        }
+
+        [Test]
+        public void ParseUnititialized()
+        {
+            try
+            {
+                TestRequired.ParseFrom(ByteString.Empty);
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (InvalidProtocolBufferException e)
+            {
+                Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
+            }
+        }
+
+        [Test]
+        public void ParseNestedUnititialized()
+        {
+            ByteString data =
+                TestRequiredForeign.CreateBuilder()
+                    .SetOptionalMessage(TestRequiredUninitialized)
+                    .AddRepeatedMessage(TestRequiredUninitialized)
+                    .AddRepeatedMessage(TestRequiredUninitialized)
+                    .BuildPartial().ToByteString();
+
+            try
+            {
+                TestRequiredForeign.ParseFrom(data);
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (InvalidProtocolBufferException e)
+            {
+                Assert.AreEqual(
+                    "Message missing required fields: " +
+                    "optional_message.a, " +
+                    "optional_message.b, " +
+                    "optional_message.c, " +
+                    "repeated_message[0].a, " +
+                    "repeated_message[0].b, " +
+                    "repeated_message[0].c, " +
+                    "repeated_message[1].a, " +
+                    "repeated_message[1].b, " +
+                    "repeated_message[1].c",
+                    e.Message);
+            }
+        }
+
+        [Test]
+        public void DynamicUninitializedException()
+        {
+            try
+            {
+                DynamicMessage.CreateBuilder(TestRequired.Descriptor).Build();
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (UninitializedMessageException e)
+            {
+                Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
+            }
+        }
+
+        [Test]
+        public void DynamicBuildPartial()
+        {
+            // We're mostly testing that no exception is thrown.
+            DynamicMessage message = DynamicMessage.CreateBuilder(TestRequired.Descriptor).BuildPartial();
+            Assert.IsFalse(message.Initialized);
+        }
+
+        [Test]
+        public void DynamicParseUnititialized()
+        {
+            try
+            {
+                MessageDescriptor descriptor = TestRequired.Descriptor;
+                DynamicMessage.ParseFrom(descriptor, ByteString.Empty);
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (InvalidProtocolBufferException e)
+            {
+                Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
+            }
+        }
+
+        [Test]
+        public void PackedTypesWrittenDirectlyToStream()
+        {
+            TestPackedTypes message = new TestPackedTypes.Builder {PackedInt32List = {0, 1, 2}}.Build();
+            MemoryStream stream = new MemoryStream();
+            message.WriteTo(stream);
+            stream.Position = 0;
+            TestPackedTypes readMessage = TestPackedTypes.ParseFrom(stream);
+            Assert.AreEqual(message, readMessage);
+        }
+    }
+}

+ 87 - 77
src/ProtocolBuffers.Test/MessageUtilTest.cs

@@ -1,77 +1,87 @@
-#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 Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class MessageUtilTest {
-
-    [Test]
-    [ExpectedException(typeof(ArgumentNullException))]
-    public void NullTypeName() {
-      MessageUtil.GetDefaultMessage((string)null);
-    }
-
-    [Test]
-    [ExpectedException(typeof(ArgumentException))]
-    public void InvalidTypeName() {
-      MessageUtil.GetDefaultMessage("invalidtypename");
-    }
-
-    [Test]
-    public void ValidTypeName() {
-      Assert.AreSame(TestAllTypes.DefaultInstance, MessageUtil.GetDefaultMessage(typeof(TestAllTypes).AssemblyQualifiedName));
-    }
-
-    [Test]
-    [ExpectedException(typeof(ArgumentNullException))]
-    public void NullType() {
-      MessageUtil.GetDefaultMessage((Type)null);
-    }
-
-    [Test]
-    [ExpectedException(typeof(ArgumentException))]
-    public void NonMessageType() {
-      MessageUtil.GetDefaultMessage(typeof(string));
-    }
-
-    [Test]
-    public void ValidType() {
-      Assert.AreSame(TestAllTypes.DefaultInstance, MessageUtil.GetDefaultMessage(typeof(TestAllTypes)));
-    }
-  }
-}
+#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 Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class MessageUtilTest
+    {
+        [Test]
+        [ExpectedException(typeof (ArgumentNullException))]
+        public void NullTypeName()
+        {
+            MessageUtil.GetDefaultMessage((string) null);
+        }
+
+        [Test]
+        [ExpectedException(typeof (ArgumentException))]
+        public void InvalidTypeName()
+        {
+            MessageUtil.GetDefaultMessage("invalidtypename");
+        }
+
+        [Test]
+        public void ValidTypeName()
+        {
+            Assert.AreSame(TestAllTypes.DefaultInstance,
+                           MessageUtil.GetDefaultMessage(typeof (TestAllTypes).AssemblyQualifiedName));
+        }
+
+        [Test]
+        [ExpectedException(typeof (ArgumentNullException))]
+        public void NullType()
+        {
+            MessageUtil.GetDefaultMessage((Type) null);
+        }
+
+        [Test]
+        [ExpectedException(typeof (ArgumentException))]
+        public void NonMessageType()
+        {
+            MessageUtil.GetDefaultMessage(typeof (string));
+        }
+
+        [Test]
+        public void ValidType()
+        {
+            Assert.AreSame(TestAllTypes.DefaultInstance, MessageUtil.GetDefaultMessage(typeof (TestAllTypes)));
+        }
+    }
+}

+ 71 - 65
src/ProtocolBuffers.Test/NameHelpersTest.cs

@@ -1,66 +1,72 @@
-#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 NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class NameHelpersTest {
-
-    [Test]
-    public void UnderscoresToPascalCase() {
-      Assert.AreEqual("FooBar", NameHelpers.UnderscoresToPascalCase("Foo_bar"));
-      Assert.AreEqual("FooBar", NameHelpers.UnderscoresToPascalCase("foo_bar"));
-      Assert.AreEqual("Foo0Bar", NameHelpers.UnderscoresToPascalCase("Foo0bar"));
-      Assert.AreEqual("FooBar", NameHelpers.UnderscoresToPascalCase("Foo_+_Bar"));
-    }
-
-    [Test]
-    public void UnderscoresToCamelCase() {
-      Assert.AreEqual("fooBar", NameHelpers.UnderscoresToCamelCase("Foo_bar"));
-      Assert.AreEqual("fooBar", NameHelpers.UnderscoresToCamelCase("foo_bar"));
-      Assert.AreEqual("foo0Bar", NameHelpers.UnderscoresToCamelCase("Foo0bar"));
-      Assert.AreEqual("fooBar", NameHelpers.UnderscoresToCamelCase("Foo_+_Bar"));
-    }
-
-    [Test]
-    public void StripSuffix() {
-      string text = "FooBar";
-      Assert.IsFalse(NameHelpers.StripSuffix(ref text, "Foo"));
-      Assert.AreEqual("FooBar", text);
-      Assert.IsTrue(NameHelpers.StripSuffix(ref text, "Bar"));
-      Assert.AreEqual("Foo", text);
-    }
-  }
+#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 NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class NameHelpersTest
+    {
+        [Test]
+        public void UnderscoresToPascalCase()
+        {
+            Assert.AreEqual("FooBar", NameHelpers.UnderscoresToPascalCase("Foo_bar"));
+            Assert.AreEqual("FooBar", NameHelpers.UnderscoresToPascalCase("foo_bar"));
+            Assert.AreEqual("Foo0Bar", NameHelpers.UnderscoresToPascalCase("Foo0bar"));
+            Assert.AreEqual("FooBar", NameHelpers.UnderscoresToPascalCase("Foo_+_Bar"));
+        }
+
+        [Test]
+        public void UnderscoresToCamelCase()
+        {
+            Assert.AreEqual("fooBar", NameHelpers.UnderscoresToCamelCase("Foo_bar"));
+            Assert.AreEqual("fooBar", NameHelpers.UnderscoresToCamelCase("foo_bar"));
+            Assert.AreEqual("foo0Bar", NameHelpers.UnderscoresToCamelCase("Foo0bar"));
+            Assert.AreEqual("fooBar", NameHelpers.UnderscoresToCamelCase("Foo_+_Bar"));
+        }
+
+        [Test]
+        public void StripSuffix()
+        {
+            string text = "FooBar";
+            Assert.IsFalse(NameHelpers.StripSuffix(ref text, "Foo"));
+            Assert.AreEqual("FooBar", text);
+            Assert.IsTrue(NameHelpers.StripSuffix(ref text, "Bar"));
+            Assert.AreEqual("Foo", text);
+        }
+    }
 }

+ 45 - 40
src/ProtocolBuffers.Test/Properties/AssemblyInfo.cs

@@ -1,40 +1,45 @@
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ProtocolBuffers.Test")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ProtocolBuffers.Test")]
-[assembly: AssemblyCopyright("Copyright ©  2008")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("54e627c3-daaa-4850-82cf-f25b7f097e78")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyVersion("2.3.0.277")]
-[assembly: AssemblyFileVersion("2.3.0.277")]
-// We don't really need CLSCompliance, but if the assembly builds with no warnings,
-// that means the generator is okay.
-[assembly: CLSCompliant(true)]
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("ProtocolBuffers.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ProtocolBuffers.Test")]
+[assembly: AssemblyCopyright("Copyright ©  2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("54e627c3-daaa-4850-82cf-f25b7f097e78")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("2.3.0.277")]
+
+[assembly: AssemblyVersion("2.3.0.277")]
+[assembly: AssemblyFileVersion("2.3.0.277")]
+// We don't really need CLSCompliance, but if the assembly builds with no warnings,
+// that means the generator is okay.
+
+[assembly: CLSCompliant(true)]

+ 990 - 936
src/ProtocolBuffers.Test/ReflectionTester.cs

@@ -1,936 +1,990 @@
-#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 Google.ProtocolBuffers.Descriptors;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Performs the same things that the methods of TestUtil do, but
-  /// via the reflection interface.  This is its own class because it needs
-  /// to know what descriptor to use.
-  /// </summary>
-  internal class ReflectionTester {
-    private readonly MessageDescriptor baseDescriptor;
-    private readonly ExtensionRegistry extensionRegistry;
-
-    private readonly FileDescriptor file;
-    private readonly FileDescriptor importFile;
-
-    private readonly MessageDescriptor optionalGroup;
-    private readonly MessageDescriptor repeatedGroup;
-    private readonly MessageDescriptor nestedMessage;
-    private readonly MessageDescriptor foreignMessage;
-    private readonly MessageDescriptor importMessage;
-
-    private readonly FieldDescriptor groupA;
-    private readonly FieldDescriptor repeatedGroupA;
-    private readonly FieldDescriptor nestedB;
-    private readonly FieldDescriptor foreignC;
-    private readonly FieldDescriptor importD;
-
-    private readonly EnumDescriptor nestedEnum;
-    private readonly EnumDescriptor foreignEnum;
-    private readonly EnumDescriptor importEnum;
-
-    private readonly EnumValueDescriptor nestedFoo;
-    private readonly EnumValueDescriptor nestedBar;
-    private readonly EnumValueDescriptor nestedBaz;
-    private readonly EnumValueDescriptor foreignFoo;
-    private readonly EnumValueDescriptor foreignBar;
-    private readonly EnumValueDescriptor foreignBaz;
-    private readonly EnumValueDescriptor importFoo;
-    private readonly EnumValueDescriptor importBar;
-    private readonly EnumValueDescriptor importBaz;
-
-    /// <summary>
-    /// Constructs an instance that will expect messages using the given
-    /// descriptor. Normally <paramref name="baseDescriptor"/> should be
-    /// a descriptor for TestAllTypes. However, if extensionRegistry is non-null,
-    /// then baseDescriptor should be for TestAllExtensions instead, and instead of
-    /// reading and writing normal fields, the tester will read and write extensions.
-    /// All of the TestAllExtensions extensions must be registered in the registry.
-    /// </summary>
-    private ReflectionTester(MessageDescriptor baseDescriptor,
-                            ExtensionRegistry extensionRegistry) {
-      this.baseDescriptor = baseDescriptor;
-      this.extensionRegistry = extensionRegistry;
-
-      this.file = baseDescriptor.File;
-      // TODO(jonskeet): We've got 2 dependencies, not 1 - because of the C# options. Hmm.
-      //      Assert.AreEqual(1, file.Dependencies.Count);
-      // TODO(jonskeet): Find dependency by name instead of number?
-      this.importFile = file.Dependencies[1];
-
-      MessageDescriptor testAllTypes;
-      if (baseDescriptor.Name == "TestAllTypes") {
-        testAllTypes = baseDescriptor;
-      } else {
-        testAllTypes = file.FindTypeByName<MessageDescriptor>("TestAllTypes");
-        Assert.IsNotNull(testAllTypes);
-      }
-
-      if (extensionRegistry == null) {
-        // Use testAllTypes, rather than baseDescriptor, to allow
-        // initialization using TestPackedTypes descriptors. These objects
-        // won't be used by the methods for packed fields.
-        this.optionalGroup =
-          testAllTypes.FindDescriptor<MessageDescriptor>("OptionalGroup");
-        this.repeatedGroup =
-          testAllTypes.FindDescriptor<MessageDescriptor>("RepeatedGroup");
-      } else {
-        this.optionalGroup =
-          file.FindTypeByName<MessageDescriptor>("OptionalGroup_extension");
-        this.repeatedGroup =
-          file.FindTypeByName<MessageDescriptor>("RepeatedGroup_extension");
-      }
-      this.nestedMessage = testAllTypes.FindDescriptor<MessageDescriptor>("NestedMessage");
-      this.foreignMessage = file.FindTypeByName<MessageDescriptor>("ForeignMessage");
-      this.importMessage = importFile.FindTypeByName<MessageDescriptor>("ImportMessage");
-
-      this.nestedEnum = testAllTypes.FindDescriptor<EnumDescriptor>("NestedEnum");
-      this.foreignEnum = file.FindTypeByName<EnumDescriptor>("ForeignEnum");
-      this.importEnum = importFile.FindTypeByName<EnumDescriptor>("ImportEnum");
-
-      Assert.IsNotNull(optionalGroup);
-      Assert.IsNotNull(repeatedGroup);
-      Assert.IsNotNull(nestedMessage);
-      Assert.IsNotNull(foreignMessage);
-      Assert.IsNotNull(importMessage);
-      Assert.IsNotNull(nestedEnum);
-      Assert.IsNotNull(foreignEnum);
-      Assert.IsNotNull(importEnum);
-
-      this.nestedB = nestedMessage.FindDescriptor<FieldDescriptor>("bb");
-      this.foreignC = foreignMessage.FindDescriptor<FieldDescriptor>("c");
-      this.importD = importMessage.FindDescriptor<FieldDescriptor>("d");
-      this.nestedFoo = nestedEnum.FindValueByName("FOO");
-      this.nestedBar = nestedEnum.FindValueByName("BAR");
-      this.nestedBaz = nestedEnum.FindValueByName("BAZ");
-      this.foreignFoo = foreignEnum.FindValueByName("FOREIGN_FOO");
-      this.foreignBar = foreignEnum.FindValueByName("FOREIGN_BAR");
-      this.foreignBaz = foreignEnum.FindValueByName("FOREIGN_BAZ");
-      this.importFoo = importEnum.FindValueByName("IMPORT_FOO");
-      this.importBar = importEnum.FindValueByName("IMPORT_BAR");
-      this.importBaz = importEnum.FindValueByName("IMPORT_BAZ");
-
-      this.groupA = optionalGroup.FindDescriptor<FieldDescriptor>("a");
-      this.repeatedGroupA = repeatedGroup.FindDescriptor<FieldDescriptor>("a");
-
-      Assert.IsNotNull(groupA);
-      Assert.IsNotNull(repeatedGroupA);
-      Assert.IsNotNull(nestedB);
-      Assert.IsNotNull(foreignC);
-      Assert.IsNotNull(importD);
-      Assert.IsNotNull(nestedFoo);
-      Assert.IsNotNull(nestedBar);
-      Assert.IsNotNull(nestedBaz);
-      Assert.IsNotNull(foreignFoo);
-      Assert.IsNotNull(foreignBar);
-      Assert.IsNotNull(foreignBaz);
-      Assert.IsNotNull(importFoo);
-      Assert.IsNotNull(importBar);
-      Assert.IsNotNull(importBaz);
-    }
-
-    /// <summary>
-    /// Creates an instance for the TestAllTypes message, with no extension registry.
-    /// </summary>
-    public static ReflectionTester CreateTestAllTypesInstance() {
-      return new ReflectionTester(TestAllTypes.Descriptor, null);
-    }
-
-    /// <summary>
-    /// Creates an instance for the TestAllExtensions message, with an
-    /// extension registry from TestUtil.CreateExtensionRegistry.
-    /// </summary>
-    public static ReflectionTester CreateTestAllExtensionsInstance() {
-      return new ReflectionTester(TestAllExtensions.Descriptor, TestUtil.CreateExtensionRegistry());
-    }
-
-    /// <summary>
-    /// Creates an instance for the TestPackedTypes message, with no extensions.
-    /// </summary>
-    public static ReflectionTester CreateTestPackedTypesInstance() {
-      return new ReflectionTester(TestPackedTypes.Descriptor, null);
-    }
-
-    /// <summary>
-    /// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
-    /// </summary>
-    private FieldDescriptor f(String name) {
-      FieldDescriptor result;
-      if (extensionRegistry == null) {
-        result = baseDescriptor.FindDescriptor<FieldDescriptor>(name);
-      } else {
-        result = file.FindTypeByName<FieldDescriptor>(name + "_extension");
-      }
-      Assert.IsNotNull(result);
-      return result;
-    }
-
-    /// <summary>
-    /// Calls parent.CreateBuilderForField() or uses the extension registry
-    /// to find an appropriate builder, depending on what type is being tested.
-    /// </summary>
-    private IBuilder CreateBuilderForField(IBuilder parent, FieldDescriptor field) {
-      if (extensionRegistry == null) {
-        return parent.CreateBuilderForField(field);
-      } else {
-        ExtensionInfo extension = extensionRegistry[field.ContainingType, field.FieldNumber];
-        Assert.IsNotNull(extension);
-        Assert.IsNotNull(extension.DefaultInstance);
-        return (IBuilder)extension.DefaultInstance.WeakCreateBuilderForType();
-      }
-    }
-
-    /// <summary>
-    /// Sets every field of the message to the values expected by
-    /// AssertAllFieldsSet, using the reflection interface.
-    /// </summary>
-    /// <param name="message"></param>
-    internal void SetAllFieldsViaReflection(IBuilder message) {
-      message[f("optional_int32")] = 101;
-      message[f("optional_int64")] = 102L;
-      message[f("optional_uint32")] = 103U;
-      message[f("optional_uint64")] = 104UL;
-      message[f("optional_sint32")] = 105;
-      message[f("optional_sint64")] = 106L;
-      message[f("optional_fixed32")] = 107U;
-      message[f("optional_fixed64")] = 108UL;
-      message[f("optional_sfixed32")] = 109;
-      message[f("optional_sfixed64")] = 110L;
-      message[f("optional_float")] = 111F;
-      message[f("optional_double")] = 112D;
-      message[f("optional_bool")] = true;
-      message[f("optional_string")] = "115";
-      message[f("optional_bytes")] = TestUtil.ToBytes("116");
-
-      message[f("optionalgroup")] = CreateBuilderForField(message, f("optionalgroup")).SetField(groupA, 117).WeakBuild();
-      message[f("optional_nested_message")] = CreateBuilderForField(message, f("optional_nested_message")).SetField(nestedB, 118).WeakBuild();
-      message[f("optional_foreign_message")] = CreateBuilderForField(message, f("optional_foreign_message")).SetField(foreignC, 119).WeakBuild();
-      message[f("optional_import_message")] = CreateBuilderForField(message, f("optional_import_message")).SetField(importD, 120).WeakBuild();
-
-      message[f("optional_nested_enum")] = nestedBaz;
-      message[f("optional_foreign_enum")] = foreignBaz;
-      message[f("optional_import_enum")] = importBaz;
-
-      message[f("optional_string_piece")] = "124";
-      message[f("optional_cord")] = "125";
-
-      // -----------------------------------------------------------------
-
-      message.WeakAddRepeatedField(f("repeated_int32"), 201);
-      message.WeakAddRepeatedField(f("repeated_int64"), 202L);
-      message.WeakAddRepeatedField(f("repeated_uint32"), 203U);
-      message.WeakAddRepeatedField(f("repeated_uint64"), 204UL);
-      message.WeakAddRepeatedField(f("repeated_sint32"), 205);
-      message.WeakAddRepeatedField(f("repeated_sint64"), 206L);
-      message.WeakAddRepeatedField(f("repeated_fixed32"), 207U);
-      message.WeakAddRepeatedField(f("repeated_fixed64"), 208UL);
-      message.WeakAddRepeatedField(f("repeated_sfixed32"), 209);
-      message.WeakAddRepeatedField(f("repeated_sfixed64"), 210L);
-      message.WeakAddRepeatedField(f("repeated_float"), 211F);
-      message.WeakAddRepeatedField(f("repeated_double"), 212D);
-      message.WeakAddRepeatedField(f("repeated_bool"), true);
-      message.WeakAddRepeatedField(f("repeated_string"), "215");
-      message.WeakAddRepeatedField(f("repeated_bytes"), TestUtil.ToBytes("216"));
-
-
-      message.WeakAddRepeatedField(f("repeatedgroup"), CreateBuilderForField(message, f("repeatedgroup")).SetField(repeatedGroupA, 217).WeakBuild());
-      message.WeakAddRepeatedField(f("repeated_nested_message"), CreateBuilderForField(message, f("repeated_nested_message")).SetField(nestedB, 218).WeakBuild());
-      message.WeakAddRepeatedField(f("repeated_foreign_message"), CreateBuilderForField(message, f("repeated_foreign_message")).SetField(foreignC, 219).WeakBuild());
-      message.WeakAddRepeatedField(f("repeated_import_message"), CreateBuilderForField(message, f("repeated_import_message")).SetField(importD, 220).WeakBuild());
-
-      message.WeakAddRepeatedField(f("repeated_nested_enum"), nestedBar);
-      message.WeakAddRepeatedField(f("repeated_foreign_enum"), foreignBar);
-      message.WeakAddRepeatedField(f("repeated_import_enum"), importBar);
-
-      message.WeakAddRepeatedField(f("repeated_string_piece"), "224");
-      message.WeakAddRepeatedField(f("repeated_cord"), "225");
-
-      // Add a second one of each field.
-      message.WeakAddRepeatedField(f("repeated_int32"), 301);
-      message.WeakAddRepeatedField(f("repeated_int64"), 302L);
-      message.WeakAddRepeatedField(f("repeated_uint32"), 303U);
-      message.WeakAddRepeatedField(f("repeated_uint64"), 304UL);
-      message.WeakAddRepeatedField(f("repeated_sint32"), 305);
-      message.WeakAddRepeatedField(f("repeated_sint64"), 306L);
-      message.WeakAddRepeatedField(f("repeated_fixed32"), 307U);
-      message.WeakAddRepeatedField(f("repeated_fixed64"), 308UL);
-      message.WeakAddRepeatedField(f("repeated_sfixed32"), 309);
-      message.WeakAddRepeatedField(f("repeated_sfixed64"), 310L);
-      message.WeakAddRepeatedField(f("repeated_float"), 311F);
-      message.WeakAddRepeatedField(f("repeated_double"), 312D);
-      message.WeakAddRepeatedField(f("repeated_bool"), false);
-      message.WeakAddRepeatedField(f("repeated_string"), "315");
-      message.WeakAddRepeatedField(f("repeated_bytes"), TestUtil.ToBytes("316"));
-
-      message.WeakAddRepeatedField(f("repeatedgroup"),
-        CreateBuilderForField(message, f("repeatedgroup"))
-               .SetField(repeatedGroupA, 317).WeakBuild());
-      message.WeakAddRepeatedField(f("repeated_nested_message"),
-        CreateBuilderForField(message, f("repeated_nested_message"))
-               .SetField(nestedB, 318).WeakBuild());
-      message.WeakAddRepeatedField(f("repeated_foreign_message"),
-        CreateBuilderForField(message, f("repeated_foreign_message"))
-               .SetField(foreignC, 319).WeakBuild());
-      message.WeakAddRepeatedField(f("repeated_import_message"),
-        CreateBuilderForField(message, f("repeated_import_message"))
-               .SetField(importD, 320).WeakBuild());
-
-      message.WeakAddRepeatedField(f("repeated_nested_enum"), nestedBaz);
-      message.WeakAddRepeatedField(f("repeated_foreign_enum"), foreignBaz);
-      message.WeakAddRepeatedField(f("repeated_import_enum"), importBaz);
-
-      message.WeakAddRepeatedField(f("repeated_string_piece"), "324");
-      message.WeakAddRepeatedField(f("repeated_cord"), "325");
-
-      // -----------------------------------------------------------------
-
-      message[f("default_int32")] = 401;
-      message[f("default_int64")] = 402L;
-      message[f("default_uint32")] = 403U;
-      message[f("default_uint64")] = 404UL;
-      message[f("default_sint32")] = 405;
-      message[f("default_sint64")] = 406L;
-      message[f("default_fixed32")] = 407U;
-      message[f("default_fixed64")] = 408UL;
-      message[f("default_sfixed32")] = 409;
-      message[f("default_sfixed64")] = 410L;
-      message[f("default_float")] = 411F;
-      message[f("default_double")] = 412D;
-      message[f("default_bool")] = false;
-      message[f("default_string")] = "415";
-      message[f("default_bytes")] = TestUtil.ToBytes("416");
-
-      message[f("default_nested_enum")] = nestedFoo;
-      message[f("default_foreign_enum")] = foreignFoo;
-      message[f("default_import_enum")] = importFoo;
-
-      message[f("default_string_piece")] = "424";
-      message[f("default_cord")] = "425";
-    }
-
-    // -------------------------------------------------------------------
-
-    /// <summary>
-    /// Modify the repeated fields of the specified message to contain the
-    /// values expected by AssertRepeatedFieldsModified, using the IBuilder
-    /// reflection interface.
-    /// </summary>
-    internal void ModifyRepeatedFieldsViaReflection(IBuilder message) {
-      message[f("repeated_int32"), 1] = 501;
-      message[f("repeated_int64"), 1] = 502L;
-      message[f("repeated_uint32"), 1] = 503U;
-      message[f("repeated_uint64"), 1] = 504UL;
-      message[f("repeated_sint32"), 1] = 505;
-      message[f("repeated_sint64"), 1] = 506L;
-      message[f("repeated_fixed32"), 1] = 507U;
-      message[f("repeated_fixed64"), 1] = 508UL;
-      message[f("repeated_sfixed32"), 1] = 509;
-      message[f("repeated_sfixed64"), 1] = 510L;
-      message[f("repeated_float"), 1] = 511F;
-      message[f("repeated_double"), 1] = 512D;
-      message[f("repeated_bool"), 1] = true;
-      message[f("repeated_string"), 1] = "515";
-      message.SetRepeatedField(f("repeated_bytes"), 1, TestUtil.ToBytes("516"));
-
-      message.SetRepeatedField(f("repeatedgroup"), 1, CreateBuilderForField(message, f("repeatedgroup")).SetField(repeatedGroupA, 517).WeakBuild());
-      message.SetRepeatedField(f("repeated_nested_message"), 1, CreateBuilderForField(message, f("repeated_nested_message")).SetField(nestedB, 518).WeakBuild());
-      message.SetRepeatedField(f("repeated_foreign_message"), 1, CreateBuilderForField(message, f("repeated_foreign_message")).SetField(foreignC, 519).WeakBuild());
-      message.SetRepeatedField(f("repeated_import_message"), 1, CreateBuilderForField(message, f("repeated_import_message")).SetField(importD, 520).WeakBuild());
-
-      message[f("repeated_nested_enum"), 1] = nestedFoo;
-      message[f("repeated_foreign_enum"), 1] = foreignFoo;
-      message[f("repeated_import_enum"), 1] = importFoo;
-
-      message[f("repeated_string_piece"), 1] = "524";
-      message[f("repeated_cord"), 1] = "525";
-    }
-
-    // -------------------------------------------------------------------
-
-    /// <summary>
-    /// Asserts that all fields of the specified message are set to the values
-    /// assigned by SetAllFields, using the IMessage reflection interface.
-    /// </summary>
-    public void AssertAllFieldsSetViaReflection(IMessage message) {
-      Assert.IsTrue(message.HasField(f("optional_int32")));
-      Assert.IsTrue(message.HasField(f("optional_int64")));
-      Assert.IsTrue(message.HasField(f("optional_uint32")));
-      Assert.IsTrue(message.HasField(f("optional_uint64")));
-      Assert.IsTrue(message.HasField(f("optional_sint32")));
-      Assert.IsTrue(message.HasField(f("optional_sint64")));
-      Assert.IsTrue(message.HasField(f("optional_fixed32")));
-      Assert.IsTrue(message.HasField(f("optional_fixed64")));
-      Assert.IsTrue(message.HasField(f("optional_sfixed32")));
-      Assert.IsTrue(message.HasField(f("optional_sfixed64")));
-      Assert.IsTrue(message.HasField(f("optional_float")));
-      Assert.IsTrue(message.HasField(f("optional_double")));
-      Assert.IsTrue(message.HasField(f("optional_bool")));
-      Assert.IsTrue(message.HasField(f("optional_string")));
-      Assert.IsTrue(message.HasField(f("optional_bytes")));
-
-      Assert.IsTrue(message.HasField(f("optionalgroup")));
-      Assert.IsTrue(message.HasField(f("optional_nested_message")));
-      Assert.IsTrue(message.HasField(f("optional_foreign_message")));
-      Assert.IsTrue(message.HasField(f("optional_import_message")));
-
-      Assert.IsTrue(((IMessage)message[f("optionalgroup")]).HasField(groupA));
-      Assert.IsTrue(((IMessage)message[f("optional_nested_message")]).HasField(nestedB));
-      Assert.IsTrue(((IMessage)message[f("optional_foreign_message")]).HasField(foreignC));
-      Assert.IsTrue(((IMessage)message[f("optional_import_message")]).HasField(importD));
-
-      Assert.IsTrue(message.HasField(f("optional_nested_enum")));
-      Assert.IsTrue(message.HasField(f("optional_foreign_enum")));
-      Assert.IsTrue(message.HasField(f("optional_import_enum")));
-
-      Assert.IsTrue(message.HasField(f("optional_string_piece")));
-      Assert.IsTrue(message.HasField(f("optional_cord")));
-
-      Assert.AreEqual(101, message[f("optional_int32")]);
-      Assert.AreEqual(102L, message[f("optional_int64")]);
-      Assert.AreEqual(103U, message[f("optional_uint32")]);
-      Assert.AreEqual(104UL, message[f("optional_uint64")]);
-      Assert.AreEqual(105, message[f("optional_sint32")]);
-      Assert.AreEqual(106L, message[f("optional_sint64")]);
-      Assert.AreEqual(107U, message[f("optional_fixed32")]);
-      Assert.AreEqual(108UL, message[f("optional_fixed64")]);
-      Assert.AreEqual(109, message[f("optional_sfixed32")]);
-      Assert.AreEqual(110L, message[f("optional_sfixed64")]);
-      Assert.AreEqual(111F, message[f("optional_float")]);
-      Assert.AreEqual(112D, message[f("optional_double")]);
-      Assert.AreEqual(true, message[f("optional_bool")]);
-      Assert.AreEqual("115", message[f("optional_string")]);
-      Assert.AreEqual(TestUtil.ToBytes("116"), message[f("optional_bytes")]);
-
-      Assert.AreEqual(117, ((IMessage)message[f("optionalgroup")])[groupA]);
-      Assert.AreEqual(118, ((IMessage)message[f("optional_nested_message")])[nestedB]);
-      Assert.AreEqual(119, ((IMessage)message[f("optional_foreign_message")])[foreignC]);
-      Assert.AreEqual(120, ((IMessage)message[f("optional_import_message")])[importD]);
-
-      Assert.AreEqual(nestedBaz, message[f("optional_nested_enum")]);
-      Assert.AreEqual(foreignBaz, message[f("optional_foreign_enum")]);
-      Assert.AreEqual(importBaz, message[f("optional_import_enum")]);
-
-      Assert.AreEqual("124", message[f("optional_string_piece")]);
-      Assert.AreEqual("125", message[f("optional_cord")]);
-
-      // -----------------------------------------------------------------
-
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_int32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_int64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_uint32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_uint64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sint32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sint64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_fixed32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_fixed64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sfixed32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sfixed64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_float")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_double")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_bool")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_string")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_bytes")));
-
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeatedgroup")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_nested_message")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_foreign_message")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_import_message")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_nested_enum")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_foreign_enum")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_import_enum")));
-
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_string_piece")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_cord")));
-
-      Assert.AreEqual(201, message[f("repeated_int32"), 0]);
-      Assert.AreEqual(202L, message[f("repeated_int64"), 0]);
-      Assert.AreEqual(203U, message[f("repeated_uint32"), 0]);
-      Assert.AreEqual(204UL, message[f("repeated_uint64"), 0]);
-      Assert.AreEqual(205, message[f("repeated_sint32"), 0]);
-      Assert.AreEqual(206L, message[f("repeated_sint64"), 0]);
-      Assert.AreEqual(207U, message[f("repeated_fixed32"), 0]);
-      Assert.AreEqual(208UL, message[f("repeated_fixed64"), 0]);
-      Assert.AreEqual(209, message[f("repeated_sfixed32"), 0]);
-      Assert.AreEqual(210L, message[f("repeated_sfixed64"), 0]);
-      Assert.AreEqual(211F, message[f("repeated_float"), 0]);
-      Assert.AreEqual(212D, message[f("repeated_double"), 0]);
-      Assert.AreEqual(true, message[f("repeated_bool"), 0]);
-      Assert.AreEqual("215", message[f("repeated_string"), 0]);
-      Assert.AreEqual(TestUtil.ToBytes("216"), message[f("repeated_bytes"), 0]);
-
-      Assert.AreEqual(217, ((IMessage)message[f("repeatedgroup"), 0])[repeatedGroupA]);
-      Assert.AreEqual(218, ((IMessage)message[f("repeated_nested_message"), 0])[nestedB]);
-      Assert.AreEqual(219, ((IMessage)message[f("repeated_foreign_message"), 0])[foreignC]);
-      Assert.AreEqual(220, ((IMessage)message[f("repeated_import_message"), 0])[importD]);
-
-      Assert.AreEqual(nestedBar, message[f("repeated_nested_enum"), 0]);
-      Assert.AreEqual(foreignBar, message[f("repeated_foreign_enum"), 0]);
-      Assert.AreEqual(importBar, message[f("repeated_import_enum"), 0]);
-
-      Assert.AreEqual("224", message[f("repeated_string_piece"), 0]);
-      Assert.AreEqual("225", message[f("repeated_cord"), 0]);
-
-      Assert.AreEqual(301, message[f("repeated_int32"), 1]);
-      Assert.AreEqual(302L, message[f("repeated_int64"), 1]);
-      Assert.AreEqual(303U, message[f("repeated_uint32"), 1]);
-      Assert.AreEqual(304UL, message[f("repeated_uint64"), 1]);
-      Assert.AreEqual(305, message[f("repeated_sint32"), 1]);
-      Assert.AreEqual(306L, message[f("repeated_sint64"), 1]);
-      Assert.AreEqual(307U, message[f("repeated_fixed32"), 1]);
-      Assert.AreEqual(308UL, message[f("repeated_fixed64"), 1]);
-      Assert.AreEqual(309, message[f("repeated_sfixed32"), 1]);
-      Assert.AreEqual(310L, message[f("repeated_sfixed64"), 1]);
-      Assert.AreEqual(311F, message[f("repeated_float"), 1]);
-      Assert.AreEqual(312D, message[f("repeated_double"), 1]);
-      Assert.AreEqual(false, message[f("repeated_bool"), 1]);
-      Assert.AreEqual("315", message[f("repeated_string"), 1]);
-      Assert.AreEqual(TestUtil.ToBytes("316"), message[f("repeated_bytes"), 1]);
-
-      Assert.AreEqual(317, ((IMessage)message[f("repeatedgroup"), 1])[repeatedGroupA]);
-      Assert.AreEqual(318, ((IMessage)message[f("repeated_nested_message"), 1])[nestedB]);
-      Assert.AreEqual(319, ((IMessage)message[f("repeated_foreign_message"), 1])[foreignC]);
-      Assert.AreEqual(320, ((IMessage)message[f("repeated_import_message"), 1])[importD]);
-
-      Assert.AreEqual(nestedBaz, message[f("repeated_nested_enum"), 1]);
-      Assert.AreEqual(foreignBaz, message[f("repeated_foreign_enum"), 1]);
-      Assert.AreEqual(importBaz, message[f("repeated_import_enum"), 1]);
-
-      Assert.AreEqual("324", message[f("repeated_string_piece"), 1]);
-      Assert.AreEqual("325", message[f("repeated_cord"), 1]);
-
-      // -----------------------------------------------------------------
-
-      Assert.IsTrue(message.HasField(f("default_int32")));
-      Assert.IsTrue(message.HasField(f("default_int64")));
-      Assert.IsTrue(message.HasField(f("default_uint32")));
-      Assert.IsTrue(message.HasField(f("default_uint64")));
-      Assert.IsTrue(message.HasField(f("default_sint32")));
-      Assert.IsTrue(message.HasField(f("default_sint64")));
-      Assert.IsTrue(message.HasField(f("default_fixed32")));
-      Assert.IsTrue(message.HasField(f("default_fixed64")));
-      Assert.IsTrue(message.HasField(f("default_sfixed32")));
-      Assert.IsTrue(message.HasField(f("default_sfixed64")));
-      Assert.IsTrue(message.HasField(f("default_float")));
-      Assert.IsTrue(message.HasField(f("default_double")));
-      Assert.IsTrue(message.HasField(f("default_bool")));
-      Assert.IsTrue(message.HasField(f("default_string")));
-      Assert.IsTrue(message.HasField(f("default_bytes")));
-
-      Assert.IsTrue(message.HasField(f("default_nested_enum")));
-      Assert.IsTrue(message.HasField(f("default_foreign_enum")));
-      Assert.IsTrue(message.HasField(f("default_import_enum")));
-
-      Assert.IsTrue(message.HasField(f("default_string_piece")));
-      Assert.IsTrue(message.HasField(f("default_cord")));
-
-      Assert.AreEqual(401, message[f("default_int32")]);
-      Assert.AreEqual(402L, message[f("default_int64")]);
-      Assert.AreEqual(403U, message[f("default_uint32")]);
-      Assert.AreEqual(404UL, message[f("default_uint64")]);
-      Assert.AreEqual(405, message[f("default_sint32")]);
-      Assert.AreEqual(406L, message[f("default_sint64")]);
-      Assert.AreEqual(407U, message[f("default_fixed32")]);
-      Assert.AreEqual(408UL, message[f("default_fixed64")]);
-      Assert.AreEqual(409, message[f("default_sfixed32")]);
-      Assert.AreEqual(410L, message[f("default_sfixed64")]);
-      Assert.AreEqual(411F, message[f("default_float")]);
-      Assert.AreEqual(412D, message[f("default_double")]);
-      Assert.AreEqual(false, message[f("default_bool")]);
-      Assert.AreEqual("415", message[f("default_string")]);
-      Assert.AreEqual(TestUtil.ToBytes("416"), message[f("default_bytes")]);
-
-      Assert.AreEqual(nestedFoo, message[f("default_nested_enum")]);
-      Assert.AreEqual(foreignFoo, message[f("default_foreign_enum")]);
-      Assert.AreEqual(importFoo, message[f("default_import_enum")]);
-
-      Assert.AreEqual("424", message[f("default_string_piece")]);
-      Assert.AreEqual("425", message[f("default_cord")]);
-    }
-
-    /// <summary>
-    /// Assert that all fields of the message are cleared, and that
-    /// getting the fields returns their default values, using the reflection interface.
-    /// </summary>
-    public void AssertClearViaReflection(IMessage message) {
-      // has_blah() should initially be false for all optional fields.
-      Assert.IsFalse(message.HasField(f("optional_int32")));
-      Assert.IsFalse(message.HasField(f("optional_int64")));
-      Assert.IsFalse(message.HasField(f("optional_uint32")));
-      Assert.IsFalse(message.HasField(f("optional_uint64")));
-      Assert.IsFalse(message.HasField(f("optional_sint32")));
-      Assert.IsFalse(message.HasField(f("optional_sint64")));
-      Assert.IsFalse(message.HasField(f("optional_fixed32")));
-      Assert.IsFalse(message.HasField(f("optional_fixed64")));
-      Assert.IsFalse(message.HasField(f("optional_sfixed32")));
-      Assert.IsFalse(message.HasField(f("optional_sfixed64")));
-      Assert.IsFalse(message.HasField(f("optional_float")));
-      Assert.IsFalse(message.HasField(f("optional_double")));
-      Assert.IsFalse(message.HasField(f("optional_bool")));
-      Assert.IsFalse(message.HasField(f("optional_string")));
-      Assert.IsFalse(message.HasField(f("optional_bytes")));
-
-      Assert.IsFalse(message.HasField(f("optionalgroup")));
-      Assert.IsFalse(message.HasField(f("optional_nested_message")));
-      Assert.IsFalse(message.HasField(f("optional_foreign_message")));
-      Assert.IsFalse(message.HasField(f("optional_import_message")));
-
-      Assert.IsFalse(message.HasField(f("optional_nested_enum")));
-      Assert.IsFalse(message.HasField(f("optional_foreign_enum")));
-      Assert.IsFalse(message.HasField(f("optional_import_enum")));
-
-      Assert.IsFalse(message.HasField(f("optional_string_piece")));
-      Assert.IsFalse(message.HasField(f("optional_cord")));
-
-      // Optional fields without defaults are set to zero or something like it.
-      Assert.AreEqual(0, message[f("optional_int32")]);
-      Assert.AreEqual(0L, message[f("optional_int64")]);
-      Assert.AreEqual(0U, message[f("optional_uint32")]);
-      Assert.AreEqual(0UL, message[f("optional_uint64")]);
-      Assert.AreEqual(0, message[f("optional_sint32")]);
-      Assert.AreEqual(0L, message[f("optional_sint64")]);
-      Assert.AreEqual(0U, message[f("optional_fixed32")]);
-      Assert.AreEqual(0UL, message[f("optional_fixed64")]);
-      Assert.AreEqual(0, message[f("optional_sfixed32")]);
-      Assert.AreEqual(0L, message[f("optional_sfixed64")]);
-      Assert.AreEqual(0F, message[f("optional_float")]);
-      Assert.AreEqual(0D, message[f("optional_double")]);
-      Assert.AreEqual(false, message[f("optional_bool")]);
-      Assert.AreEqual("", message[f("optional_string")]);
-      Assert.AreEqual(ByteString.Empty, message[f("optional_bytes")]);
-
-      // Embedded messages should also be clear.
-      Assert.IsFalse(((IMessage)message[f("optionalgroup")]).HasField(groupA));
-      Assert.IsFalse(((IMessage)message[f("optional_nested_message")])
-                         .HasField(nestedB));
-      Assert.IsFalse(((IMessage)message[f("optional_foreign_message")])
-                         .HasField(foreignC));
-      Assert.IsFalse(((IMessage)message[f("optional_import_message")])
-                         .HasField(importD));
-
-      Assert.AreEqual(0, ((IMessage)message[f("optionalgroup")])[groupA]);
-      Assert.AreEqual(0, ((IMessage)message[f("optional_nested_message")])[nestedB]);
-      Assert.AreEqual(0, ((IMessage)message[f("optional_foreign_message")])[foreignC]);
-      Assert.AreEqual(0, ((IMessage)message[f("optional_import_message")])[importD]);
-
-      // Enums without defaults are set to the first value in the enum.
-      Assert.AreEqual(nestedFoo, message[f("optional_nested_enum")]);
-      Assert.AreEqual(foreignFoo, message[f("optional_foreign_enum")]);
-      Assert.AreEqual(importFoo, message[f("optional_import_enum")]);
-
-      Assert.AreEqual("", message[f("optional_string_piece")]);
-      Assert.AreEqual("", message[f("optional_cord")]);
-
-      // Repeated fields are empty.
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_int32")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_int64")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_uint32")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_uint64")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_sint32")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_sint64")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_fixed32")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_fixed64")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_sfixed32")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_sfixed64")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_float")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_double")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_bool")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_string")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_bytes")));
-
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeatedgroup")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_nested_message")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_foreign_message")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_import_message")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_nested_enum")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_foreign_enum")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_import_enum")));
-
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_string_piece")));
-      Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_cord")));
-
-      // has_blah() should also be false for all default fields.
-      Assert.IsFalse(message.HasField(f("default_int32")));
-      Assert.IsFalse(message.HasField(f("default_int64")));
-      Assert.IsFalse(message.HasField(f("default_uint32")));
-      Assert.IsFalse(message.HasField(f("default_uint64")));
-      Assert.IsFalse(message.HasField(f("default_sint32")));
-      Assert.IsFalse(message.HasField(f("default_sint64")));
-      Assert.IsFalse(message.HasField(f("default_fixed32")));
-      Assert.IsFalse(message.HasField(f("default_fixed64")));
-      Assert.IsFalse(message.HasField(f("default_sfixed32")));
-      Assert.IsFalse(message.HasField(f("default_sfixed64")));
-      Assert.IsFalse(message.HasField(f("default_float")));
-      Assert.IsFalse(message.HasField(f("default_double")));
-      Assert.IsFalse(message.HasField(f("default_bool")));
-      Assert.IsFalse(message.HasField(f("default_string")));
-      Assert.IsFalse(message.HasField(f("default_bytes")));
-
-      Assert.IsFalse(message.HasField(f("default_nested_enum")));
-      Assert.IsFalse(message.HasField(f("default_foreign_enum")));
-      Assert.IsFalse(message.HasField(f("default_import_enum")));
-
-      Assert.IsFalse(message.HasField(f("default_string_piece")));
-      Assert.IsFalse(message.HasField(f("default_cord")));
-
-      // Fields with defaults have their default values (duh).
-      Assert.AreEqual(41, message[f("default_int32")]);
-      Assert.AreEqual(42L, message[f("default_int64")]);
-      Assert.AreEqual(43U, message[f("default_uint32")]);
-      Assert.AreEqual(44UL, message[f("default_uint64")]);
-      Assert.AreEqual(-45, message[f("default_sint32")]);
-      Assert.AreEqual(46L, message[f("default_sint64")]);
-      Assert.AreEqual(47U, message[f("default_fixed32")]);
-      Assert.AreEqual(48UL, message[f("default_fixed64")]);
-      Assert.AreEqual(49, message[f("default_sfixed32")]);
-      Assert.AreEqual(-50L, message[f("default_sfixed64")]);
-      Assert.AreEqual(51.5F, message[f("default_float")]);
-      Assert.AreEqual(52e3D, message[f("default_double")]);
-      Assert.AreEqual(true, message[f("default_bool")]);
-      Assert.AreEqual("hello", message[f("default_string")]);
-      Assert.AreEqual(TestUtil.ToBytes("world"), message[f("default_bytes")]);
-
-      Assert.AreEqual(nestedBar, message[f("default_nested_enum")]);
-      Assert.AreEqual(foreignBar, message[f("default_foreign_enum")]);
-      Assert.AreEqual(importBar, message[f("default_import_enum")]);
-
-      Assert.AreEqual("abc", message[f("default_string_piece")]);
-      Assert.AreEqual("123", message[f("default_cord")]);
-    }
-
-    // ---------------------------------------------------------------
-
-    internal void AssertRepeatedFieldsModifiedViaReflection(IMessage message) {
-      // ModifyRepeatedFields only sets the second repeated element of each
-      // field.  In addition to verifying this, we also verify that the first
-      // element and size were *not* modified.
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_int32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_int64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_uint32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_uint64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sint32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sint64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_fixed32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_fixed64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sfixed32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sfixed64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_float")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_double")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_bool")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_string")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_bytes")));
-
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeatedgroup")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_nested_message")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_foreign_message")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_import_message")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_nested_enum")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_foreign_enum")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_import_enum")));
-
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_string_piece")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_cord")));
-
-      Assert.AreEqual(201, message[f("repeated_int32"), 0]);
-      Assert.AreEqual(202L, message[f("repeated_int64"), 0]);
-      Assert.AreEqual(203U, message[f("repeated_uint32"), 0]);
-      Assert.AreEqual(204UL, message[f("repeated_uint64"), 0]);
-      Assert.AreEqual(205, message[f("repeated_sint32"), 0]);
-      Assert.AreEqual(206L, message[f("repeated_sint64"), 0]);
-      Assert.AreEqual(207U, message[f("repeated_fixed32"), 0]);
-      Assert.AreEqual(208UL, message[f("repeated_fixed64"), 0]);
-      Assert.AreEqual(209, message[f("repeated_sfixed32"), 0]);
-      Assert.AreEqual(210L, message[f("repeated_sfixed64"), 0]);
-      Assert.AreEqual(211F, message[f("repeated_float"), 0]);
-      Assert.AreEqual(212D, message[f("repeated_double"), 0]);
-      Assert.AreEqual(true, message[f("repeated_bool"), 0]);
-      Assert.AreEqual("215", message[f("repeated_string"), 0]);
-      Assert.AreEqual(TestUtil.ToBytes("216"), message[f("repeated_bytes"), 0]);
-
-      Assert.AreEqual(217, ((IMessage)message[f("repeatedgroup"), 0])[repeatedGroupA]);
-      Assert.AreEqual(218, ((IMessage)message[f("repeated_nested_message"), 0])[nestedB]);
-      Assert.AreEqual(219, ((IMessage)message[f("repeated_foreign_message"), 0])[foreignC]);
-      Assert.AreEqual(220, ((IMessage)message[f("repeated_import_message"), 0])[importD]);
-
-      Assert.AreEqual(nestedBar, message[f("repeated_nested_enum"), 0]);
-      Assert.AreEqual(foreignBar, message[f("repeated_foreign_enum"), 0]);
-      Assert.AreEqual(importBar, message[f("repeated_import_enum"), 0]);
-
-      Assert.AreEqual("224", message[f("repeated_string_piece"), 0]);
-      Assert.AreEqual("225", message[f("repeated_cord"), 0]);
-
-      Assert.AreEqual(501, message[f("repeated_int32"), 1]);
-      Assert.AreEqual(502L, message[f("repeated_int64"), 1]);
-      Assert.AreEqual(503U, message[f("repeated_uint32"), 1]);
-      Assert.AreEqual(504UL, message[f("repeated_uint64"), 1]);
-      Assert.AreEqual(505, message[f("repeated_sint32"), 1]);
-      Assert.AreEqual(506L, message[f("repeated_sint64"), 1]);
-      Assert.AreEqual(507U, message[f("repeated_fixed32"), 1]);
-      Assert.AreEqual(508UL, message[f("repeated_fixed64"), 1]);
-      Assert.AreEqual(509, message[f("repeated_sfixed32"), 1]);
-      Assert.AreEqual(510L, message[f("repeated_sfixed64"), 1]);
-      Assert.AreEqual(511F, message[f("repeated_float"), 1]);
-      Assert.AreEqual(512D, message[f("repeated_double"), 1]);
-      Assert.AreEqual(true, message[f("repeated_bool"), 1]);
-      Assert.AreEqual("515", message[f("repeated_string"), 1]);
-      Assert.AreEqual(TestUtil.ToBytes("516"), message[f("repeated_bytes"), 1]);
-
-      Assert.AreEqual(517, ((IMessage)message[f("repeatedgroup"), 1])[repeatedGroupA]);
-      Assert.AreEqual(518, ((IMessage)message[f("repeated_nested_message"), 1])[nestedB]);
-      Assert.AreEqual(519, ((IMessage)message[f("repeated_foreign_message"), 1])[foreignC]);
-      Assert.AreEqual(520, ((IMessage)message[f("repeated_import_message"), 1])[importD]);
-
-      Assert.AreEqual(nestedFoo, message[f("repeated_nested_enum"), 1]);
-      Assert.AreEqual(foreignFoo, message[f("repeated_foreign_enum"), 1]);
-      Assert.AreEqual(importFoo, message[f("repeated_import_enum"), 1]);
-
-      Assert.AreEqual("524", message[f("repeated_string_piece"), 1]);
-      Assert.AreEqual("525", message[f("repeated_cord"), 1]);
-    }
-
-    /// <summary>
-    /// Verifies that the reflection setters for the given Builder object throw an
-    /// ArgumentNullException if they are passed a null value. 
-    /// </summary>
-    public void AssertReflectionSettersRejectNull(IBuilder builder) {
-      TestUtil.AssertArgumentNullException(() => builder[f("optional_string")] = null);
-      TestUtil.AssertArgumentNullException(() => builder[f("optional_bytes")] = null);
-      TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_enum")] = null);
-      TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_message")] = null);
-      TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_message")] = null);
-      TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_string"), null));
-      TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_bytes"), null));
-      TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_nested_enum"), null));
-      TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_nested_message"), null));
-    }
-
-    /// <summary>
-    /// Verifies that the reflection repeated setters for the given Builder object throw an
-    /// ArgumentNullException if they are passed a null value.
-    /// </summary>
-    public void AssertReflectionRepeatedSettersRejectNull(IBuilder builder) {
-      builder.WeakAddRepeatedField(f("repeated_string"), "one");
-      TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_string"), 0, null));
-      builder.WeakAddRepeatedField(f("repeated_bytes"), TestUtil.ToBytes("one"));
-      TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_bytes"), 0, null));
-      builder.WeakAddRepeatedField(f("repeated_nested_enum"), nestedBaz);
-      TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_nested_enum"), 0, null));
-      builder.WeakAddRepeatedField(f("repeated_nested_message"),
-          new TestAllTypes.Types.NestedMessage.Builder { Bb = 218 }.Build());
-      TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_nested_message"), 0, null));
-    }
-
-    public void SetPackedFieldsViaReflection(IBuilder message) {
-      message.WeakAddRepeatedField(f("packed_int32"), 601);
-      message.WeakAddRepeatedField(f("packed_int64"), 602L);
-      message.WeakAddRepeatedField(f("packed_uint32"), 603U);
-      message.WeakAddRepeatedField(f("packed_uint64"), 604UL);
-      message.WeakAddRepeatedField(f("packed_sint32"), 605);
-      message.WeakAddRepeatedField(f("packed_sint64"), 606L);
-      message.WeakAddRepeatedField(f("packed_fixed32"), 607U);
-      message.WeakAddRepeatedField(f("packed_fixed64"), 608UL);
-      message.WeakAddRepeatedField(f("packed_sfixed32"), 609);
-      message.WeakAddRepeatedField(f("packed_sfixed64"), 610L);
-      message.WeakAddRepeatedField(f("packed_float"), 611F);
-      message.WeakAddRepeatedField(f("packed_double"), 612D);
-      message.WeakAddRepeatedField(f("packed_bool"), true);
-      message.WeakAddRepeatedField(f("packed_enum"), foreignBar);
-      // Add a second one of each field.
-      message.WeakAddRepeatedField(f("packed_int32"), 701);
-      message.WeakAddRepeatedField(f("packed_int64"), 702L);
-      message.WeakAddRepeatedField(f("packed_uint32"), 703U);
-      message.WeakAddRepeatedField(f("packed_uint64"), 704UL);
-      message.WeakAddRepeatedField(f("packed_sint32"), 705);
-      message.WeakAddRepeatedField(f("packed_sint64"), 706L);
-      message.WeakAddRepeatedField(f("packed_fixed32"), 707U);
-      message.WeakAddRepeatedField(f("packed_fixed64"), 708UL);
-      message.WeakAddRepeatedField(f("packed_sfixed32"), 709);
-      message.WeakAddRepeatedField(f("packed_sfixed64"), 710L);
-      message.WeakAddRepeatedField(f("packed_float"), 711F);
-      message.WeakAddRepeatedField(f("packed_double"), 712D);
-      message.WeakAddRepeatedField(f("packed_bool"), false);
-      message.WeakAddRepeatedField(f("packed_enum"), foreignBaz);
-    }
-
-    public void AssertPackedFieldsSetViaReflection(IMessage message) {
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_int32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_int64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_uint32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_uint64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_sint32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_sint64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_fixed32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_fixed64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_sfixed32")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_sfixed64")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_float")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_double")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_bool")));
-      Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_enum")));
-      Assert.AreEqual(601, message[f("packed_int32"), 0]);
-      Assert.AreEqual(602L, message[f("packed_int64"), 0]);
-      Assert.AreEqual(603, message[f("packed_uint32"), 0]);
-      Assert.AreEqual(604L, message[f("packed_uint64"), 0]);
-      Assert.AreEqual(605, message[f("packed_sint32"), 0]);
-      Assert.AreEqual(606L, message[f("packed_sint64"), 0]);
-      Assert.AreEqual(607, message[f("packed_fixed32"), 0]);
-      Assert.AreEqual(608L, message[f("packed_fixed64"), 0]);
-      Assert.AreEqual(609, message[f("packed_sfixed32"), 0]);
-      Assert.AreEqual(610L, message[f("packed_sfixed64"), 0]);
-      Assert.AreEqual(611F, message[f("packed_float"), 0]);
-      Assert.AreEqual(612D, message[f("packed_double"), 0]);
-      Assert.AreEqual(true, message[f("packed_bool"), 0]);
-      Assert.AreEqual(foreignBar, message[f("packed_enum"), 0]);
-      Assert.AreEqual(701, message[f("packed_int32"), 1]);
-      Assert.AreEqual(702L, message[f("packed_int64"), 1]);
-      Assert.AreEqual(703, message[f("packed_uint32"), 1]);
-      Assert.AreEqual(704L, message[f("packed_uint64"), 1]);
-      Assert.AreEqual(705, message[f("packed_sint32"), 1]);
-      Assert.AreEqual(706L, message[f("packed_sint64"), 1]);
-      Assert.AreEqual(707, message[f("packed_fixed32"), 1]);
-      Assert.AreEqual(708L, message[f("packed_fixed64"), 1]);
-      Assert.AreEqual(709, message[f("packed_sfixed32"), 1]);
-      Assert.AreEqual(710L, message[f("packed_sfixed64"), 1]);
-      Assert.AreEqual(711F, message[f("packed_float"), 1]);
-      Assert.AreEqual(712D, message[f("packed_double"), 1]);
-      Assert.AreEqual(false, message[f("packed_bool"), 1]);
-      Assert.AreEqual(foreignBaz, message[f("packed_enum"), 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 Google.ProtocolBuffers.Descriptors;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Performs the same things that the methods of TestUtil do, but
+    /// via the reflection interface.  This is its own class because it needs
+    /// to know what descriptor to use.
+    /// </summary>
+    internal class ReflectionTester
+    {
+        private readonly MessageDescriptor baseDescriptor;
+        private readonly ExtensionRegistry extensionRegistry;
+
+        private readonly FileDescriptor file;
+        private readonly FileDescriptor importFile;
+
+        private readonly MessageDescriptor optionalGroup;
+        private readonly MessageDescriptor repeatedGroup;
+        private readonly MessageDescriptor nestedMessage;
+        private readonly MessageDescriptor foreignMessage;
+        private readonly MessageDescriptor importMessage;
+
+        private readonly FieldDescriptor groupA;
+        private readonly FieldDescriptor repeatedGroupA;
+        private readonly FieldDescriptor nestedB;
+        private readonly FieldDescriptor foreignC;
+        private readonly FieldDescriptor importD;
+
+        private readonly EnumDescriptor nestedEnum;
+        private readonly EnumDescriptor foreignEnum;
+        private readonly EnumDescriptor importEnum;
+
+        private readonly EnumValueDescriptor nestedFoo;
+        private readonly EnumValueDescriptor nestedBar;
+        private readonly EnumValueDescriptor nestedBaz;
+        private readonly EnumValueDescriptor foreignFoo;
+        private readonly EnumValueDescriptor foreignBar;
+        private readonly EnumValueDescriptor foreignBaz;
+        private readonly EnumValueDescriptor importFoo;
+        private readonly EnumValueDescriptor importBar;
+        private readonly EnumValueDescriptor importBaz;
+
+        /// <summary>
+        /// Constructs an instance that will expect messages using the given
+        /// descriptor. Normally <paramref name="baseDescriptor"/> should be
+        /// a descriptor for TestAllTypes. However, if extensionRegistry is non-null,
+        /// then baseDescriptor should be for TestAllExtensions instead, and instead of
+        /// reading and writing normal fields, the tester will read and write extensions.
+        /// All of the TestAllExtensions extensions must be registered in the registry.
+        /// </summary>
+        private ReflectionTester(MessageDescriptor baseDescriptor,
+                                 ExtensionRegistry extensionRegistry)
+        {
+            this.baseDescriptor = baseDescriptor;
+            this.extensionRegistry = extensionRegistry;
+
+            this.file = baseDescriptor.File;
+            // TODO(jonskeet): We've got 2 dependencies, not 1 - because of the C# options. Hmm.
+            //      Assert.AreEqual(1, file.Dependencies.Count);
+            // TODO(jonskeet): Find dependency by name instead of number?
+            this.importFile = file.Dependencies[1];
+
+            MessageDescriptor testAllTypes;
+            if (baseDescriptor.Name == "TestAllTypes")
+            {
+                testAllTypes = baseDescriptor;
+            }
+            else
+            {
+                testAllTypes = file.FindTypeByName<MessageDescriptor>("TestAllTypes");
+                Assert.IsNotNull(testAllTypes);
+            }
+
+            if (extensionRegistry == null)
+            {
+                // Use testAllTypes, rather than baseDescriptor, to allow
+                // initialization using TestPackedTypes descriptors. These objects
+                // won't be used by the methods for packed fields.
+                this.optionalGroup =
+                    testAllTypes.FindDescriptor<MessageDescriptor>("OptionalGroup");
+                this.repeatedGroup =
+                    testAllTypes.FindDescriptor<MessageDescriptor>("RepeatedGroup");
+            }
+            else
+            {
+                this.optionalGroup =
+                    file.FindTypeByName<MessageDescriptor>("OptionalGroup_extension");
+                this.repeatedGroup =
+                    file.FindTypeByName<MessageDescriptor>("RepeatedGroup_extension");
+            }
+            this.nestedMessage = testAllTypes.FindDescriptor<MessageDescriptor>("NestedMessage");
+            this.foreignMessage = file.FindTypeByName<MessageDescriptor>("ForeignMessage");
+            this.importMessage = importFile.FindTypeByName<MessageDescriptor>("ImportMessage");
+
+            this.nestedEnum = testAllTypes.FindDescriptor<EnumDescriptor>("NestedEnum");
+            this.foreignEnum = file.FindTypeByName<EnumDescriptor>("ForeignEnum");
+            this.importEnum = importFile.FindTypeByName<EnumDescriptor>("ImportEnum");
+
+            Assert.IsNotNull(optionalGroup);
+            Assert.IsNotNull(repeatedGroup);
+            Assert.IsNotNull(nestedMessage);
+            Assert.IsNotNull(foreignMessage);
+            Assert.IsNotNull(importMessage);
+            Assert.IsNotNull(nestedEnum);
+            Assert.IsNotNull(foreignEnum);
+            Assert.IsNotNull(importEnum);
+
+            this.nestedB = nestedMessage.FindDescriptor<FieldDescriptor>("bb");
+            this.foreignC = foreignMessage.FindDescriptor<FieldDescriptor>("c");
+            this.importD = importMessage.FindDescriptor<FieldDescriptor>("d");
+            this.nestedFoo = nestedEnum.FindValueByName("FOO");
+            this.nestedBar = nestedEnum.FindValueByName("BAR");
+            this.nestedBaz = nestedEnum.FindValueByName("BAZ");
+            this.foreignFoo = foreignEnum.FindValueByName("FOREIGN_FOO");
+            this.foreignBar = foreignEnum.FindValueByName("FOREIGN_BAR");
+            this.foreignBaz = foreignEnum.FindValueByName("FOREIGN_BAZ");
+            this.importFoo = importEnum.FindValueByName("IMPORT_FOO");
+            this.importBar = importEnum.FindValueByName("IMPORT_BAR");
+            this.importBaz = importEnum.FindValueByName("IMPORT_BAZ");
+
+            this.groupA = optionalGroup.FindDescriptor<FieldDescriptor>("a");
+            this.repeatedGroupA = repeatedGroup.FindDescriptor<FieldDescriptor>("a");
+
+            Assert.IsNotNull(groupA);
+            Assert.IsNotNull(repeatedGroupA);
+            Assert.IsNotNull(nestedB);
+            Assert.IsNotNull(foreignC);
+            Assert.IsNotNull(importD);
+            Assert.IsNotNull(nestedFoo);
+            Assert.IsNotNull(nestedBar);
+            Assert.IsNotNull(nestedBaz);
+            Assert.IsNotNull(foreignFoo);
+            Assert.IsNotNull(foreignBar);
+            Assert.IsNotNull(foreignBaz);
+            Assert.IsNotNull(importFoo);
+            Assert.IsNotNull(importBar);
+            Assert.IsNotNull(importBaz);
+        }
+
+        /// <summary>
+        /// Creates an instance for the TestAllTypes message, with no extension registry.
+        /// </summary>
+        public static ReflectionTester CreateTestAllTypesInstance()
+        {
+            return new ReflectionTester(TestAllTypes.Descriptor, null);
+        }
+
+        /// <summary>
+        /// Creates an instance for the TestAllExtensions message, with an
+        /// extension registry from TestUtil.CreateExtensionRegistry.
+        /// </summary>
+        public static ReflectionTester CreateTestAllExtensionsInstance()
+        {
+            return new ReflectionTester(TestAllExtensions.Descriptor, TestUtil.CreateExtensionRegistry());
+        }
+
+        /// <summary>
+        /// Creates an instance for the TestPackedTypes message, with no extensions.
+        /// </summary>
+        public static ReflectionTester CreateTestPackedTypesInstance()
+        {
+            return new ReflectionTester(TestPackedTypes.Descriptor, null);
+        }
+
+        /// <summary>
+        /// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+        /// </summary>
+        private FieldDescriptor f(String name)
+        {
+            FieldDescriptor result;
+            if (extensionRegistry == null)
+            {
+                result = baseDescriptor.FindDescriptor<FieldDescriptor>(name);
+            }
+            else
+            {
+                result = file.FindTypeByName<FieldDescriptor>(name + "_extension");
+            }
+            Assert.IsNotNull(result);
+            return result;
+        }
+
+        /// <summary>
+        /// Calls parent.CreateBuilderForField() or uses the extension registry
+        /// to find an appropriate builder, depending on what type is being tested.
+        /// </summary>
+        private IBuilder CreateBuilderForField(IBuilder parent, FieldDescriptor field)
+        {
+            if (extensionRegistry == null)
+            {
+                return parent.CreateBuilderForField(field);
+            }
+            else
+            {
+                ExtensionInfo extension = extensionRegistry[field.ContainingType, field.FieldNumber];
+                Assert.IsNotNull(extension);
+                Assert.IsNotNull(extension.DefaultInstance);
+                return (IBuilder) extension.DefaultInstance.WeakCreateBuilderForType();
+            }
+        }
+
+        /// <summary>
+        /// Sets every field of the message to the values expected by
+        /// AssertAllFieldsSet, using the reflection interface.
+        /// </summary>
+        /// <param name="message"></param>
+        internal void SetAllFieldsViaReflection(IBuilder message)
+        {
+            message[f("optional_int32")] = 101;
+            message[f("optional_int64")] = 102L;
+            message[f("optional_uint32")] = 103U;
+            message[f("optional_uint64")] = 104UL;
+            message[f("optional_sint32")] = 105;
+            message[f("optional_sint64")] = 106L;
+            message[f("optional_fixed32")] = 107U;
+            message[f("optional_fixed64")] = 108UL;
+            message[f("optional_sfixed32")] = 109;
+            message[f("optional_sfixed64")] = 110L;
+            message[f("optional_float")] = 111F;
+            message[f("optional_double")] = 112D;
+            message[f("optional_bool")] = true;
+            message[f("optional_string")] = "115";
+            message[f("optional_bytes")] = TestUtil.ToBytes("116");
+
+            message[f("optionalgroup")] =
+                CreateBuilderForField(message, f("optionalgroup")).SetField(groupA, 117).WeakBuild();
+            message[f("optional_nested_message")] =
+                CreateBuilderForField(message, f("optional_nested_message")).SetField(nestedB, 118).WeakBuild();
+            message[f("optional_foreign_message")] =
+                CreateBuilderForField(message, f("optional_foreign_message")).SetField(foreignC, 119).WeakBuild();
+            message[f("optional_import_message")] =
+                CreateBuilderForField(message, f("optional_import_message")).SetField(importD, 120).WeakBuild();
+
+            message[f("optional_nested_enum")] = nestedBaz;
+            message[f("optional_foreign_enum")] = foreignBaz;
+            message[f("optional_import_enum")] = importBaz;
+
+            message[f("optional_string_piece")] = "124";
+            message[f("optional_cord")] = "125";
+
+            // -----------------------------------------------------------------
+
+            message.WeakAddRepeatedField(f("repeated_int32"), 201);
+            message.WeakAddRepeatedField(f("repeated_int64"), 202L);
+            message.WeakAddRepeatedField(f("repeated_uint32"), 203U);
+            message.WeakAddRepeatedField(f("repeated_uint64"), 204UL);
+            message.WeakAddRepeatedField(f("repeated_sint32"), 205);
+            message.WeakAddRepeatedField(f("repeated_sint64"), 206L);
+            message.WeakAddRepeatedField(f("repeated_fixed32"), 207U);
+            message.WeakAddRepeatedField(f("repeated_fixed64"), 208UL);
+            message.WeakAddRepeatedField(f("repeated_sfixed32"), 209);
+            message.WeakAddRepeatedField(f("repeated_sfixed64"), 210L);
+            message.WeakAddRepeatedField(f("repeated_float"), 211F);
+            message.WeakAddRepeatedField(f("repeated_double"), 212D);
+            message.WeakAddRepeatedField(f("repeated_bool"), true);
+            message.WeakAddRepeatedField(f("repeated_string"), "215");
+            message.WeakAddRepeatedField(f("repeated_bytes"), TestUtil.ToBytes("216"));
+
+
+            message.WeakAddRepeatedField(f("repeatedgroup"),
+                                         CreateBuilderForField(message, f("repeatedgroup")).SetField(repeatedGroupA, 217)
+                                             .WeakBuild());
+            message.WeakAddRepeatedField(f("repeated_nested_message"),
+                                         CreateBuilderForField(message, f("repeated_nested_message")).SetField(nestedB,
+                                                                                                               218).
+                                             WeakBuild());
+            message.WeakAddRepeatedField(f("repeated_foreign_message"),
+                                         CreateBuilderForField(message, f("repeated_foreign_message")).SetField(
+                                             foreignC, 219).WeakBuild());
+            message.WeakAddRepeatedField(f("repeated_import_message"),
+                                         CreateBuilderForField(message, f("repeated_import_message")).SetField(importD,
+                                                                                                               220).
+                                             WeakBuild());
+
+            message.WeakAddRepeatedField(f("repeated_nested_enum"), nestedBar);
+            message.WeakAddRepeatedField(f("repeated_foreign_enum"), foreignBar);
+            message.WeakAddRepeatedField(f("repeated_import_enum"), importBar);
+
+            message.WeakAddRepeatedField(f("repeated_string_piece"), "224");
+            message.WeakAddRepeatedField(f("repeated_cord"), "225");
+
+            // Add a second one of each field.
+            message.WeakAddRepeatedField(f("repeated_int32"), 301);
+            message.WeakAddRepeatedField(f("repeated_int64"), 302L);
+            message.WeakAddRepeatedField(f("repeated_uint32"), 303U);
+            message.WeakAddRepeatedField(f("repeated_uint64"), 304UL);
+            message.WeakAddRepeatedField(f("repeated_sint32"), 305);
+            message.WeakAddRepeatedField(f("repeated_sint64"), 306L);
+            message.WeakAddRepeatedField(f("repeated_fixed32"), 307U);
+            message.WeakAddRepeatedField(f("repeated_fixed64"), 308UL);
+            message.WeakAddRepeatedField(f("repeated_sfixed32"), 309);
+            message.WeakAddRepeatedField(f("repeated_sfixed64"), 310L);
+            message.WeakAddRepeatedField(f("repeated_float"), 311F);
+            message.WeakAddRepeatedField(f("repeated_double"), 312D);
+            message.WeakAddRepeatedField(f("repeated_bool"), false);
+            message.WeakAddRepeatedField(f("repeated_string"), "315");
+            message.WeakAddRepeatedField(f("repeated_bytes"), TestUtil.ToBytes("316"));
+
+            message.WeakAddRepeatedField(f("repeatedgroup"),
+                                         CreateBuilderForField(message, f("repeatedgroup"))
+                                             .SetField(repeatedGroupA, 317).WeakBuild());
+            message.WeakAddRepeatedField(f("repeated_nested_message"),
+                                         CreateBuilderForField(message, f("repeated_nested_message"))
+                                             .SetField(nestedB, 318).WeakBuild());
+            message.WeakAddRepeatedField(f("repeated_foreign_message"),
+                                         CreateBuilderForField(message, f("repeated_foreign_message"))
+                                             .SetField(foreignC, 319).WeakBuild());
+            message.WeakAddRepeatedField(f("repeated_import_message"),
+                                         CreateBuilderForField(message, f("repeated_import_message"))
+                                             .SetField(importD, 320).WeakBuild());
+
+            message.WeakAddRepeatedField(f("repeated_nested_enum"), nestedBaz);
+            message.WeakAddRepeatedField(f("repeated_foreign_enum"), foreignBaz);
+            message.WeakAddRepeatedField(f("repeated_import_enum"), importBaz);
+
+            message.WeakAddRepeatedField(f("repeated_string_piece"), "324");
+            message.WeakAddRepeatedField(f("repeated_cord"), "325");
+
+            // -----------------------------------------------------------------
+
+            message[f("default_int32")] = 401;
+            message[f("default_int64")] = 402L;
+            message[f("default_uint32")] = 403U;
+            message[f("default_uint64")] = 404UL;
+            message[f("default_sint32")] = 405;
+            message[f("default_sint64")] = 406L;
+            message[f("default_fixed32")] = 407U;
+            message[f("default_fixed64")] = 408UL;
+            message[f("default_sfixed32")] = 409;
+            message[f("default_sfixed64")] = 410L;
+            message[f("default_float")] = 411F;
+            message[f("default_double")] = 412D;
+            message[f("default_bool")] = false;
+            message[f("default_string")] = "415";
+            message[f("default_bytes")] = TestUtil.ToBytes("416");
+
+            message[f("default_nested_enum")] = nestedFoo;
+            message[f("default_foreign_enum")] = foreignFoo;
+            message[f("default_import_enum")] = importFoo;
+
+            message[f("default_string_piece")] = "424";
+            message[f("default_cord")] = "425";
+        }
+
+        // -------------------------------------------------------------------
+
+        /// <summary>
+        /// Modify the repeated fields of the specified message to contain the
+        /// values expected by AssertRepeatedFieldsModified, using the IBuilder
+        /// reflection interface.
+        /// </summary>
+        internal void ModifyRepeatedFieldsViaReflection(IBuilder message)
+        {
+            message[f("repeated_int32"), 1] = 501;
+            message[f("repeated_int64"), 1] = 502L;
+            message[f("repeated_uint32"), 1] = 503U;
+            message[f("repeated_uint64"), 1] = 504UL;
+            message[f("repeated_sint32"), 1] = 505;
+            message[f("repeated_sint64"), 1] = 506L;
+            message[f("repeated_fixed32"), 1] = 507U;
+            message[f("repeated_fixed64"), 1] = 508UL;
+            message[f("repeated_sfixed32"), 1] = 509;
+            message[f("repeated_sfixed64"), 1] = 510L;
+            message[f("repeated_float"), 1] = 511F;
+            message[f("repeated_double"), 1] = 512D;
+            message[f("repeated_bool"), 1] = true;
+            message[f("repeated_string"), 1] = "515";
+            message.SetRepeatedField(f("repeated_bytes"), 1, TestUtil.ToBytes("516"));
+
+            message.SetRepeatedField(f("repeatedgroup"), 1,
+                                     CreateBuilderForField(message, f("repeatedgroup")).SetField(repeatedGroupA, 517).
+                                         WeakBuild());
+            message.SetRepeatedField(f("repeated_nested_message"), 1,
+                                     CreateBuilderForField(message, f("repeated_nested_message")).SetField(nestedB, 518)
+                                         .WeakBuild());
+            message.SetRepeatedField(f("repeated_foreign_message"), 1,
+                                     CreateBuilderForField(message, f("repeated_foreign_message")).SetField(foreignC,
+                                                                                                            519).
+                                         WeakBuild());
+            message.SetRepeatedField(f("repeated_import_message"), 1,
+                                     CreateBuilderForField(message, f("repeated_import_message")).SetField(importD, 520)
+                                         .WeakBuild());
+
+            message[f("repeated_nested_enum"), 1] = nestedFoo;
+            message[f("repeated_foreign_enum"), 1] = foreignFoo;
+            message[f("repeated_import_enum"), 1] = importFoo;
+
+            message[f("repeated_string_piece"), 1] = "524";
+            message[f("repeated_cord"), 1] = "525";
+        }
+
+        // -------------------------------------------------------------------
+
+        /// <summary>
+        /// Asserts that all fields of the specified message are set to the values
+        /// assigned by SetAllFields, using the IMessage reflection interface.
+        /// </summary>
+        public void AssertAllFieldsSetViaReflection(IMessage message)
+        {
+            Assert.IsTrue(message.HasField(f("optional_int32")));
+            Assert.IsTrue(message.HasField(f("optional_int64")));
+            Assert.IsTrue(message.HasField(f("optional_uint32")));
+            Assert.IsTrue(message.HasField(f("optional_uint64")));
+            Assert.IsTrue(message.HasField(f("optional_sint32")));
+            Assert.IsTrue(message.HasField(f("optional_sint64")));
+            Assert.IsTrue(message.HasField(f("optional_fixed32")));
+            Assert.IsTrue(message.HasField(f("optional_fixed64")));
+            Assert.IsTrue(message.HasField(f("optional_sfixed32")));
+            Assert.IsTrue(message.HasField(f("optional_sfixed64")));
+            Assert.IsTrue(message.HasField(f("optional_float")));
+            Assert.IsTrue(message.HasField(f("optional_double")));
+            Assert.IsTrue(message.HasField(f("optional_bool")));
+            Assert.IsTrue(message.HasField(f("optional_string")));
+            Assert.IsTrue(message.HasField(f("optional_bytes")));
+
+            Assert.IsTrue(message.HasField(f("optionalgroup")));
+            Assert.IsTrue(message.HasField(f("optional_nested_message")));
+            Assert.IsTrue(message.HasField(f("optional_foreign_message")));
+            Assert.IsTrue(message.HasField(f("optional_import_message")));
+
+            Assert.IsTrue(((IMessage) message[f("optionalgroup")]).HasField(groupA));
+            Assert.IsTrue(((IMessage) message[f("optional_nested_message")]).HasField(nestedB));
+            Assert.IsTrue(((IMessage) message[f("optional_foreign_message")]).HasField(foreignC));
+            Assert.IsTrue(((IMessage) message[f("optional_import_message")]).HasField(importD));
+
+            Assert.IsTrue(message.HasField(f("optional_nested_enum")));
+            Assert.IsTrue(message.HasField(f("optional_foreign_enum")));
+            Assert.IsTrue(message.HasField(f("optional_import_enum")));
+
+            Assert.IsTrue(message.HasField(f("optional_string_piece")));
+            Assert.IsTrue(message.HasField(f("optional_cord")));
+
+            Assert.AreEqual(101, message[f("optional_int32")]);
+            Assert.AreEqual(102L, message[f("optional_int64")]);
+            Assert.AreEqual(103U, message[f("optional_uint32")]);
+            Assert.AreEqual(104UL, message[f("optional_uint64")]);
+            Assert.AreEqual(105, message[f("optional_sint32")]);
+            Assert.AreEqual(106L, message[f("optional_sint64")]);
+            Assert.AreEqual(107U, message[f("optional_fixed32")]);
+            Assert.AreEqual(108UL, message[f("optional_fixed64")]);
+            Assert.AreEqual(109, message[f("optional_sfixed32")]);
+            Assert.AreEqual(110L, message[f("optional_sfixed64")]);
+            Assert.AreEqual(111F, message[f("optional_float")]);
+            Assert.AreEqual(112D, message[f("optional_double")]);
+            Assert.AreEqual(true, message[f("optional_bool")]);
+            Assert.AreEqual("115", message[f("optional_string")]);
+            Assert.AreEqual(TestUtil.ToBytes("116"), message[f("optional_bytes")]);
+
+            Assert.AreEqual(117, ((IMessage) message[f("optionalgroup")])[groupA]);
+            Assert.AreEqual(118, ((IMessage) message[f("optional_nested_message")])[nestedB]);
+            Assert.AreEqual(119, ((IMessage) message[f("optional_foreign_message")])[foreignC]);
+            Assert.AreEqual(120, ((IMessage) message[f("optional_import_message")])[importD]);
+
+            Assert.AreEqual(nestedBaz, message[f("optional_nested_enum")]);
+            Assert.AreEqual(foreignBaz, message[f("optional_foreign_enum")]);
+            Assert.AreEqual(importBaz, message[f("optional_import_enum")]);
+
+            Assert.AreEqual("124", message[f("optional_string_piece")]);
+            Assert.AreEqual("125", message[f("optional_cord")]);
+
+            // -----------------------------------------------------------------
+
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_int32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_int64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_uint32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_uint64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sint32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sint64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_fixed32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_fixed64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sfixed32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sfixed64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_float")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_double")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_bool")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_string")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_bytes")));
+
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeatedgroup")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_nested_message")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_foreign_message")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_import_message")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_nested_enum")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_foreign_enum")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_import_enum")));
+
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_string_piece")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_cord")));
+
+            Assert.AreEqual(201, message[f("repeated_int32"), 0]);
+            Assert.AreEqual(202L, message[f("repeated_int64"), 0]);
+            Assert.AreEqual(203U, message[f("repeated_uint32"), 0]);
+            Assert.AreEqual(204UL, message[f("repeated_uint64"), 0]);
+            Assert.AreEqual(205, message[f("repeated_sint32"), 0]);
+            Assert.AreEqual(206L, message[f("repeated_sint64"), 0]);
+            Assert.AreEqual(207U, message[f("repeated_fixed32"), 0]);
+            Assert.AreEqual(208UL, message[f("repeated_fixed64"), 0]);
+            Assert.AreEqual(209, message[f("repeated_sfixed32"), 0]);
+            Assert.AreEqual(210L, message[f("repeated_sfixed64"), 0]);
+            Assert.AreEqual(211F, message[f("repeated_float"), 0]);
+            Assert.AreEqual(212D, message[f("repeated_double"), 0]);
+            Assert.AreEqual(true, message[f("repeated_bool"), 0]);
+            Assert.AreEqual("215", message[f("repeated_string"), 0]);
+            Assert.AreEqual(TestUtil.ToBytes("216"), message[f("repeated_bytes"), 0]);
+
+            Assert.AreEqual(217, ((IMessage) message[f("repeatedgroup"), 0])[repeatedGroupA]);
+            Assert.AreEqual(218, ((IMessage) message[f("repeated_nested_message"), 0])[nestedB]);
+            Assert.AreEqual(219, ((IMessage) message[f("repeated_foreign_message"), 0])[foreignC]);
+            Assert.AreEqual(220, ((IMessage) message[f("repeated_import_message"), 0])[importD]);
+
+            Assert.AreEqual(nestedBar, message[f("repeated_nested_enum"), 0]);
+            Assert.AreEqual(foreignBar, message[f("repeated_foreign_enum"), 0]);
+            Assert.AreEqual(importBar, message[f("repeated_import_enum"), 0]);
+
+            Assert.AreEqual("224", message[f("repeated_string_piece"), 0]);
+            Assert.AreEqual("225", message[f("repeated_cord"), 0]);
+
+            Assert.AreEqual(301, message[f("repeated_int32"), 1]);
+            Assert.AreEqual(302L, message[f("repeated_int64"), 1]);
+            Assert.AreEqual(303U, message[f("repeated_uint32"), 1]);
+            Assert.AreEqual(304UL, message[f("repeated_uint64"), 1]);
+            Assert.AreEqual(305, message[f("repeated_sint32"), 1]);
+            Assert.AreEqual(306L, message[f("repeated_sint64"), 1]);
+            Assert.AreEqual(307U, message[f("repeated_fixed32"), 1]);
+            Assert.AreEqual(308UL, message[f("repeated_fixed64"), 1]);
+            Assert.AreEqual(309, message[f("repeated_sfixed32"), 1]);
+            Assert.AreEqual(310L, message[f("repeated_sfixed64"), 1]);
+            Assert.AreEqual(311F, message[f("repeated_float"), 1]);
+            Assert.AreEqual(312D, message[f("repeated_double"), 1]);
+            Assert.AreEqual(false, message[f("repeated_bool"), 1]);
+            Assert.AreEqual("315", message[f("repeated_string"), 1]);
+            Assert.AreEqual(TestUtil.ToBytes("316"), message[f("repeated_bytes"), 1]);
+
+            Assert.AreEqual(317, ((IMessage) message[f("repeatedgroup"), 1])[repeatedGroupA]);
+            Assert.AreEqual(318, ((IMessage) message[f("repeated_nested_message"), 1])[nestedB]);
+            Assert.AreEqual(319, ((IMessage) message[f("repeated_foreign_message"), 1])[foreignC]);
+            Assert.AreEqual(320, ((IMessage) message[f("repeated_import_message"), 1])[importD]);
+
+            Assert.AreEqual(nestedBaz, message[f("repeated_nested_enum"), 1]);
+            Assert.AreEqual(foreignBaz, message[f("repeated_foreign_enum"), 1]);
+            Assert.AreEqual(importBaz, message[f("repeated_import_enum"), 1]);
+
+            Assert.AreEqual("324", message[f("repeated_string_piece"), 1]);
+            Assert.AreEqual("325", message[f("repeated_cord"), 1]);
+
+            // -----------------------------------------------------------------
+
+            Assert.IsTrue(message.HasField(f("default_int32")));
+            Assert.IsTrue(message.HasField(f("default_int64")));
+            Assert.IsTrue(message.HasField(f("default_uint32")));
+            Assert.IsTrue(message.HasField(f("default_uint64")));
+            Assert.IsTrue(message.HasField(f("default_sint32")));
+            Assert.IsTrue(message.HasField(f("default_sint64")));
+            Assert.IsTrue(message.HasField(f("default_fixed32")));
+            Assert.IsTrue(message.HasField(f("default_fixed64")));
+            Assert.IsTrue(message.HasField(f("default_sfixed32")));
+            Assert.IsTrue(message.HasField(f("default_sfixed64")));
+            Assert.IsTrue(message.HasField(f("default_float")));
+            Assert.IsTrue(message.HasField(f("default_double")));
+            Assert.IsTrue(message.HasField(f("default_bool")));
+            Assert.IsTrue(message.HasField(f("default_string")));
+            Assert.IsTrue(message.HasField(f("default_bytes")));
+
+            Assert.IsTrue(message.HasField(f("default_nested_enum")));
+            Assert.IsTrue(message.HasField(f("default_foreign_enum")));
+            Assert.IsTrue(message.HasField(f("default_import_enum")));
+
+            Assert.IsTrue(message.HasField(f("default_string_piece")));
+            Assert.IsTrue(message.HasField(f("default_cord")));
+
+            Assert.AreEqual(401, message[f("default_int32")]);
+            Assert.AreEqual(402L, message[f("default_int64")]);
+            Assert.AreEqual(403U, message[f("default_uint32")]);
+            Assert.AreEqual(404UL, message[f("default_uint64")]);
+            Assert.AreEqual(405, message[f("default_sint32")]);
+            Assert.AreEqual(406L, message[f("default_sint64")]);
+            Assert.AreEqual(407U, message[f("default_fixed32")]);
+            Assert.AreEqual(408UL, message[f("default_fixed64")]);
+            Assert.AreEqual(409, message[f("default_sfixed32")]);
+            Assert.AreEqual(410L, message[f("default_sfixed64")]);
+            Assert.AreEqual(411F, message[f("default_float")]);
+            Assert.AreEqual(412D, message[f("default_double")]);
+            Assert.AreEqual(false, message[f("default_bool")]);
+            Assert.AreEqual("415", message[f("default_string")]);
+            Assert.AreEqual(TestUtil.ToBytes("416"), message[f("default_bytes")]);
+
+            Assert.AreEqual(nestedFoo, message[f("default_nested_enum")]);
+            Assert.AreEqual(foreignFoo, message[f("default_foreign_enum")]);
+            Assert.AreEqual(importFoo, message[f("default_import_enum")]);
+
+            Assert.AreEqual("424", message[f("default_string_piece")]);
+            Assert.AreEqual("425", message[f("default_cord")]);
+        }
+
+        /// <summary>
+        /// Assert that all fields of the message are cleared, and that
+        /// getting the fields returns their default values, using the reflection interface.
+        /// </summary>
+        public void AssertClearViaReflection(IMessage message)
+        {
+            // has_blah() should initially be false for all optional fields.
+            Assert.IsFalse(message.HasField(f("optional_int32")));
+            Assert.IsFalse(message.HasField(f("optional_int64")));
+            Assert.IsFalse(message.HasField(f("optional_uint32")));
+            Assert.IsFalse(message.HasField(f("optional_uint64")));
+            Assert.IsFalse(message.HasField(f("optional_sint32")));
+            Assert.IsFalse(message.HasField(f("optional_sint64")));
+            Assert.IsFalse(message.HasField(f("optional_fixed32")));
+            Assert.IsFalse(message.HasField(f("optional_fixed64")));
+            Assert.IsFalse(message.HasField(f("optional_sfixed32")));
+            Assert.IsFalse(message.HasField(f("optional_sfixed64")));
+            Assert.IsFalse(message.HasField(f("optional_float")));
+            Assert.IsFalse(message.HasField(f("optional_double")));
+            Assert.IsFalse(message.HasField(f("optional_bool")));
+            Assert.IsFalse(message.HasField(f("optional_string")));
+            Assert.IsFalse(message.HasField(f("optional_bytes")));
+
+            Assert.IsFalse(message.HasField(f("optionalgroup")));
+            Assert.IsFalse(message.HasField(f("optional_nested_message")));
+            Assert.IsFalse(message.HasField(f("optional_foreign_message")));
+            Assert.IsFalse(message.HasField(f("optional_import_message")));
+
+            Assert.IsFalse(message.HasField(f("optional_nested_enum")));
+            Assert.IsFalse(message.HasField(f("optional_foreign_enum")));
+            Assert.IsFalse(message.HasField(f("optional_import_enum")));
+
+            Assert.IsFalse(message.HasField(f("optional_string_piece")));
+            Assert.IsFalse(message.HasField(f("optional_cord")));
+
+            // Optional fields without defaults are set to zero or something like it.
+            Assert.AreEqual(0, message[f("optional_int32")]);
+            Assert.AreEqual(0L, message[f("optional_int64")]);
+            Assert.AreEqual(0U, message[f("optional_uint32")]);
+            Assert.AreEqual(0UL, message[f("optional_uint64")]);
+            Assert.AreEqual(0, message[f("optional_sint32")]);
+            Assert.AreEqual(0L, message[f("optional_sint64")]);
+            Assert.AreEqual(0U, message[f("optional_fixed32")]);
+            Assert.AreEqual(0UL, message[f("optional_fixed64")]);
+            Assert.AreEqual(0, message[f("optional_sfixed32")]);
+            Assert.AreEqual(0L, message[f("optional_sfixed64")]);
+            Assert.AreEqual(0F, message[f("optional_float")]);
+            Assert.AreEqual(0D, message[f("optional_double")]);
+            Assert.AreEqual(false, message[f("optional_bool")]);
+            Assert.AreEqual("", message[f("optional_string")]);
+            Assert.AreEqual(ByteString.Empty, message[f("optional_bytes")]);
+
+            // Embedded messages should also be clear.
+            Assert.IsFalse(((IMessage) message[f("optionalgroup")]).HasField(groupA));
+            Assert.IsFalse(((IMessage) message[f("optional_nested_message")])
+                               .HasField(nestedB));
+            Assert.IsFalse(((IMessage) message[f("optional_foreign_message")])
+                               .HasField(foreignC));
+            Assert.IsFalse(((IMessage) message[f("optional_import_message")])
+                               .HasField(importD));
+
+            Assert.AreEqual(0, ((IMessage) message[f("optionalgroup")])[groupA]);
+            Assert.AreEqual(0, ((IMessage) message[f("optional_nested_message")])[nestedB]);
+            Assert.AreEqual(0, ((IMessage) message[f("optional_foreign_message")])[foreignC]);
+            Assert.AreEqual(0, ((IMessage) message[f("optional_import_message")])[importD]);
+
+            // Enums without defaults are set to the first value in the enum.
+            Assert.AreEqual(nestedFoo, message[f("optional_nested_enum")]);
+            Assert.AreEqual(foreignFoo, message[f("optional_foreign_enum")]);
+            Assert.AreEqual(importFoo, message[f("optional_import_enum")]);
+
+            Assert.AreEqual("", message[f("optional_string_piece")]);
+            Assert.AreEqual("", message[f("optional_cord")]);
+
+            // Repeated fields are empty.
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_int32")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_int64")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_uint32")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_uint64")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_sint32")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_sint64")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_fixed32")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_fixed64")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_sfixed32")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_sfixed64")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_float")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_double")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_bool")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_string")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_bytes")));
+
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeatedgroup")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_nested_message")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_foreign_message")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_import_message")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_nested_enum")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_foreign_enum")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_import_enum")));
+
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_string_piece")));
+            Assert.AreEqual(0, message.GetRepeatedFieldCount(f("repeated_cord")));
+
+            // has_blah() should also be false for all default fields.
+            Assert.IsFalse(message.HasField(f("default_int32")));
+            Assert.IsFalse(message.HasField(f("default_int64")));
+            Assert.IsFalse(message.HasField(f("default_uint32")));
+            Assert.IsFalse(message.HasField(f("default_uint64")));
+            Assert.IsFalse(message.HasField(f("default_sint32")));
+            Assert.IsFalse(message.HasField(f("default_sint64")));
+            Assert.IsFalse(message.HasField(f("default_fixed32")));
+            Assert.IsFalse(message.HasField(f("default_fixed64")));
+            Assert.IsFalse(message.HasField(f("default_sfixed32")));
+            Assert.IsFalse(message.HasField(f("default_sfixed64")));
+            Assert.IsFalse(message.HasField(f("default_float")));
+            Assert.IsFalse(message.HasField(f("default_double")));
+            Assert.IsFalse(message.HasField(f("default_bool")));
+            Assert.IsFalse(message.HasField(f("default_string")));
+            Assert.IsFalse(message.HasField(f("default_bytes")));
+
+            Assert.IsFalse(message.HasField(f("default_nested_enum")));
+            Assert.IsFalse(message.HasField(f("default_foreign_enum")));
+            Assert.IsFalse(message.HasField(f("default_import_enum")));
+
+            Assert.IsFalse(message.HasField(f("default_string_piece")));
+            Assert.IsFalse(message.HasField(f("default_cord")));
+
+            // Fields with defaults have their default values (duh).
+            Assert.AreEqual(41, message[f("default_int32")]);
+            Assert.AreEqual(42L, message[f("default_int64")]);
+            Assert.AreEqual(43U, message[f("default_uint32")]);
+            Assert.AreEqual(44UL, message[f("default_uint64")]);
+            Assert.AreEqual(-45, message[f("default_sint32")]);
+            Assert.AreEqual(46L, message[f("default_sint64")]);
+            Assert.AreEqual(47U, message[f("default_fixed32")]);
+            Assert.AreEqual(48UL, message[f("default_fixed64")]);
+            Assert.AreEqual(49, message[f("default_sfixed32")]);
+            Assert.AreEqual(-50L, message[f("default_sfixed64")]);
+            Assert.AreEqual(51.5F, message[f("default_float")]);
+            Assert.AreEqual(52e3D, message[f("default_double")]);
+            Assert.AreEqual(true, message[f("default_bool")]);
+            Assert.AreEqual("hello", message[f("default_string")]);
+            Assert.AreEqual(TestUtil.ToBytes("world"), message[f("default_bytes")]);
+
+            Assert.AreEqual(nestedBar, message[f("default_nested_enum")]);
+            Assert.AreEqual(foreignBar, message[f("default_foreign_enum")]);
+            Assert.AreEqual(importBar, message[f("default_import_enum")]);
+
+            Assert.AreEqual("abc", message[f("default_string_piece")]);
+            Assert.AreEqual("123", message[f("default_cord")]);
+        }
+
+        // ---------------------------------------------------------------
+
+        internal void AssertRepeatedFieldsModifiedViaReflection(IMessage message)
+        {
+            // ModifyRepeatedFields only sets the second repeated element of each
+            // field.  In addition to verifying this, we also verify that the first
+            // element and size were *not* modified.
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_int32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_int64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_uint32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_uint64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sint32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sint64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_fixed32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_fixed64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sfixed32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_sfixed64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_float")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_double")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_bool")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_string")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_bytes")));
+
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeatedgroup")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_nested_message")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_foreign_message")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_import_message")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_nested_enum")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_foreign_enum")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_import_enum")));
+
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_string_piece")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("repeated_cord")));
+
+            Assert.AreEqual(201, message[f("repeated_int32"), 0]);
+            Assert.AreEqual(202L, message[f("repeated_int64"), 0]);
+            Assert.AreEqual(203U, message[f("repeated_uint32"), 0]);
+            Assert.AreEqual(204UL, message[f("repeated_uint64"), 0]);
+            Assert.AreEqual(205, message[f("repeated_sint32"), 0]);
+            Assert.AreEqual(206L, message[f("repeated_sint64"), 0]);
+            Assert.AreEqual(207U, message[f("repeated_fixed32"), 0]);
+            Assert.AreEqual(208UL, message[f("repeated_fixed64"), 0]);
+            Assert.AreEqual(209, message[f("repeated_sfixed32"), 0]);
+            Assert.AreEqual(210L, message[f("repeated_sfixed64"), 0]);
+            Assert.AreEqual(211F, message[f("repeated_float"), 0]);
+            Assert.AreEqual(212D, message[f("repeated_double"), 0]);
+            Assert.AreEqual(true, message[f("repeated_bool"), 0]);
+            Assert.AreEqual("215", message[f("repeated_string"), 0]);
+            Assert.AreEqual(TestUtil.ToBytes("216"), message[f("repeated_bytes"), 0]);
+
+            Assert.AreEqual(217, ((IMessage) message[f("repeatedgroup"), 0])[repeatedGroupA]);
+            Assert.AreEqual(218, ((IMessage) message[f("repeated_nested_message"), 0])[nestedB]);
+            Assert.AreEqual(219, ((IMessage) message[f("repeated_foreign_message"), 0])[foreignC]);
+            Assert.AreEqual(220, ((IMessage) message[f("repeated_import_message"), 0])[importD]);
+
+            Assert.AreEqual(nestedBar, message[f("repeated_nested_enum"), 0]);
+            Assert.AreEqual(foreignBar, message[f("repeated_foreign_enum"), 0]);
+            Assert.AreEqual(importBar, message[f("repeated_import_enum"), 0]);
+
+            Assert.AreEqual("224", message[f("repeated_string_piece"), 0]);
+            Assert.AreEqual("225", message[f("repeated_cord"), 0]);
+
+            Assert.AreEqual(501, message[f("repeated_int32"), 1]);
+            Assert.AreEqual(502L, message[f("repeated_int64"), 1]);
+            Assert.AreEqual(503U, message[f("repeated_uint32"), 1]);
+            Assert.AreEqual(504UL, message[f("repeated_uint64"), 1]);
+            Assert.AreEqual(505, message[f("repeated_sint32"), 1]);
+            Assert.AreEqual(506L, message[f("repeated_sint64"), 1]);
+            Assert.AreEqual(507U, message[f("repeated_fixed32"), 1]);
+            Assert.AreEqual(508UL, message[f("repeated_fixed64"), 1]);
+            Assert.AreEqual(509, message[f("repeated_sfixed32"), 1]);
+            Assert.AreEqual(510L, message[f("repeated_sfixed64"), 1]);
+            Assert.AreEqual(511F, message[f("repeated_float"), 1]);
+            Assert.AreEqual(512D, message[f("repeated_double"), 1]);
+            Assert.AreEqual(true, message[f("repeated_bool"), 1]);
+            Assert.AreEqual("515", message[f("repeated_string"), 1]);
+            Assert.AreEqual(TestUtil.ToBytes("516"), message[f("repeated_bytes"), 1]);
+
+            Assert.AreEqual(517, ((IMessage) message[f("repeatedgroup"), 1])[repeatedGroupA]);
+            Assert.AreEqual(518, ((IMessage) message[f("repeated_nested_message"), 1])[nestedB]);
+            Assert.AreEqual(519, ((IMessage) message[f("repeated_foreign_message"), 1])[foreignC]);
+            Assert.AreEqual(520, ((IMessage) message[f("repeated_import_message"), 1])[importD]);
+
+            Assert.AreEqual(nestedFoo, message[f("repeated_nested_enum"), 1]);
+            Assert.AreEqual(foreignFoo, message[f("repeated_foreign_enum"), 1]);
+            Assert.AreEqual(importFoo, message[f("repeated_import_enum"), 1]);
+
+            Assert.AreEqual("524", message[f("repeated_string_piece"), 1]);
+            Assert.AreEqual("525", message[f("repeated_cord"), 1]);
+        }
+
+        /// <summary>
+        /// Verifies that the reflection setters for the given Builder object throw an
+        /// ArgumentNullException if they are passed a null value. 
+        /// </summary>
+        public void AssertReflectionSettersRejectNull(IBuilder builder)
+        {
+            TestUtil.AssertArgumentNullException(() => builder[f("optional_string")] = null);
+            TestUtil.AssertArgumentNullException(() => builder[f("optional_bytes")] = null);
+            TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_enum")] = null);
+            TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_message")] = null);
+            TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_message")] = null);
+            TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_string"), null));
+            TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_bytes"), null));
+            TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_nested_enum"), null));
+            TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_nested_message"), null));
+        }
+
+        /// <summary>
+        /// Verifies that the reflection repeated setters for the given Builder object throw an
+        /// ArgumentNullException if they are passed a null value.
+        /// </summary>
+        public void AssertReflectionRepeatedSettersRejectNull(IBuilder builder)
+        {
+            builder.WeakAddRepeatedField(f("repeated_string"), "one");
+            TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_string"), 0, null));
+            builder.WeakAddRepeatedField(f("repeated_bytes"), TestUtil.ToBytes("one"));
+            TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_bytes"), 0, null));
+            builder.WeakAddRepeatedField(f("repeated_nested_enum"), nestedBaz);
+            TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_nested_enum"), 0, null));
+            builder.WeakAddRepeatedField(f("repeated_nested_message"),
+                                         new TestAllTypes.Types.NestedMessage.Builder {Bb = 218}.Build());
+            TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_nested_message"), 0, null));
+        }
+
+        public void SetPackedFieldsViaReflection(IBuilder message)
+        {
+            message.WeakAddRepeatedField(f("packed_int32"), 601);
+            message.WeakAddRepeatedField(f("packed_int64"), 602L);
+            message.WeakAddRepeatedField(f("packed_uint32"), 603U);
+            message.WeakAddRepeatedField(f("packed_uint64"), 604UL);
+            message.WeakAddRepeatedField(f("packed_sint32"), 605);
+            message.WeakAddRepeatedField(f("packed_sint64"), 606L);
+            message.WeakAddRepeatedField(f("packed_fixed32"), 607U);
+            message.WeakAddRepeatedField(f("packed_fixed64"), 608UL);
+            message.WeakAddRepeatedField(f("packed_sfixed32"), 609);
+            message.WeakAddRepeatedField(f("packed_sfixed64"), 610L);
+            message.WeakAddRepeatedField(f("packed_float"), 611F);
+            message.WeakAddRepeatedField(f("packed_double"), 612D);
+            message.WeakAddRepeatedField(f("packed_bool"), true);
+            message.WeakAddRepeatedField(f("packed_enum"), foreignBar);
+            // Add a second one of each field.
+            message.WeakAddRepeatedField(f("packed_int32"), 701);
+            message.WeakAddRepeatedField(f("packed_int64"), 702L);
+            message.WeakAddRepeatedField(f("packed_uint32"), 703U);
+            message.WeakAddRepeatedField(f("packed_uint64"), 704UL);
+            message.WeakAddRepeatedField(f("packed_sint32"), 705);
+            message.WeakAddRepeatedField(f("packed_sint64"), 706L);
+            message.WeakAddRepeatedField(f("packed_fixed32"), 707U);
+            message.WeakAddRepeatedField(f("packed_fixed64"), 708UL);
+            message.WeakAddRepeatedField(f("packed_sfixed32"), 709);
+            message.WeakAddRepeatedField(f("packed_sfixed64"), 710L);
+            message.WeakAddRepeatedField(f("packed_float"), 711F);
+            message.WeakAddRepeatedField(f("packed_double"), 712D);
+            message.WeakAddRepeatedField(f("packed_bool"), false);
+            message.WeakAddRepeatedField(f("packed_enum"), foreignBaz);
+        }
+
+        public void AssertPackedFieldsSetViaReflection(IMessage message)
+        {
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_int32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_int64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_uint32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_uint64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_sint32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_sint64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_fixed32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_fixed64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_sfixed32")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_sfixed64")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_float")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_double")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_bool")));
+            Assert.AreEqual(2, message.GetRepeatedFieldCount(f("packed_enum")));
+            Assert.AreEqual(601, message[f("packed_int32"), 0]);
+            Assert.AreEqual(602L, message[f("packed_int64"), 0]);
+            Assert.AreEqual(603, message[f("packed_uint32"), 0]);
+            Assert.AreEqual(604L, message[f("packed_uint64"), 0]);
+            Assert.AreEqual(605, message[f("packed_sint32"), 0]);
+            Assert.AreEqual(606L, message[f("packed_sint64"), 0]);
+            Assert.AreEqual(607, message[f("packed_fixed32"), 0]);
+            Assert.AreEqual(608L, message[f("packed_fixed64"), 0]);
+            Assert.AreEqual(609, message[f("packed_sfixed32"), 0]);
+            Assert.AreEqual(610L, message[f("packed_sfixed64"), 0]);
+            Assert.AreEqual(611F, message[f("packed_float"), 0]);
+            Assert.AreEqual(612D, message[f("packed_double"), 0]);
+            Assert.AreEqual(true, message[f("packed_bool"), 0]);
+            Assert.AreEqual(foreignBar, message[f("packed_enum"), 0]);
+            Assert.AreEqual(701, message[f("packed_int32"), 1]);
+            Assert.AreEqual(702L, message[f("packed_int64"), 1]);
+            Assert.AreEqual(703, message[f("packed_uint32"), 1]);
+            Assert.AreEqual(704L, message[f("packed_uint64"), 1]);
+            Assert.AreEqual(705, message[f("packed_sint32"), 1]);
+            Assert.AreEqual(706L, message[f("packed_sint64"), 1]);
+            Assert.AreEqual(707, message[f("packed_fixed32"), 1]);
+            Assert.AreEqual(708L, message[f("packed_fixed64"), 1]);
+            Assert.AreEqual(709, message[f("packed_sfixed32"), 1]);
+            Assert.AreEqual(710L, message[f("packed_sfixed64"), 1]);
+            Assert.AreEqual(711F, message[f("packed_float"), 1]);
+            Assert.AreEqual(712D, message[f("packed_double"), 1]);
+            Assert.AreEqual(false, message[f("packed_bool"), 1]);
+            Assert.AreEqual(foreignBaz, message[f("packed_enum"), 1]);
+        }
+    }
+}

+ 216 - 198
src/ProtocolBuffers.Test/ServiceTest.cs

@@ -1,198 +1,216 @@
-#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 Google.ProtocolBuffers.Descriptors;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-using Rhino.Mocks;
-using Rhino.Mocks.Constraints;
-
-namespace Google.ProtocolBuffers {
-
-  /// <summary>
-  /// Tests for generated service classes.
-  /// TODO(jonskeet): Convert the mocking tests using Rhino.Mocks.
-  /// </summary>
-  [TestFixture]
-  public class ServiceTest {
-
-    delegate void Action<T1, T2>(T1 t1, T2 t2);
-
-    private static readonly MethodDescriptor FooDescriptor = TestGenericService.Descriptor.Methods[0];
-    private static readonly MethodDescriptor BarDescriptor = TestGenericService.Descriptor.Methods[1];
-
-    [Test]
-    public void GetRequestPrototype() {
-      TestGenericService service = new TestServiceImpl();
-
-      Assert.AreSame(service.GetRequestPrototype(FooDescriptor), FooRequest.DefaultInstance);
-      Assert.AreSame(service.GetRequestPrototype(BarDescriptor), BarRequest.DefaultInstance);
-    }
-
-    [Test]
-    public void GetResponsePrototype() {
-      TestGenericService service = new TestServiceImpl();
-
-      Assert.AreSame(service.GetResponsePrototype(FooDescriptor), FooResponse.DefaultInstance);
-      Assert.AreSame(service.GetResponsePrototype(BarDescriptor), BarResponse.DefaultInstance);
-    }
-
-    [Test]
-    public void CallMethodFoo() {
-      MockRepository mocks = new MockRepository();
-      FooRequest fooRequest = FooRequest.CreateBuilder().Build();
-      FooResponse fooResponse = FooResponse.CreateBuilder().Build();
-      IRpcController controller = mocks.StrictMock<IRpcController>();
-
-      bool fooCalled = false;
-
-      TestGenericService service = new TestServiceImpl((request, responseAction) => {
-        Assert.AreSame(fooRequest, request);
-        fooCalled = true;
-        responseAction(fooResponse);
-      }, null, controller);
-
-      bool doneHandlerCalled = false;
-      Action<IMessage> doneHandler = (response => {
-        Assert.AreSame(fooResponse, response);
-        doneHandlerCalled = true;          
-      });
-
-      using (mocks.Record()) {
-        // No mock interactions to record
-      }
-
-      service.CallMethod(FooDescriptor, controller, fooRequest, doneHandler);
-
-      Assert.IsTrue(doneHandlerCalled);
-      Assert.IsTrue(fooCalled);
-      mocks.VerifyAll();
-    }
-
-    delegate void CallFooDelegate(MethodDescriptor descriptor, IRpcController controller,
-        IMessage request, IMessage response, Action<IMessage> doneHandler);
-
-    /// <summary>
-    /// Tests the generated stub handling of Foo. By this stage we're reasonably confident
-    /// that the choice between Foo and Bar is arbitrary, hence the lack of a corresponding Bar
-    /// test.
-    /// </summary>
-    [Test]
-    [Ignore("Crashes Mono - needs further investigation")]
-    public void GeneratedStubFooCall() {
-      FooRequest fooRequest = FooRequest.CreateBuilder().Build();      
-      MockRepository mocks = new MockRepository();
-      IRpcChannel mockChannel = mocks.StrictMock<IRpcChannel>();
-      IRpcController mockController = mocks.StrictMock<IRpcController>();
-      TestGenericService service = TestGenericService.CreateStub(mockChannel);
-      Action<FooResponse> doneHandler = mocks.StrictMock<Action<FooResponse>>();
-
-      using (mocks.Record()) {
-        
-        // Nasty way of mocking out "the channel calls the done handler".
-        Expect.Call(() => mockChannel.CallMethod(null, null, null, null, null))
-            .IgnoreArguments()
-            .Constraints(Is.Same(FooDescriptor), Is.Same(mockController), Is.Same(fooRequest), 
-                         Is.Same(FooResponse.DefaultInstance), Is.Anything())
-            .Do((CallFooDelegate) ((p1, p2, p3, response, done) => done(response)));
-        doneHandler(FooResponse.DefaultInstance);
-      }
-
-      service.Foo(mockController, fooRequest, doneHandler);
-
-      mocks.VerifyAll();
-    }
-
-    [Test]
-    public void CallMethodBar() {
-      MockRepository mocks = new MockRepository();
-      BarRequest barRequest = BarRequest.CreateBuilder().Build();
-      BarResponse barResponse = BarResponse.CreateBuilder().Build();
-      IRpcController controller = mocks.StrictMock<IRpcController>();
-
-      bool barCalled = false;
-
-      TestGenericService service = new TestServiceImpl(null, (request, responseAction) => {
-        Assert.AreSame(barRequest, request);
-        barCalled = true;
-        responseAction(barResponse);
-      }, controller);
-
-      bool doneHandlerCalled = false;
-      Action<IMessage> doneHandler = (response => {
-        Assert.AreSame(barResponse, response);
-        doneHandlerCalled = true;
-      });
-
-      using (mocks.Record()) {
-        // No mock interactions to record
-      }
-
-      service.CallMethod(BarDescriptor, controller, barRequest, doneHandler);
-
-      Assert.IsTrue(doneHandlerCalled);
-      Assert.IsTrue(barCalled);
-      mocks.VerifyAll();
-    }
-    
-    
-    class TestServiceImpl : TestGenericService {
-      private readonly Action<FooRequest, Action<FooResponse>> fooHandler;
-      private readonly Action<BarRequest, Action<BarResponse>> barHandler;
-      private readonly IRpcController expectedController;
-
-      internal TestServiceImpl() {
-      }
-
-      internal TestServiceImpl(Action<FooRequest, Action<FooResponse>> fooHandler,
-          Action<BarRequest, Action<BarResponse>> barHandler,
-          IRpcController expectedController) {
-        this.fooHandler = fooHandler;
-        this.barHandler = barHandler;
-        this.expectedController = expectedController;
-      }
-
-      public override void Foo(IRpcController controller, FooRequest request, Action<FooResponse> done) {
-        Assert.AreSame(expectedController, controller);
-        fooHandler(request, done);
-      }
-
-      public override void Bar(IRpcController controller, BarRequest request, Action<BarResponse> done) {
-        Assert.AreSame(expectedController, controller);
-        barHandler(request, done);
-      }
-    }    
-  }
-}
+#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 Google.ProtocolBuffers.Descriptors;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+using Rhino.Mocks;
+using Rhino.Mocks.Constraints;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Tests for generated service classes.
+    /// TODO(jonskeet): Convert the mocking tests using Rhino.Mocks.
+    /// </summary>
+    [TestFixture]
+    public class ServiceTest
+    {
+        private delegate void Action<T1, T2>(T1 t1, T2 t2);
+
+        private static readonly MethodDescriptor FooDescriptor = TestGenericService.Descriptor.Methods[0];
+        private static readonly MethodDescriptor BarDescriptor = TestGenericService.Descriptor.Methods[1];
+
+        [Test]
+        public void GetRequestPrototype()
+        {
+            TestGenericService service = new TestServiceImpl();
+
+            Assert.AreSame(service.GetRequestPrototype(FooDescriptor), FooRequest.DefaultInstance);
+            Assert.AreSame(service.GetRequestPrototype(BarDescriptor), BarRequest.DefaultInstance);
+        }
+
+        [Test]
+        public void GetResponsePrototype()
+        {
+            TestGenericService service = new TestServiceImpl();
+
+            Assert.AreSame(service.GetResponsePrototype(FooDescriptor), FooResponse.DefaultInstance);
+            Assert.AreSame(service.GetResponsePrototype(BarDescriptor), BarResponse.DefaultInstance);
+        }
+
+        [Test]
+        public void CallMethodFoo()
+        {
+            MockRepository mocks = new MockRepository();
+            FooRequest fooRequest = FooRequest.CreateBuilder().Build();
+            FooResponse fooResponse = FooResponse.CreateBuilder().Build();
+            IRpcController controller = mocks.StrictMock<IRpcController>();
+
+            bool fooCalled = false;
+
+            TestGenericService service = new TestServiceImpl((request, responseAction) =>
+                                                                 {
+                                                                     Assert.AreSame(fooRequest, request);
+                                                                     fooCalled = true;
+                                                                     responseAction(fooResponse);
+                                                                 }, null, controller);
+
+            bool doneHandlerCalled = false;
+            Action<IMessage> doneHandler = (response =>
+                                                {
+                                                    Assert.AreSame(fooResponse, response);
+                                                    doneHandlerCalled = true;
+                                                });
+
+            using (mocks.Record())
+            {
+                // No mock interactions to record
+            }
+
+            service.CallMethod(FooDescriptor, controller, fooRequest, doneHandler);
+
+            Assert.IsTrue(doneHandlerCalled);
+            Assert.IsTrue(fooCalled);
+            mocks.VerifyAll();
+        }
+
+        private delegate void CallFooDelegate(MethodDescriptor descriptor, IRpcController controller,
+                                              IMessage request, IMessage response, Action<IMessage> doneHandler);
+
+        /// <summary>
+        /// Tests the generated stub handling of Foo. By this stage we're reasonably confident
+        /// that the choice between Foo and Bar is arbitrary, hence the lack of a corresponding Bar
+        /// test.
+        /// </summary>
+        [Test]
+        [Ignore("Crashes Mono - needs further investigation")]
+        public void GeneratedStubFooCall()
+        {
+            FooRequest fooRequest = FooRequest.CreateBuilder().Build();
+            MockRepository mocks = new MockRepository();
+            IRpcChannel mockChannel = mocks.StrictMock<IRpcChannel>();
+            IRpcController mockController = mocks.StrictMock<IRpcController>();
+            TestGenericService service = TestGenericService.CreateStub(mockChannel);
+            Action<FooResponse> doneHandler = mocks.StrictMock<Action<FooResponse>>();
+
+            using (mocks.Record())
+            {
+                // Nasty way of mocking out "the channel calls the done handler".
+                Expect.Call(() => mockChannel.CallMethod(null, null, null, null, null))
+                    .IgnoreArguments()
+                    .Constraints(Is.Same(FooDescriptor), Is.Same(mockController), Is.Same(fooRequest),
+                                 Is.Same(FooResponse.DefaultInstance), Is.Anything())
+                    .Do((CallFooDelegate) ((p1, p2, p3, response, done) => done(response)));
+                doneHandler(FooResponse.DefaultInstance);
+            }
+
+            service.Foo(mockController, fooRequest, doneHandler);
+
+            mocks.VerifyAll();
+        }
+
+        [Test]
+        public void CallMethodBar()
+        {
+            MockRepository mocks = new MockRepository();
+            BarRequest barRequest = BarRequest.CreateBuilder().Build();
+            BarResponse barResponse = BarResponse.CreateBuilder().Build();
+            IRpcController controller = mocks.StrictMock<IRpcController>();
+
+            bool barCalled = false;
+
+            TestGenericService service = new TestServiceImpl(null, (request, responseAction) =>
+                                                                       {
+                                                                           Assert.AreSame(barRequest, request);
+                                                                           barCalled = true;
+                                                                           responseAction(barResponse);
+                                                                       }, controller);
+
+            bool doneHandlerCalled = false;
+            Action<IMessage> doneHandler = (response =>
+                                                {
+                                                    Assert.AreSame(barResponse, response);
+                                                    doneHandlerCalled = true;
+                                                });
+
+            using (mocks.Record())
+            {
+                // No mock interactions to record
+            }
+
+            service.CallMethod(BarDescriptor, controller, barRequest, doneHandler);
+
+            Assert.IsTrue(doneHandlerCalled);
+            Assert.IsTrue(barCalled);
+            mocks.VerifyAll();
+        }
+
+
+        private class TestServiceImpl : TestGenericService
+        {
+            private readonly Action<FooRequest, Action<FooResponse>> fooHandler;
+            private readonly Action<BarRequest, Action<BarResponse>> barHandler;
+            private readonly IRpcController expectedController;
+
+            internal TestServiceImpl()
+            {
+            }
+
+            internal TestServiceImpl(Action<FooRequest, Action<FooResponse>> fooHandler,
+                                     Action<BarRequest, Action<BarResponse>> barHandler,
+                                     IRpcController expectedController)
+            {
+                this.fooHandler = fooHandler;
+                this.barHandler = barHandler;
+                this.expectedController = expectedController;
+            }
+
+            public override void Foo(IRpcController controller, FooRequest request, Action<FooResponse> done)
+            {
+                Assert.AreSame(expectedController, controller);
+                fooHandler(request, done);
+            }
+
+            public override void Bar(IRpcController controller, BarRequest request, Action<BarResponse> done)
+            {
+                Assert.AreSame(expectedController, controller);
+                barHandler(request, done);
+            }
+        }
+    }
+}

+ 89 - 71
src/ProtocolBuffers.Test/TestRpcGenerator.cs

@@ -1,4 +1,5 @@
-#region Copyright notice and license
+#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/
@@ -30,6 +31,7 @@
 // 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;
@@ -46,81 +48,95 @@ namespace Google.ProtocolBuffers
     [TestFixture]
     public class TestRpcGenerator
     {
-      /// <summary>
-      /// A sample implementation of the ISearchService for testing
-      /// </summary>
-      class ExampleSearchImpl : ISearchService {
-        SearchResponse ISearchService.Search(SearchRequest searchRequest) {
-            if (searchRequest.CriteriaCount == 0) {
-              throw new ArgumentException("No criteria specified.", new InvalidOperationException());
+        /// <summary>
+        /// A sample implementation of the ISearchService for testing
+        /// </summary>
+        private class ExampleSearchImpl : ISearchService
+        {
+            SearchResponse ISearchService.Search(SearchRequest searchRequest)
+            {
+                if (searchRequest.CriteriaCount == 0)
+                {
+                    throw new ArgumentException("No criteria specified.", new InvalidOperationException());
+                }
+                SearchResponse.Builder resp = SearchResponse.CreateBuilder();
+                foreach (string criteria in searchRequest.CriteriaList)
+                {
+                    resp.AddResults(
+                        SearchResponse.Types.ResultItem.CreateBuilder().SetName(criteria).SetUrl("http://search.com").
+                            Build());
+                }
+                return resp.Build();
+            }
+
+            SearchResponse ISearchService.RefineSearch(RefineSearchRequest refineSearchRequest)
+            {
+                SearchResponse.Builder resp = refineSearchRequest.PreviousResults.ToBuilder();
+                foreach (string criteria in refineSearchRequest.CriteriaList)
+                {
+                    resp.AddResults(
+                        SearchResponse.Types.ResultItem.CreateBuilder().SetName(criteria).SetUrl("http://refine.com").
+                            Build());
+                }
+                return resp.Build();
+            }
+        }
+
+        /// <summary>
+        /// An example extraction of the wire protocol
+        /// </summary>
+        private interface IWireTransfer
+        {
+            byte[] Execute(string method, byte[] message);
+        }
+
+        /// <summary>
+        /// An example of a server responding to a wire request
+        /// </summary>
+        private class ExampleServerHost : IWireTransfer
+        {
+            private readonly IRpcServerStub _stub;
+
+            public ExampleServerHost(ISearchService implementation)
+            {
+                //on the server, we create a dispatch to call the appropriate method by name
+                IRpcDispatch dispatch = new SearchService.Dispatch(implementation);
+                //we then wrap that dispatch in a server stub which will deserialize the wire bytes to the message
+                //type appropriate for the method name being invoked.
+                _stub = new SearchService.ServerStub(dispatch);
             }
-            SearchResponse.Builder resp = SearchResponse.CreateBuilder();
-            foreach (string criteria in searchRequest.CriteriaList) {
-              resp.AddResults(SearchResponse.Types.ResultItem.CreateBuilder().SetName(criteria).SetUrl("http://search.com").Build());
+
+            byte[] IWireTransfer.Execute(string method, byte[] message)
+            {
+                //now when we recieve a wire transmission to invoke a method by name with a byte[] or stream payload
+                //we just simply call the sub:
+                IMessageLite response = _stub.CallMethod(method, CodedInputStream.CreateInstance(message),
+                                                         ExtensionRegistry.Empty);
+                //now we return the expected response message:
+                return response.ToByteArray();
             }
-            return resp.Build();
         }
 
-        SearchResponse ISearchService.RefineSearch(RefineSearchRequest refineSearchRequest) {
-            SearchResponse.Builder resp = refineSearchRequest.PreviousResults.ToBuilder();
-            foreach (string criteria in refineSearchRequest.CriteriaList) {
-              resp.AddResults(SearchResponse.Types.ResultItem.CreateBuilder().SetName(criteria).SetUrl("http://refine.com").Build());
+        /// <summary>
+        /// An example of a client sending a wire request
+        /// </summary>
+        private class ExampleClient : IRpcDispatch
+        {
+            private readonly IWireTransfer _wire;
+
+            public ExampleClient(IWireTransfer wire)
+            {
+                _wire = wire;
+            }
+
+            TMessage IRpcDispatch.CallMethod<TMessage, TBuilder>(string method, IMessageLite request,
+                                                                 IBuilderLite<TMessage, TBuilder> response)
+            {
+                byte[] rawResponse = _wire.Execute(method, request.ToByteArray());
+                response.MergeFrom(rawResponse);
+                return response.Build();
             }
-            return resp.Build();
         }
-      }
-
-      /// <summary>
-      /// An example extraction of the wire protocol
-      /// </summary>
-      interface IWireTransfer 
-      {
-          byte[] Execute(string method, byte[] message);
-      }
-
-      /// <summary>
-      /// An example of a server responding to a wire request
-      /// </summary>
-      class ExampleServerHost : IWireTransfer
-      {
-          readonly IRpcServerStub _stub;
-          public ExampleServerHost(ISearchService implementation)
-          {
-              //on the server, we create a dispatch to call the appropriate method by name
-              IRpcDispatch dispatch = new SearchService.Dispatch(implementation);
-              //we then wrap that dispatch in a server stub which will deserialize the wire bytes to the message
-              //type appropriate for the method name being invoked.
-              _stub = new SearchService.ServerStub(dispatch);
-          }
-
-          byte[] IWireTransfer.Execute(string method, byte[] message)
-          {
-              //now when we recieve a wire transmission to invoke a method by name with a byte[] or stream payload
-              //we just simply call the sub:
-              IMessageLite response = _stub.CallMethod(method, CodedInputStream.CreateInstance(message), ExtensionRegistry.Empty);
-              //now we return the expected response message:
-              return response.ToByteArray();
-          }
-      }
-
-      /// <summary>
-      /// An example of a client sending a wire request
-      /// </summary>
-      class ExampleClient : IRpcDispatch
-      {
-          readonly IWireTransfer _wire;
-          public ExampleClient(IWireTransfer wire)
-          {
-              _wire = wire;
-          }
-
-          TMessage IRpcDispatch.CallMethod<TMessage, TBuilder>(string method, IMessageLite request, IBuilderLite<TMessage, TBuilder> response)
-          {
-              byte[] rawResponse = _wire.Execute(method, request.ToByteArray());
-              response.MergeFrom(rawResponse);
-              return response.Build();
-          }
-      }
 
         /// <summary>
         /// Put it all together to create one seamless client/server experience full of rich-type goodness ;)
@@ -141,7 +157,9 @@ namespace Google.ProtocolBuffers
             Assert.AreEqual("http://search.com", result.ResultsList[0].Url);
 
             //The test part of this, call the only other method
-            result = client.RefineSearch(RefineSearchRequest.CreateBuilder().SetPreviousResults(result).AddCriteria("Refine").Build());
+            result =
+                client.RefineSearch(
+                    RefineSearchRequest.CreateBuilder().SetPreviousResults(result).AddCriteria("Refine").Build());
             Assert.AreEqual(2, result.ResultsCount);
             Assert.AreEqual("Test", result.ResultsList[0].Name);
             Assert.AreEqual("http://search.com", result.ResultsList[0].Url);

+ 1705 - 1620
src/ProtocolBuffers.Test/TestUtil.cs

@@ -1,1620 +1,1705 @@
-#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 System.Threading;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  internal static class TestUtil {
-
-    private static string testDataDirectory;
-    private static ByteString goldenMessage = null;
-
-    internal static string TestDataDirectory {
-      get {
-        if (testDataDirectory != null) {
-          return testDataDirectory;
-        }
-
-        DirectoryInfo ancestor = new DirectoryInfo(".");
-        // Search each parent directory looking for "testdata".
-        while (ancestor != null) {
-          string candidate = Path.Combine(ancestor.FullName, "testdata");
-          if (Directory.Exists(candidate)) {
-            testDataDirectory = candidate;
-            return candidate;
-          }
-          ancestor = ancestor.Parent;
-        }
-        // TODO(jonskeet): Come up with a better exception to throw
-        throw new Exception("Unable to find directory containing test files");
-      }
-    }
-
-    internal static ByteString GoldenMessage {
-      get {
-        if (goldenMessage == null) {
-          goldenMessage = ReadBytesFromFile("golden_message");
-        }
-        return goldenMessage;
-      }
-    }
-
-    /// <summary>
-    /// Creates an unmodifiable ExtensionRegistry containing all the extensions
-    /// of TestAllExtensions.
-    /// </summary>
-    /// <returns></returns>
-    internal static ExtensionRegistry CreateExtensionRegistry() {
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      RegisterAllExtensions(registry);
-      return registry.AsReadOnly();
-    }
-
-    /// <summary>
-    /// Registers all of the extensions in TestAllExtensions with the given
-    /// ExtensionRegistry.
-    /// </summary>
-    internal static void RegisterAllExtensions(ExtensionRegistry registry) {
-      registry.Add(UnitTestProtoFile.OptionalInt32Extension);
-      registry.Add(UnitTestProtoFile.OptionalInt64Extension);
-      registry.Add(UnitTestProtoFile.OptionalUint32Extension);
-      registry.Add(UnitTestProtoFile.OptionalUint64Extension);
-      registry.Add(UnitTestProtoFile.OptionalSint32Extension);
-      registry.Add(UnitTestProtoFile.OptionalSint64Extension);
-      registry.Add(UnitTestProtoFile.OptionalFixed32Extension);
-      registry.Add(UnitTestProtoFile.OptionalFixed64Extension);
-      registry.Add(UnitTestProtoFile.OptionalSfixed32Extension);
-      registry.Add(UnitTestProtoFile.OptionalSfixed64Extension);
-      registry.Add(UnitTestProtoFile.OptionalFloatExtension);
-      registry.Add(UnitTestProtoFile.OptionalDoubleExtension);
-      registry.Add(UnitTestProtoFile.OptionalBoolExtension);
-      registry.Add(UnitTestProtoFile.OptionalStringExtension);
-      registry.Add(UnitTestProtoFile.OptionalBytesExtension);
-      registry.Add(UnitTestProtoFile.OptionalGroupExtension);
-      registry.Add(UnitTestProtoFile.OptionalNestedMessageExtension);
-      registry.Add(UnitTestProtoFile.OptionalForeignMessageExtension);
-      registry.Add(UnitTestProtoFile.OptionalImportMessageExtension);
-      registry.Add(UnitTestProtoFile.OptionalNestedEnumExtension);
-      registry.Add(UnitTestProtoFile.OptionalForeignEnumExtension);
-      registry.Add(UnitTestProtoFile.OptionalImportEnumExtension);
-      registry.Add(UnitTestProtoFile.OptionalStringPieceExtension);
-      registry.Add(UnitTestProtoFile.OptionalCordExtension);
-
-      registry.Add(UnitTestProtoFile.RepeatedInt32Extension);
-      registry.Add(UnitTestProtoFile.RepeatedInt64Extension);
-      registry.Add(UnitTestProtoFile.RepeatedUint32Extension);
-      registry.Add(UnitTestProtoFile.RepeatedUint64Extension);
-      registry.Add(UnitTestProtoFile.RepeatedSint32Extension);
-      registry.Add(UnitTestProtoFile.RepeatedSint64Extension);
-      registry.Add(UnitTestProtoFile.RepeatedFixed32Extension);
-      registry.Add(UnitTestProtoFile.RepeatedFixed64Extension);
-      registry.Add(UnitTestProtoFile.RepeatedSfixed32Extension);
-      registry.Add(UnitTestProtoFile.RepeatedSfixed64Extension);
-      registry.Add(UnitTestProtoFile.RepeatedFloatExtension);
-      registry.Add(UnitTestProtoFile.RepeatedDoubleExtension);
-      registry.Add(UnitTestProtoFile.RepeatedBoolExtension);
-      registry.Add(UnitTestProtoFile.RepeatedStringExtension);
-      registry.Add(UnitTestProtoFile.RepeatedBytesExtension);
-      registry.Add(UnitTestProtoFile.RepeatedGroupExtension);
-      registry.Add(UnitTestProtoFile.RepeatedNestedMessageExtension);
-      registry.Add(UnitTestProtoFile.RepeatedForeignMessageExtension);
-      registry.Add(UnitTestProtoFile.RepeatedImportMessageExtension);
-      registry.Add(UnitTestProtoFile.RepeatedNestedEnumExtension);
-      registry.Add(UnitTestProtoFile.RepeatedForeignEnumExtension);
-      registry.Add(UnitTestProtoFile.RepeatedImportEnumExtension);
-      registry.Add(UnitTestProtoFile.RepeatedStringPieceExtension);
-      registry.Add(UnitTestProtoFile.RepeatedCordExtension);
-
-      registry.Add(UnitTestProtoFile.DefaultInt32Extension);
-      registry.Add(UnitTestProtoFile.DefaultInt64Extension);
-      registry.Add(UnitTestProtoFile.DefaultUint32Extension);
-      registry.Add(UnitTestProtoFile.DefaultUint64Extension);
-      registry.Add(UnitTestProtoFile.DefaultSint32Extension);
-      registry.Add(UnitTestProtoFile.DefaultSint64Extension);
-      registry.Add(UnitTestProtoFile.DefaultFixed32Extension);
-      registry.Add(UnitTestProtoFile.DefaultFixed64Extension);
-      registry.Add(UnitTestProtoFile.DefaultSfixed32Extension);
-      registry.Add(UnitTestProtoFile.DefaultSfixed64Extension);
-      registry.Add(UnitTestProtoFile.DefaultFloatExtension);
-      registry.Add(UnitTestProtoFile.DefaultDoubleExtension);
-      registry.Add(UnitTestProtoFile.DefaultBoolExtension);
-      registry.Add(UnitTestProtoFile.DefaultStringExtension);
-      registry.Add(UnitTestProtoFile.DefaultBytesExtension);
-      registry.Add(UnitTestProtoFile.DefaultNestedEnumExtension);
-      registry.Add(UnitTestProtoFile.DefaultForeignEnumExtension);
-      registry.Add(UnitTestProtoFile.DefaultImportEnumExtension);
-      registry.Add(UnitTestProtoFile.DefaultStringPieceExtension);
-      registry.Add(UnitTestProtoFile.DefaultCordExtension);
-
-      registry.Add(UnitTestProtoFile.PackedInt32Extension);
-      registry.Add(UnitTestProtoFile.PackedInt64Extension);
-      registry.Add(UnitTestProtoFile.PackedUint32Extension);
-      registry.Add(UnitTestProtoFile.PackedUint64Extension);
-      registry.Add(UnitTestProtoFile.PackedSint32Extension);
-      registry.Add(UnitTestProtoFile.PackedSint64Extension);
-      registry.Add(UnitTestProtoFile.PackedFixed32Extension);
-      registry.Add(UnitTestProtoFile.PackedFixed64Extension);
-      registry.Add(UnitTestProtoFile.PackedSfixed32Extension);
-      registry.Add(UnitTestProtoFile.PackedSfixed64Extension);
-      registry.Add(UnitTestProtoFile.PackedFloatExtension);
-      registry.Add(UnitTestProtoFile.PackedDoubleExtension);
-      registry.Add(UnitTestProtoFile.PackedBoolExtension);
-      registry.Add(UnitTestProtoFile.PackedEnumExtension);
-    }
-
-    internal static string ReadTextFromFile(string filePath) {
-      return ReadBytesFromFile(filePath).ToStringUtf8();
-    }
-
-    internal static ByteString ReadBytesFromFile(String filename) {
-      byte[] data = File.ReadAllBytes(Path.Combine(TestDataDirectory, filename));
-      return ByteString.CopyFrom(data);
-    }
-
-    /// <summary>
-    /// Helper to convert a String to ByteString.
-    /// </summary>
-    internal static ByteString ToBytes(String str) {
-      return ByteString.CopyFrom(Encoding.UTF8.GetBytes(str));
-    }
-
-    internal static TestAllTypes GetAllSet() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      SetAllFields(builder);
-      return builder.Build();
-    }
-
-    /// <summary>
-    /// Sets every field of the specified message to the values expected by
-    /// AssertAllFieldsSet.
-    /// </summary>
-    internal static void SetAllFields(TestAllTypes.Builder message) {
-      message.SetOptionalInt32(101);
-      message.SetOptionalInt64(102);
-      message.SetOptionalUint32(103);
-      message.SetOptionalUint64(104);
-      message.SetOptionalSint32(105);
-      message.SetOptionalSint64(106);
-      message.SetOptionalFixed32(107);
-      message.SetOptionalFixed64(108);
-      message.SetOptionalSfixed32(109);
-      message.SetOptionalSfixed64(110);
-      message.SetOptionalFloat(111);
-      message.SetOptionalDouble(112);
-      message.SetOptionalBool(true);
-      message.SetOptionalString("115");
-      message.SetOptionalBytes(ToBytes("116"));
-      
-      message.SetOptionalGroup(TestAllTypes.Types.OptionalGroup.CreateBuilder().SetA(117).Build());
-      message.SetOptionalNestedMessage(TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(118).Build());
-      message.SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(119).Build());
-      message.SetOptionalImportMessage(ImportMessage.CreateBuilder().SetD(120).Build());
-
-      message.SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.BAZ);
-      message.SetOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ);
-      message.SetOptionalImportEnum(ImportEnum.IMPORT_BAZ);
-
-      message.SetOptionalStringPiece("124");
-      message.SetOptionalCord("125");
-
-      // -----------------------------------------------------------------
-
-      message.AddRepeatedInt32(201);
-      message.AddRepeatedInt64(202);
-      message.AddRepeatedUint32(203);
-      message.AddRepeatedUint64(204);
-      message.AddRepeatedSint32(205);
-      message.AddRepeatedSint64(206);
-      message.AddRepeatedFixed32(207);
-      message.AddRepeatedFixed64(208);
-      message.AddRepeatedSfixed32(209);
-      message.AddRepeatedSfixed64(210);
-      message.AddRepeatedFloat(211);
-      message.AddRepeatedDouble(212);
-      message.AddRepeatedBool(true);
-      message.AddRepeatedString("215");
-      message.AddRepeatedBytes(ToBytes("216"));
-
-      message.AddRepeatedGroup(TestAllTypes.Types.RepeatedGroup.CreateBuilder().SetA(217).Build());
-      message.AddRepeatedNestedMessage(TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(218).Build());
-      message.AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(219).Build());
-      message.AddRepeatedImportMessage(ImportMessage.CreateBuilder().SetD(220).Build());
-
-      message.AddRepeatedNestedEnum(TestAllTypes.Types.NestedEnum.BAR);
-      message.AddRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR);
-      message.AddRepeatedImportEnum(ImportEnum.IMPORT_BAR);
-
-      message.AddRepeatedStringPiece("224");
-      message.AddRepeatedCord("225");
-
-      // Add a second one of each field.
-      message.AddRepeatedInt32(301);
-      message.AddRepeatedInt64(302);
-      message.AddRepeatedUint32(303);
-      message.AddRepeatedUint64(304);
-      message.AddRepeatedSint32(305);
-      message.AddRepeatedSint64(306);
-      message.AddRepeatedFixed32(307);
-      message.AddRepeatedFixed64(308);
-      message.AddRepeatedSfixed32(309);
-      message.AddRepeatedSfixed64(310);
-      message.AddRepeatedFloat(311);
-      message.AddRepeatedDouble(312);
-      message.AddRepeatedBool(false);
-      message.AddRepeatedString("315");
-      message.AddRepeatedBytes(ToBytes("316"));
-
-      message.AddRepeatedGroup(TestAllTypes.Types.RepeatedGroup.CreateBuilder().SetA(317).Build());
-      message.AddRepeatedNestedMessage(TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(318).Build());
-      message.AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(319).Build());
-      message.AddRepeatedImportMessage(ImportMessage.CreateBuilder().SetD(320).Build());
-
-      message.AddRepeatedNestedEnum(TestAllTypes.Types.NestedEnum.BAZ);
-      message.AddRepeatedForeignEnum(ForeignEnum.FOREIGN_BAZ);
-      message.AddRepeatedImportEnum(ImportEnum.IMPORT_BAZ);
-
-      message.AddRepeatedStringPiece("324");
-      message.AddRepeatedCord("325");
-
-      // -----------------------------------------------------------------
-
-      message.SetDefaultInt32(401);
-      message.SetDefaultInt64(402);
-      message.SetDefaultUint32(403);
-      message.SetDefaultUint64(404);
-      message.SetDefaultSint32(405);
-      message.SetDefaultSint64(406);
-      message.SetDefaultFixed32(407);
-      message.SetDefaultFixed64(408);
-      message.SetDefaultSfixed32(409);
-      message.SetDefaultSfixed64(410);
-      message.SetDefaultFloat(411);
-      message.SetDefaultDouble(412);
-      message.SetDefaultBool(false);
-      message.SetDefaultString("415");
-      message.SetDefaultBytes(ToBytes("416"));
-      
-      message.SetDefaultNestedEnum(TestAllTypes.Types.NestedEnum.FOO);
-      message.SetDefaultForeignEnum(ForeignEnum.FOREIGN_FOO);
-      message.SetDefaultImportEnum(ImportEnum.IMPORT_FOO);
-
-      message.SetDefaultStringPiece("424");
-      message.SetDefaultCord("425");
-    }
-
-    /// <summary>
-    /// Asserts that all fields of the specified message are set to the values
-    /// assigned by SetAllFields.
-    /// </summary>
-    internal static void AssertAllFieldsSet(TestAllTypes message) {
-      Assert.IsTrue(message.HasOptionalInt32);
-      Assert.IsTrue(message.HasOptionalInt64);
-      Assert.IsTrue(message.HasOptionalUint32);
-      Assert.IsTrue(message.HasOptionalUint64);
-      Assert.IsTrue(message.HasOptionalSint32);
-      Assert.IsTrue(message.HasOptionalSint64);
-      Assert.IsTrue(message.HasOptionalFixed32);
-      Assert.IsTrue(message.HasOptionalFixed64);
-      Assert.IsTrue(message.HasOptionalSfixed32);
-      Assert.IsTrue(message.HasOptionalSfixed64);
-      Assert.IsTrue(message.HasOptionalFloat);
-      Assert.IsTrue(message.HasOptionalDouble);
-      Assert.IsTrue(message.HasOptionalBool);
-      Assert.IsTrue(message.HasOptionalString);
-      Assert.IsTrue(message.HasOptionalBytes);
-
-      Assert.IsTrue(message.HasOptionalGroup);
-      Assert.IsTrue(message.HasOptionalNestedMessage);
-      Assert.IsTrue(message.HasOptionalForeignMessage);
-      Assert.IsTrue(message.HasOptionalImportMessage);
-
-      Assert.IsTrue(message.OptionalGroup.HasA);
-      Assert.IsTrue(message.OptionalNestedMessage.HasBb);
-      Assert.IsTrue(message.OptionalForeignMessage.HasC);
-      Assert.IsTrue(message.OptionalImportMessage.HasD);
-
-      Assert.IsTrue(message.HasOptionalNestedEnum);
-      Assert.IsTrue(message.HasOptionalForeignEnum);
-      Assert.IsTrue(message.HasOptionalImportEnum);
-
-      Assert.IsTrue(message.HasOptionalStringPiece);
-      Assert.IsTrue(message.HasOptionalCord);
-
-      Assert.AreEqual(101, message.OptionalInt32);
-      Assert.AreEqual(102, message.OptionalInt64);
-      Assert.AreEqual(103, message.OptionalUint32);
-      Assert.AreEqual(104, message.OptionalUint64);
-      Assert.AreEqual(105, message.OptionalSint32);
-      Assert.AreEqual(106, message.OptionalSint64);
-      Assert.AreEqual(107, message.OptionalFixed32);
-      Assert.AreEqual(108, message.OptionalFixed64);
-      Assert.AreEqual(109, message.OptionalSfixed32);
-      Assert.AreEqual(110, message.OptionalSfixed64);
-      Assert.AreEqual(111, message.OptionalFloat);
-      Assert.AreEqual(112, message.OptionalDouble);
-      Assert.AreEqual(true, message.OptionalBool);
-      Assert.AreEqual("115", message.OptionalString);
-      Assert.AreEqual(ToBytes("116"), message.OptionalBytes);
-
-      Assert.AreEqual(117, message.OptionalGroup.A);
-      Assert.AreEqual(118, message.OptionalNestedMessage.Bb);
-      Assert.AreEqual(119, message.OptionalForeignMessage.C);
-      Assert.AreEqual(120, message.OptionalImportMessage.D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAZ, message.OptionalNestedEnum);
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.OptionalForeignEnum);
-      Assert.AreEqual(ImportEnum.IMPORT_BAZ, message.OptionalImportEnum);
-
-      Assert.AreEqual("124", message.OptionalStringPiece);
-      Assert.AreEqual("125", message.OptionalCord);
-
-      // -----------------------------------------------------------------
-
-      Assert.AreEqual(2, message.RepeatedInt32Count);
-      Assert.AreEqual(2, message.RepeatedInt64Count);
-      Assert.AreEqual(2, message.RepeatedUint32Count);
-      Assert.AreEqual(2, message.RepeatedUint64Count);
-      Assert.AreEqual(2, message.RepeatedSint32Count);
-      Assert.AreEqual(2, message.RepeatedSint64Count);
-      Assert.AreEqual(2, message.RepeatedFixed32Count);
-      Assert.AreEqual(2, message.RepeatedFixed64Count);
-      Assert.AreEqual(2, message.RepeatedSfixed32Count);
-      Assert.AreEqual(2, message.RepeatedSfixed64Count);
-      Assert.AreEqual(2, message.RepeatedFloatCount);
-      Assert.AreEqual(2, message.RepeatedDoubleCount);
-      Assert.AreEqual(2, message.RepeatedBoolCount);
-      Assert.AreEqual(2, message.RepeatedStringCount);
-      Assert.AreEqual(2, message.RepeatedBytesCount);
-
-      Assert.AreEqual(2, message.RepeatedGroupCount         );
-      Assert.AreEqual(2, message.RepeatedNestedMessageCount );
-      Assert.AreEqual(2, message.RepeatedForeignMessageCount);
-      Assert.AreEqual(2, message.RepeatedImportMessageCount );
-      Assert.AreEqual(2, message.RepeatedNestedEnumCount    );
-      Assert.AreEqual(2, message.RepeatedForeignEnumCount   );
-      Assert.AreEqual(2, message.RepeatedImportEnumCount    );
-
-      Assert.AreEqual(2, message.RepeatedStringPieceCount);
-      Assert.AreEqual(2, message.RepeatedCordCount);
-
-      Assert.AreEqual(201, message.GetRepeatedInt32(0));
-      Assert.AreEqual(202, message.GetRepeatedInt64(0));
-      Assert.AreEqual(203, message.GetRepeatedUint32(0));
-      Assert.AreEqual(204, message.GetRepeatedUint64(0));
-      Assert.AreEqual(205, message.GetRepeatedSint32(0));
-      Assert.AreEqual(206, message.GetRepeatedSint64(0));
-      Assert.AreEqual(207, message.GetRepeatedFixed32(0));
-      Assert.AreEqual(208, message.GetRepeatedFixed64(0));
-      Assert.AreEqual(209, message.GetRepeatedSfixed32(0));
-      Assert.AreEqual(210, message.GetRepeatedSfixed64(0));
-      Assert.AreEqual(211, message.GetRepeatedFloat(0));
-      Assert.AreEqual(212, message.GetRepeatedDouble(0));
-      Assert.AreEqual(true , message.GetRepeatedBool(0));
-      Assert.AreEqual("215", message.GetRepeatedString(0));
-      Assert.AreEqual(ToBytes("216"), message.GetRepeatedBytes(0));
-
-      Assert.AreEqual(217, message.GetRepeatedGroup(0).A);
-      Assert.AreEqual(218, message.GetRepeatedNestedMessage (0).Bb);
-      Assert.AreEqual(219, message.GetRepeatedForeignMessage(0).C);
-      Assert.AreEqual(220, message.GetRepeatedImportMessage (0).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.GetRepeatedNestedEnum (0));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetRepeatedForeignEnum(0));
-      Assert.AreEqual(ImportEnum.IMPORT_BAR, message.GetRepeatedImportEnum(0));
-
-      Assert.AreEqual("224", message.GetRepeatedStringPiece(0));
-      Assert.AreEqual("225", message.GetRepeatedCord(0));
-
-      Assert.AreEqual(301, message.GetRepeatedInt32   (1));
-      Assert.AreEqual(302, message.GetRepeatedInt64   (1));
-      Assert.AreEqual(303, message.GetRepeatedUint32  (1));
-      Assert.AreEqual(304, message.GetRepeatedUint64  (1));
-      Assert.AreEqual(305, message.GetRepeatedSint32  (1));
-      Assert.AreEqual(306, message.GetRepeatedSint64  (1));
-      Assert.AreEqual(307, message.GetRepeatedFixed32 (1));
-      Assert.AreEqual(308, message.GetRepeatedFixed64 (1));
-      Assert.AreEqual(309, message.GetRepeatedSfixed32(1));
-      Assert.AreEqual(310, message.GetRepeatedSfixed64(1));
-      Assert.AreEqual(311, message.GetRepeatedFloat   (1), 0.0);
-      Assert.AreEqual(312, message.GetRepeatedDouble  (1), 0.0);
-      Assert.AreEqual(false, message.GetRepeatedBool    (1));
-      Assert.AreEqual("315", message.GetRepeatedString  (1));
-      Assert.AreEqual(ToBytes("316"), message.GetRepeatedBytes(1));
-
-      Assert.AreEqual(317, message.GetRepeatedGroup         (1).A);
-      Assert.AreEqual(318, message.GetRepeatedNestedMessage (1).Bb);
-      Assert.AreEqual(319, message.GetRepeatedForeignMessage(1).C);
-      Assert.AreEqual(320, message.GetRepeatedImportMessage (1).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAZ, message.GetRepeatedNestedEnum (1));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.GetRepeatedForeignEnum(1));
-      Assert.AreEqual(ImportEnum.IMPORT_BAZ, message.GetRepeatedImportEnum(1));
-
-      Assert.AreEqual("324", message.GetRepeatedStringPiece(1));
-      Assert.AreEqual("325", message.GetRepeatedCord(1));
-
-      // -----------------------------------------------------------------
-
-      Assert.IsTrue(message.HasDefaultInt32   );
-      Assert.IsTrue(message.HasDefaultInt64   );
-      Assert.IsTrue(message.HasDefaultUint32  );
-      Assert.IsTrue(message.HasDefaultUint64  );
-      Assert.IsTrue(message.HasDefaultSint32  );
-      Assert.IsTrue(message.HasDefaultSint64  );
-      Assert.IsTrue(message.HasDefaultFixed32 );
-      Assert.IsTrue(message.HasDefaultFixed64 );
-      Assert.IsTrue(message.HasDefaultSfixed32);
-      Assert.IsTrue(message.HasDefaultSfixed64);
-      Assert.IsTrue(message.HasDefaultFloat   );
-      Assert.IsTrue(message.HasDefaultDouble  );
-      Assert.IsTrue(message.HasDefaultBool    );
-      Assert.IsTrue(message.HasDefaultString  );
-      Assert.IsTrue(message.HasDefaultBytes   );
-
-      Assert.IsTrue(message.HasDefaultNestedEnum );
-      Assert.IsTrue(message.HasDefaultForeignEnum);
-      Assert.IsTrue(message.HasDefaultImportEnum );
-
-      Assert.IsTrue(message.HasDefaultStringPiece);
-      Assert.IsTrue(message.HasDefaultCord);
-
-      Assert.AreEqual(401, message.DefaultInt32);
-      Assert.AreEqual(402, message.DefaultInt64);
-      Assert.AreEqual(403, message.DefaultUint32);
-      Assert.AreEqual(404, message.DefaultUint64);
-      Assert.AreEqual(405, message.DefaultSint32);
-      Assert.AreEqual(406, message.DefaultSint64);
-      Assert.AreEqual(407, message.DefaultFixed32);
-      Assert.AreEqual(408, message.DefaultFixed64);
-      Assert.AreEqual(409, message.DefaultSfixed32);
-      Assert.AreEqual(410, message.DefaultSfixed64);
-      Assert.AreEqual(411, message.DefaultFloat);
-      Assert.AreEqual(412, message.DefaultDouble);
-      Assert.AreEqual(false, message.DefaultBool    );
-      Assert.AreEqual("415", message.DefaultString  );
-      Assert.AreEqual(ToBytes("416"), message.DefaultBytes);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.DefaultNestedEnum);
-      Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.DefaultForeignEnum);
-      Assert.AreEqual(ImportEnum.IMPORT_FOO, message.DefaultImportEnum);
-
-      Assert.AreEqual("424", message.DefaultStringPiece);
-      Assert.AreEqual("425", message.DefaultCord);
-    }
-
-    internal static void AssertClear(TestAllTypes message) {
-      // HasBlah() should initially be false for all optional fields.
-      Assert.IsFalse(message.HasOptionalInt32);
-      Assert.IsFalse(message.HasOptionalInt64);
-      Assert.IsFalse(message.HasOptionalUint32);
-      Assert.IsFalse(message.HasOptionalUint64);
-      Assert.IsFalse(message.HasOptionalSint32);
-      Assert.IsFalse(message.HasOptionalSint64);
-      Assert.IsFalse(message.HasOptionalFixed32);
-      Assert.IsFalse(message.HasOptionalFixed64);
-      Assert.IsFalse(message.HasOptionalSfixed32);
-      Assert.IsFalse(message.HasOptionalSfixed64);
-      Assert.IsFalse(message.HasOptionalFloat);
-      Assert.IsFalse(message.HasOptionalDouble);
-      Assert.IsFalse(message.HasOptionalBool);
-      Assert.IsFalse(message.HasOptionalString);
-      Assert.IsFalse(message.HasOptionalBytes);
-
-      Assert.IsFalse(message.HasOptionalGroup);
-      Assert.IsFalse(message.HasOptionalNestedMessage);
-      Assert.IsFalse(message.HasOptionalForeignMessage);
-      Assert.IsFalse(message.HasOptionalImportMessage);
-
-      Assert.IsFalse(message.HasOptionalNestedEnum);
-      Assert.IsFalse(message.HasOptionalForeignEnum);
-      Assert.IsFalse(message.HasOptionalImportEnum);
-
-      Assert.IsFalse(message.HasOptionalStringPiece);
-      Assert.IsFalse(message.HasOptionalCord);
-
-      // Optional fields without defaults are set to zero or something like it.
-      Assert.AreEqual(0, message.OptionalInt32);
-      Assert.AreEqual(0, message.OptionalInt64);
-      Assert.AreEqual(0, message.OptionalUint32);
-      Assert.AreEqual(0, message.OptionalUint64);
-      Assert.AreEqual(0, message.OptionalSint32);
-      Assert.AreEqual(0, message.OptionalSint64);
-      Assert.AreEqual(0, message.OptionalFixed32);
-      Assert.AreEqual(0, message.OptionalFixed64);
-      Assert.AreEqual(0, message.OptionalSfixed32);
-      Assert.AreEqual(0, message.OptionalSfixed64);
-      Assert.AreEqual(0, message.OptionalFloat);
-      Assert.AreEqual(0, message.OptionalDouble);
-      Assert.AreEqual(false, message.OptionalBool);
-      Assert.AreEqual("", message.OptionalString);
-      Assert.AreEqual(ByteString.Empty, message.OptionalBytes);
-
-      // Embedded messages should also be clear.
-      Assert.IsFalse(message.OptionalGroup.HasA);
-      Assert.IsFalse(message.OptionalNestedMessage.HasBb);
-      Assert.IsFalse(message.OptionalForeignMessage.HasC);
-      Assert.IsFalse(message.OptionalImportMessage.HasD);
-
-      Assert.AreEqual(0, message.OptionalGroup.A);
-      Assert.AreEqual(0, message.OptionalNestedMessage.Bb);
-      Assert.AreEqual(0, message.OptionalForeignMessage.C);
-      Assert.AreEqual(0, message.OptionalImportMessage.D);
-
-      // Enums without defaults are set to the first value in the enum.
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.OptionalNestedEnum);
-      Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.OptionalForeignEnum);
-      Assert.AreEqual(ImportEnum.IMPORT_FOO, message.OptionalImportEnum);
-
-      Assert.AreEqual("", message.OptionalStringPiece);
-      Assert.AreEqual("", message.OptionalCord);
-
-      // Repeated fields are empty.
-      Assert.AreEqual(0, message.RepeatedInt32Count);
-      Assert.AreEqual(0, message.RepeatedInt64Count);
-      Assert.AreEqual(0, message.RepeatedUint32Count);
-      Assert.AreEqual(0, message.RepeatedUint64Count);
-      Assert.AreEqual(0, message.RepeatedSint32Count);
-      Assert.AreEqual(0, message.RepeatedSint64Count);
-      Assert.AreEqual(0, message.RepeatedFixed32Count);
-      Assert.AreEqual(0, message.RepeatedFixed64Count);
-      Assert.AreEqual(0, message.RepeatedSfixed32Count);
-      Assert.AreEqual(0, message.RepeatedSfixed64Count);
-      Assert.AreEqual(0, message.RepeatedFloatCount);
-      Assert.AreEqual(0, message.RepeatedDoubleCount);
-      Assert.AreEqual(0, message.RepeatedBoolCount);
-      Assert.AreEqual(0, message.RepeatedStringCount);
-      Assert.AreEqual(0, message.RepeatedBytesCount);
-
-      Assert.AreEqual(0, message.RepeatedGroupCount);
-      Assert.AreEqual(0, message.RepeatedNestedMessageCount);
-      Assert.AreEqual(0, message.RepeatedForeignMessageCount);
-      Assert.AreEqual(0, message.RepeatedImportMessageCount);
-      Assert.AreEqual(0, message.RepeatedNestedEnumCount);
-      Assert.AreEqual(0, message.RepeatedForeignEnumCount);
-      Assert.AreEqual(0, message.RepeatedImportEnumCount);
-
-      Assert.AreEqual(0, message.RepeatedStringPieceCount);
-      Assert.AreEqual(0, message.RepeatedCordCount);
-
-      // HasBlah() should also be false for all default fields.
-      Assert.IsFalse(message.HasDefaultInt32);
-      Assert.IsFalse(message.HasDefaultInt64);
-      Assert.IsFalse(message.HasDefaultUint32);
-      Assert.IsFalse(message.HasDefaultUint64);
-      Assert.IsFalse(message.HasDefaultSint32);
-      Assert.IsFalse(message.HasDefaultSint64);
-      Assert.IsFalse(message.HasDefaultFixed32);
-      Assert.IsFalse(message.HasDefaultFixed64);
-      Assert.IsFalse(message.HasDefaultSfixed32);
-      Assert.IsFalse(message.HasDefaultSfixed64);
-      Assert.IsFalse(message.HasDefaultFloat);
-      Assert.IsFalse(message.HasDefaultDouble);
-      Assert.IsFalse(message.HasDefaultBool);
-      Assert.IsFalse(message.HasDefaultString);
-      Assert.IsFalse(message.HasDefaultBytes);
-
-      Assert.IsFalse(message.HasDefaultNestedEnum);
-      Assert.IsFalse(message.HasDefaultForeignEnum);
-      Assert.IsFalse(message.HasDefaultImportEnum);
-
-      Assert.IsFalse(message.HasDefaultStringPiece);
-      Assert.IsFalse(message.HasDefaultCord);
-
-      // Fields with defaults have their default values (duh).
-      Assert.AreEqual(41, message.DefaultInt32);
-      Assert.AreEqual(42, message.DefaultInt64);
-      Assert.AreEqual(43, message.DefaultUint32);
-      Assert.AreEqual(44, message.DefaultUint64);
-      Assert.AreEqual(-45, message.DefaultSint32);
-      Assert.AreEqual(46, message.DefaultSint64);
-      Assert.AreEqual(47, message.DefaultFixed32);
-      Assert.AreEqual(48, message.DefaultFixed64);
-      Assert.AreEqual(49, message.DefaultSfixed32);
-      Assert.AreEqual(-50, message.DefaultSfixed64);
-      Assert.AreEqual(51.5, message.DefaultFloat, 0.0);
-      Assert.AreEqual(52e3, message.DefaultDouble, 0.0);
-      Assert.AreEqual(true, message.DefaultBool);
-      Assert.AreEqual("hello", message.DefaultString);
-      Assert.AreEqual(ToBytes("world"), message.DefaultBytes);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.DefaultNestedEnum);
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.DefaultForeignEnum);
-      Assert.AreEqual(ImportEnum.IMPORT_BAR, message.DefaultImportEnum);
-
-      Assert.AreEqual("abc", message.DefaultStringPiece);
-      Assert.AreEqual("123", message.DefaultCord);
-    }
-
-    /// <summary>
-    /// Get a TestAllExtensions with all fields set as they would be by
-    /// SetAllExtensions(TestAllExtensions.Builder).
-    /// </summary>
-    internal static TestAllExtensions GetAllExtensionsSet() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      SetAllExtensions(builder);
-      return builder.Build();
-    }
-
-    public static TestPackedTypes GetPackedSet() {
-      TestPackedTypes.Builder builder = TestPackedTypes.CreateBuilder();
-      SetPackedFields(builder);
-      return builder.Build();
-    }
-
-    public static TestPackedExtensions GetPackedExtensionsSet() {
-      TestPackedExtensions.Builder builder = TestPackedExtensions.CreateBuilder();
-      SetPackedExtensions(builder);
-      return builder.Build();
-    }
-
-    /// <summary>
-    /// Sets every field of the specified builder to the values expected by
-    /// AssertAllExtensionsSet.
-    /// </summary>
-    internal static void SetAllExtensions(TestAllExtensions.Builder message) {
-      message.SetExtension(UnitTestProtoFile.OptionalInt32Extension, 101);
-      message.SetExtension(UnitTestProtoFile.OptionalInt64Extension, 102L);
-      message.SetExtension(UnitTestProtoFile.OptionalUint32Extension, 103U);
-      message.SetExtension(UnitTestProtoFile.OptionalUint64Extension, 104UL);
-      message.SetExtension(UnitTestProtoFile.OptionalSint32Extension, 105);
-      message.SetExtension(UnitTestProtoFile.OptionalSint64Extension, 106L);
-      message.SetExtension(UnitTestProtoFile.OptionalFixed32Extension, 107U);
-      message.SetExtension(UnitTestProtoFile.OptionalFixed64Extension, 108UL);
-      message.SetExtension(UnitTestProtoFile.OptionalSfixed32Extension, 109);
-      message.SetExtension(UnitTestProtoFile.OptionalSfixed64Extension, 110L);
-      message.SetExtension(UnitTestProtoFile.OptionalFloatExtension, 111F);
-      message.SetExtension(UnitTestProtoFile.OptionalDoubleExtension, 112D);
-      message.SetExtension(UnitTestProtoFile.OptionalBoolExtension, true);
-      message.SetExtension(UnitTestProtoFile.OptionalStringExtension, "115");
-      message.SetExtension(UnitTestProtoFile.OptionalBytesExtension, ToBytes("116"));
-
-      message.SetExtension(UnitTestProtoFile.OptionalGroupExtension, OptionalGroup_extension.CreateBuilder().SetA(117).Build());
-      message.SetExtension(UnitTestProtoFile.OptionalNestedMessageExtension, TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(118).Build());
-      message.SetExtension(UnitTestProtoFile.OptionalForeignMessageExtension, ForeignMessage.CreateBuilder().SetC(119).Build());
-      message.SetExtension(UnitTestProtoFile.OptionalImportMessageExtension, ImportMessage.CreateBuilder().SetD(120).Build());
-
-      message.SetExtension(UnitTestProtoFile.OptionalNestedEnumExtension, TestAllTypes.Types.NestedEnum.BAZ);
-      message.SetExtension(UnitTestProtoFile.OptionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
-      message.SetExtension(UnitTestProtoFile.OptionalImportEnumExtension, ImportEnum.IMPORT_BAZ);
-
-      message.SetExtension(UnitTestProtoFile.OptionalStringPieceExtension, "124");
-      message.SetExtension(UnitTestProtoFile.OptionalCordExtension, "125");
-
-      // -----------------------------------------------------------------
-
-      message.AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 201);
-      message.AddExtension(UnitTestProtoFile.RepeatedInt64Extension, 202L);
-      message.AddExtension(UnitTestProtoFile.RepeatedUint32Extension, 203U);
-      message.AddExtension(UnitTestProtoFile.RepeatedUint64Extension, 204UL);
-      message.AddExtension(UnitTestProtoFile.RepeatedSint32Extension, 205);
-      message.AddExtension(UnitTestProtoFile.RepeatedSint64Extension, 206L);
-      message.AddExtension(UnitTestProtoFile.RepeatedFixed32Extension, 207U);
-      message.AddExtension(UnitTestProtoFile.RepeatedFixed64Extension, 208UL);
-      message.AddExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 209);
-      message.AddExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 210L);
-      message.AddExtension(UnitTestProtoFile.RepeatedFloatExtension, 211F);
-      message.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 212D);
-      message.AddExtension(UnitTestProtoFile.RepeatedBoolExtension, true);
-      message.AddExtension(UnitTestProtoFile.RepeatedStringExtension, "215");
-      message.AddExtension(UnitTestProtoFile.RepeatedBytesExtension, ToBytes("216"));
-
-      message.AddExtension(UnitTestProtoFile.RepeatedGroupExtension, RepeatedGroup_extension.CreateBuilder().SetA(217).Build());
-      message.AddExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(218).Build());
-      message.AddExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, ForeignMessage.CreateBuilder().SetC(219).Build());
-      message.AddExtension(UnitTestProtoFile.RepeatedImportMessageExtension, ImportMessage.CreateBuilder().SetD(220).Build());
-
-      message.AddExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, TestAllTypes.Types.NestedEnum.BAR);
-      message.AddExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAR);
-      message.AddExtension(UnitTestProtoFile.RepeatedImportEnumExtension, ImportEnum.IMPORT_BAR);
-
-      message.AddExtension(UnitTestProtoFile.RepeatedStringPieceExtension, "224");
-      message.AddExtension(UnitTestProtoFile.RepeatedCordExtension, "225");
-
-      // Add a second one of each field.
-      message.AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 301);
-      message.AddExtension(UnitTestProtoFile.RepeatedInt64Extension, 302L);
-      message.AddExtension(UnitTestProtoFile.RepeatedUint32Extension, 303U);
-      message.AddExtension(UnitTestProtoFile.RepeatedUint64Extension, 304UL);
-      message.AddExtension(UnitTestProtoFile.RepeatedSint32Extension, 305);
-      message.AddExtension(UnitTestProtoFile.RepeatedSint64Extension, 306L);
-      message.AddExtension(UnitTestProtoFile.RepeatedFixed32Extension, 307U);
-      message.AddExtension(UnitTestProtoFile.RepeatedFixed64Extension, 308UL);
-      message.AddExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 309);
-      message.AddExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 310L);
-      message.AddExtension(UnitTestProtoFile.RepeatedFloatExtension, 311F);
-      message.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 312D);
-      message.AddExtension(UnitTestProtoFile.RepeatedBoolExtension, false);
-      message.AddExtension(UnitTestProtoFile.RepeatedStringExtension, "315");
-      message.AddExtension(UnitTestProtoFile.RepeatedBytesExtension, ToBytes("316"));
-
-      message.AddExtension(UnitTestProtoFile.RepeatedGroupExtension, RepeatedGroup_extension.CreateBuilder().SetA(317).Build());
-      message.AddExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(318).Build());
-      message.AddExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, ForeignMessage.CreateBuilder().SetC(319).Build());
-      message.AddExtension(UnitTestProtoFile.RepeatedImportMessageExtension, ImportMessage.CreateBuilder().SetD(320).Build());
-
-      message.AddExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, TestAllTypes.Types.NestedEnum.BAZ);
-      message.AddExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
-      message.AddExtension(UnitTestProtoFile.RepeatedImportEnumExtension, ImportEnum.IMPORT_BAZ);
-
-      message.AddExtension(UnitTestProtoFile.RepeatedStringPieceExtension, "324");
-      message.AddExtension(UnitTestProtoFile.RepeatedCordExtension, "325");
-
-      // -----------------------------------------------------------------
-
-      message.SetExtension(UnitTestProtoFile.DefaultInt32Extension, 401);
-      message.SetExtension(UnitTestProtoFile.DefaultInt64Extension, 402L);
-      message.SetExtension(UnitTestProtoFile.DefaultUint32Extension, 403U);
-      message.SetExtension(UnitTestProtoFile.DefaultUint64Extension, 404UL);
-      message.SetExtension(UnitTestProtoFile.DefaultSint32Extension, 405);
-      message.SetExtension(UnitTestProtoFile.DefaultSint64Extension, 406L);
-      message.SetExtension(UnitTestProtoFile.DefaultFixed32Extension, 407U);
-      message.SetExtension(UnitTestProtoFile.DefaultFixed64Extension, 408UL);
-      message.SetExtension(UnitTestProtoFile.DefaultSfixed32Extension, 409);
-      message.SetExtension(UnitTestProtoFile.DefaultSfixed64Extension, 410L);
-      message.SetExtension(UnitTestProtoFile.DefaultFloatExtension, 411F);
-      message.SetExtension(UnitTestProtoFile.DefaultDoubleExtension, 412D);
-      message.SetExtension(UnitTestProtoFile.DefaultBoolExtension, false);
-      message.SetExtension(UnitTestProtoFile.DefaultStringExtension, "415");
-      message.SetExtension(UnitTestProtoFile.DefaultBytesExtension, ToBytes("416"));
-
-      message.SetExtension(UnitTestProtoFile.DefaultNestedEnumExtension, TestAllTypes.Types.NestedEnum.FOO);
-      message.SetExtension(UnitTestProtoFile.DefaultForeignEnumExtension, ForeignEnum.FOREIGN_FOO);
-      message.SetExtension(UnitTestProtoFile.DefaultImportEnumExtension, ImportEnum.IMPORT_FOO);
-
-      message.SetExtension(UnitTestProtoFile.DefaultStringPieceExtension, "424");
-      message.SetExtension(UnitTestProtoFile.DefaultCordExtension, "425");
-    }
-
-    internal static void ModifyRepeatedFields(TestAllTypes.Builder message) {
-      message.SetRepeatedInt32(1, 501);
-      message.SetRepeatedInt64(1, 502);
-      message.SetRepeatedUint32(1, 503);
-      message.SetRepeatedUint64(1, 504);
-      message.SetRepeatedSint32(1, 505);
-      message.SetRepeatedSint64(1, 506);
-      message.SetRepeatedFixed32(1, 507);
-      message.SetRepeatedFixed64(1, 508);
-      message.SetRepeatedSfixed32(1, 509);
-      message.SetRepeatedSfixed64(1, 510);
-      message.SetRepeatedFloat(1, 511);
-      message.SetRepeatedDouble(1, 512);
-      message.SetRepeatedBool(1, true);
-      message.SetRepeatedString(1, "515");
-      message.SetRepeatedBytes(1, ToBytes("516"));
-
-      message.SetRepeatedGroup(1, TestAllTypes.Types.RepeatedGroup.CreateBuilder().SetA(517).Build());
-      message.SetRepeatedNestedMessage(1, TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(518).Build());
-      message.SetRepeatedForeignMessage(1, ForeignMessage.CreateBuilder().SetC(519).Build());
-      message.SetRepeatedImportMessage(1, ImportMessage.CreateBuilder().SetD(520).Build());
-
-      message.SetRepeatedNestedEnum(1, TestAllTypes.Types.NestedEnum.FOO);
-      message.SetRepeatedForeignEnum(1, ForeignEnum.FOREIGN_FOO);
-      message.SetRepeatedImportEnum(1, ImportEnum.IMPORT_FOO);
-
-      message.SetRepeatedStringPiece(1, "524");
-      message.SetRepeatedCord(1, "525");
-    }
-
-    internal static void AssertRepeatedFieldsModified(TestAllTypes message) {
-      // ModifyRepeatedFields only sets the second repeated element of each
-      // field.  In addition to verifying this, we also verify that the first
-      // element and size were *not* modified.
-      Assert.AreEqual(2, message.RepeatedInt32Count);
-      Assert.AreEqual(2, message.RepeatedInt64Count);
-      Assert.AreEqual(2, message.RepeatedUint32Count);
-      Assert.AreEqual(2, message.RepeatedUint64Count);
-      Assert.AreEqual(2, message.RepeatedSint32Count);
-      Assert.AreEqual(2, message.RepeatedSint64Count);
-      Assert.AreEqual(2, message.RepeatedFixed32Count);
-      Assert.AreEqual(2, message.RepeatedFixed64Count);
-      Assert.AreEqual(2, message.RepeatedSfixed32Count);
-      Assert.AreEqual(2, message.RepeatedSfixed64Count);
-      Assert.AreEqual(2, message.RepeatedFloatCount);
-      Assert.AreEqual(2, message.RepeatedDoubleCount);
-      Assert.AreEqual(2, message.RepeatedBoolCount);
-      Assert.AreEqual(2, message.RepeatedStringCount);
-      Assert.AreEqual(2, message.RepeatedBytesCount);
-
-      Assert.AreEqual(2, message.RepeatedGroupCount);
-      Assert.AreEqual(2, message.RepeatedNestedMessageCount);
-      Assert.AreEqual(2, message.RepeatedForeignMessageCount);
-      Assert.AreEqual(2, message.RepeatedImportMessageCount);
-      Assert.AreEqual(2, message.RepeatedNestedEnumCount);
-      Assert.AreEqual(2, message.RepeatedForeignEnumCount);
-      Assert.AreEqual(2, message.RepeatedImportEnumCount);
-
-      Assert.AreEqual(2, message.RepeatedStringPieceCount);
-      Assert.AreEqual(2, message.RepeatedCordCount);
-
-      Assert.AreEqual(201, message.GetRepeatedInt32(0));
-      Assert.AreEqual(202L, message.GetRepeatedInt64(0));
-      Assert.AreEqual(203U, message.GetRepeatedUint32(0));
-      Assert.AreEqual(204UL, message.GetRepeatedUint64(0));
-      Assert.AreEqual(205, message.GetRepeatedSint32(0));
-      Assert.AreEqual(206L, message.GetRepeatedSint64(0));
-      Assert.AreEqual(207U, message.GetRepeatedFixed32(0));
-      Assert.AreEqual(208UL, message.GetRepeatedFixed64(0));
-      Assert.AreEqual(209, message.GetRepeatedSfixed32(0));
-      Assert.AreEqual(210L, message.GetRepeatedSfixed64(0));
-      Assert.AreEqual(211F, message.GetRepeatedFloat(0));
-      Assert.AreEqual(212D, message.GetRepeatedDouble(0));
-      Assert.AreEqual(true, message.GetRepeatedBool(0));
-      Assert.AreEqual("215", message.GetRepeatedString(0));
-      Assert.AreEqual(ToBytes("216"), message.GetRepeatedBytes(0));
-
-      Assert.AreEqual(217, message.GetRepeatedGroup(0).A);
-      Assert.AreEqual(218, message.GetRepeatedNestedMessage(0).Bb);
-      Assert.AreEqual(219, message.GetRepeatedForeignMessage(0).C);
-      Assert.AreEqual(220, message.GetRepeatedImportMessage(0).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.GetRepeatedNestedEnum(0));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetRepeatedForeignEnum(0));
-      Assert.AreEqual(ImportEnum.IMPORT_BAR, message.GetRepeatedImportEnum(0));
-
-      Assert.AreEqual("224", message.GetRepeatedStringPiece(0));
-      Assert.AreEqual("225", message.GetRepeatedCord(0));
-
-      // Actually verify the second (modified) elements now.
-      Assert.AreEqual(501, message.GetRepeatedInt32(1));
-      Assert.AreEqual(502L, message.GetRepeatedInt64(1));
-      Assert.AreEqual(503U, message.GetRepeatedUint32(1));
-      Assert.AreEqual(504UL, message.GetRepeatedUint64(1));
-      Assert.AreEqual(505, message.GetRepeatedSint32(1));
-      Assert.AreEqual(506L, message.GetRepeatedSint64(1));
-      Assert.AreEqual(507U, message.GetRepeatedFixed32(1));
-      Assert.AreEqual(508UL, message.GetRepeatedFixed64(1));
-      Assert.AreEqual(509, message.GetRepeatedSfixed32(1));
-      Assert.AreEqual(510L, message.GetRepeatedSfixed64(1));
-      Assert.AreEqual(511F, message.GetRepeatedFloat(1));
-      Assert.AreEqual(512D, message.GetRepeatedDouble(1));
-      Assert.AreEqual(true, message.GetRepeatedBool(1));
-      Assert.AreEqual("515", message.GetRepeatedString(1));
-      Assert.AreEqual(ToBytes("516"), message.GetRepeatedBytes(1));
-
-      Assert.AreEqual(517, message.GetRepeatedGroup(1).A);
-      Assert.AreEqual(518, message.GetRepeatedNestedMessage(1).Bb);
-      Assert.AreEqual(519, message.GetRepeatedForeignMessage(1).C);
-      Assert.AreEqual(520, message.GetRepeatedImportMessage(1).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.GetRepeatedNestedEnum(1));
-      Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.GetRepeatedForeignEnum(1));
-      Assert.AreEqual(ImportEnum.IMPORT_FOO, message.GetRepeatedImportEnum(1));
-
-      Assert.AreEqual("524", message.GetRepeatedStringPiece(1));
-      Assert.AreEqual("525", message.GetRepeatedCord(1));
-    }
-
-    /// <summary>
-    /// Helper to assert that sequences are equal.
-    /// </summary>
-    internal static void AssertEqual<T>(IEnumerable<T> first, IEnumerable<T> second) {
-      using (IEnumerator<T> firstEnumerator = first.GetEnumerator()) {
-        foreach (T secondElement in second) {
-          Assert.IsTrue(firstEnumerator.MoveNext(), "First enumerator ran out of elements too early.");
-          Assert.AreEqual(firstEnumerator.Current, secondElement);
-        }
-        Assert.IsFalse(firstEnumerator.MoveNext(), "Second enumerator ran out of elements too early.");
-      }
-    }
-
-    internal static void AssertEqualBytes(byte[] expected, byte[] actual) {
-      Assert.AreEqual(ByteString.CopyFrom(expected), ByteString.CopyFrom(actual));
-    }
-
-    internal static void AssertAllExtensionsSet(TestAllExtensions message) {
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalInt32Extension   ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalInt64Extension   ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalUint32Extension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalUint64Extension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalSint32Extension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalSint64Extension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalFixed32Extension ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalFixed64Extension ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalSfixed32Extension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalSfixed64Extension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalFloatExtension   ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalDoubleExtension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalBoolExtension    ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalStringExtension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalBytesExtension   ));
-
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalGroupExtension         ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalNestedMessageExtension ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalForeignMessageExtension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalImportMessageExtension ));
-
-      Assert.IsTrue(message.GetExtension(UnitTestProtoFile.OptionalGroupExtension         ).HasA);
-      Assert.IsTrue(message.GetExtension(UnitTestProtoFile.OptionalNestedMessageExtension ).HasBb);
-      Assert.IsTrue(message.GetExtension(UnitTestProtoFile.OptionalForeignMessageExtension).HasC);
-      Assert.IsTrue(message.GetExtension(UnitTestProtoFile.OptionalImportMessageExtension ).HasD);
-
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalNestedEnumExtension ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalImportEnumExtension ));
-
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalStringPieceExtension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalCordExtension));
-
-      Assert.AreEqual(101  , message.GetExtension(UnitTestProtoFile.OptionalInt32Extension   ));
-      Assert.AreEqual(102L , message.GetExtension(UnitTestProtoFile.OptionalInt64Extension   ));
-      Assert.AreEqual(103U  , message.GetExtension(UnitTestProtoFile.OptionalUint32Extension  ));
-      Assert.AreEqual(104UL , message.GetExtension(UnitTestProtoFile.OptionalUint64Extension  ));
-      Assert.AreEqual(105  , message.GetExtension(UnitTestProtoFile.OptionalSint32Extension  ));
-      Assert.AreEqual(106L , message.GetExtension(UnitTestProtoFile.OptionalSint64Extension  ));
-      Assert.AreEqual(107U  , message.GetExtension(UnitTestProtoFile.OptionalFixed32Extension ));
-      Assert.AreEqual(108UL , message.GetExtension(UnitTestProtoFile.OptionalFixed64Extension ));
-      Assert.AreEqual(109  , message.GetExtension(UnitTestProtoFile.OptionalSfixed32Extension));
-      Assert.AreEqual(110L , message.GetExtension(UnitTestProtoFile.OptionalSfixed64Extension));
-      Assert.AreEqual(111F , message.GetExtension(UnitTestProtoFile.OptionalFloatExtension   ));
-      Assert.AreEqual(112D , message.GetExtension(UnitTestProtoFile.OptionalDoubleExtension  ));
-      Assert.AreEqual(true , message.GetExtension(UnitTestProtoFile.OptionalBoolExtension    ));
-      Assert.AreEqual("115", message.GetExtension(UnitTestProtoFile.OptionalStringExtension  ));
-      Assert.AreEqual(ToBytes("116"), message.GetExtension(UnitTestProtoFile.OptionalBytesExtension));
-
-      Assert.AreEqual(117, message.GetExtension(UnitTestProtoFile.OptionalGroupExtension         ).A);
-      Assert.AreEqual(118, message.GetExtension(UnitTestProtoFile.OptionalNestedMessageExtension ).Bb);
-      Assert.AreEqual(119, message.GetExtension(UnitTestProtoFile.OptionalForeignMessageExtension).C);
-      Assert.AreEqual(120, message.GetExtension(UnitTestProtoFile.OptionalImportMessageExtension ).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAZ, message.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.GetExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
-      Assert.AreEqual(ImportEnum.IMPORT_BAZ, message.GetExtension(UnitTestProtoFile.OptionalImportEnumExtension));
-
-      Assert.AreEqual("124", message.GetExtension(UnitTestProtoFile.OptionalStringPieceExtension));
-      Assert.AreEqual("125", message.GetExtension(UnitTestProtoFile.OptionalCordExtension));
-
-      // -----------------------------------------------------------------
-
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension   ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt64Extension   ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint32Extension  ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint64Extension  ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint32Extension  ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint64Extension  ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed32Extension ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed64Extension ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFloatExtension   ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension  ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedBoolExtension    ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringExtension  ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedBytesExtension   ));
-
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedGroupExtension         ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedMessageExtension ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignMessageExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportMessageExtension ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedEnumExtension    ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignEnumExtension   ));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportEnumExtension    ));
-
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringPieceExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedCordExtension));
-
-      Assert.AreEqual(201  , message.GetExtension(UnitTestProtoFile.RepeatedInt32Extension   , 0));
-      Assert.AreEqual(202L , message.GetExtension(UnitTestProtoFile.RepeatedInt64Extension   , 0));
-      Assert.AreEqual(203U  , message.GetExtension(UnitTestProtoFile.RepeatedUint32Extension  , 0));
-      Assert.AreEqual(204UL , message.GetExtension(UnitTestProtoFile.RepeatedUint64Extension  , 0));
-      Assert.AreEqual(205  , message.GetExtension(UnitTestProtoFile.RepeatedSint32Extension  , 0));
-      Assert.AreEqual(206L , message.GetExtension(UnitTestProtoFile.RepeatedSint64Extension  , 0));
-      Assert.AreEqual(207U  , message.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension , 0));
-      Assert.AreEqual(208UL , message.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension , 0));
-      Assert.AreEqual(209  , message.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 0));
-      Assert.AreEqual(210L , message.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 0));
-      Assert.AreEqual(211F , message.GetExtension(UnitTestProtoFile.RepeatedFloatExtension   , 0));
-      Assert.AreEqual(212D , message.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension  , 0));
-      Assert.AreEqual(true , message.GetExtension(UnitTestProtoFile.RepeatedBoolExtension    , 0));
-      Assert.AreEqual("215", message.GetExtension(UnitTestProtoFile.RepeatedStringExtension  , 0));
-      Assert.AreEqual(ToBytes("216"), message.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 0));
-
-      Assert.AreEqual(217, message.GetExtension(UnitTestProtoFile.RepeatedGroupExtension         , 0).A);
-      Assert.AreEqual(218, message.GetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension , 0).Bb);
-      Assert.AreEqual(219, message.GetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 0).C);
-      Assert.AreEqual(220, message.GetExtension(UnitTestProtoFile.RepeatedImportMessageExtension , 0).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 0));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 0));
-      Assert.AreEqual(ImportEnum.IMPORT_BAR, message.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 0));
-
-      Assert.AreEqual("224", message.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 0));
-      Assert.AreEqual("225", message.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 0));
-
-      Assert.AreEqual(301  , message.GetExtension(UnitTestProtoFile.RepeatedInt32Extension   , 1));
-      Assert.AreEqual(302L , message.GetExtension(UnitTestProtoFile.RepeatedInt64Extension   , 1));
-      Assert.AreEqual(303U  , message.GetExtension(UnitTestProtoFile.RepeatedUint32Extension  , 1));
-      Assert.AreEqual(304UL , message.GetExtension(UnitTestProtoFile.RepeatedUint64Extension  , 1));
-      Assert.AreEqual(305  , message.GetExtension(UnitTestProtoFile.RepeatedSint32Extension  , 1));
-      Assert.AreEqual(306L , message.GetExtension(UnitTestProtoFile.RepeatedSint64Extension  , 1));
-      Assert.AreEqual(307U  , message.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension , 1));
-      Assert.AreEqual(308UL , message.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension , 1));
-      Assert.AreEqual(309  , message.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 1));
-      Assert.AreEqual(310L , message.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 1));
-      Assert.AreEqual(311F , message.GetExtension(UnitTestProtoFile.RepeatedFloatExtension   , 1));
-      Assert.AreEqual(312D , message.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension  , 1));
-      Assert.AreEqual(false, message.GetExtension(UnitTestProtoFile.RepeatedBoolExtension    , 1));
-      Assert.AreEqual("315", message.GetExtension(UnitTestProtoFile.RepeatedStringExtension  , 1));
-      Assert.AreEqual(ToBytes("316"), message.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 1));
-
-      Assert.AreEqual(317, message.GetExtension(UnitTestProtoFile.RepeatedGroupExtension         , 1).A);
-      Assert.AreEqual(318, message.GetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension , 1).Bb);
-      Assert.AreEqual(319, message.GetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 1).C);
-      Assert.AreEqual(320, message.GetExtension(UnitTestProtoFile.RepeatedImportMessageExtension , 1).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAZ, message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 1));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 1));
-      Assert.AreEqual(ImportEnum.IMPORT_BAZ, message.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 1));
-
-      Assert.AreEqual("324", message.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 1));
-      Assert.AreEqual("325", message.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 1));
-
-      // -----------------------------------------------------------------
-
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultInt32Extension   ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultInt64Extension   ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultUint32Extension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultUint64Extension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultSint32Extension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultSint64Extension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultFixed32Extension ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultFixed64Extension ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultSfixed32Extension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultSfixed64Extension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultFloatExtension   ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultDoubleExtension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultBoolExtension    ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultStringExtension  ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultBytesExtension   ));
-
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultNestedEnumExtension ));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultImportEnumExtension ));
-
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultStringPieceExtension));
-      Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultCordExtension));
-
-      Assert.AreEqual(401  , message.GetExtension(UnitTestProtoFile.DefaultInt32Extension   ));
-      Assert.AreEqual(402L , message.GetExtension(UnitTestProtoFile.DefaultInt64Extension   ));
-      Assert.AreEqual(403U  , message.GetExtension(UnitTestProtoFile.DefaultUint32Extension  ));
-      Assert.AreEqual(404UL , message.GetExtension(UnitTestProtoFile.DefaultUint64Extension  ));
-      Assert.AreEqual(405  , message.GetExtension(UnitTestProtoFile.DefaultSint32Extension  ));
-      Assert.AreEqual(406L , message.GetExtension(UnitTestProtoFile.DefaultSint64Extension  ));
-      Assert.AreEqual(407U  , message.GetExtension(UnitTestProtoFile.DefaultFixed32Extension ));
-      Assert.AreEqual(408UL , message.GetExtension(UnitTestProtoFile.DefaultFixed64Extension ));
-      Assert.AreEqual(409  , message.GetExtension(UnitTestProtoFile.DefaultSfixed32Extension));
-      Assert.AreEqual(410L , message.GetExtension(UnitTestProtoFile.DefaultSfixed64Extension));
-      Assert.AreEqual(411F , message.GetExtension(UnitTestProtoFile.DefaultFloatExtension   ));
-      Assert.AreEqual(412D , message.GetExtension(UnitTestProtoFile.DefaultDoubleExtension  ));
-      Assert.AreEqual(false, message.GetExtension(UnitTestProtoFile.DefaultBoolExtension    ));
-      Assert.AreEqual("415", message.GetExtension(UnitTestProtoFile.DefaultStringExtension  ));
-      Assert.AreEqual(ToBytes("416"), message.GetExtension(UnitTestProtoFile.DefaultBytesExtension));
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.GetExtension(UnitTestProtoFile.DefaultNestedEnumExtension ));
-      Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.GetExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
-      Assert.AreEqual(ImportEnum.IMPORT_FOO, message.GetExtension(UnitTestProtoFile.DefaultImportEnumExtension));
-
-      Assert.AreEqual("424", message.GetExtension(UnitTestProtoFile.DefaultStringPieceExtension));
-      Assert.AreEqual("425", message.GetExtension(UnitTestProtoFile.DefaultCordExtension));
-    }
-
-    /// <summary>
-    /// Modifies the repeated extensions of the given message to contain the values
-    /// expected by AssertRepeatedExtensionsModified.
-    /// </summary>
-    internal static void ModifyRepeatedExtensions(TestAllExtensions.Builder message) {
-      message.SetExtension(UnitTestProtoFile.RepeatedInt32Extension, 1, 501);
-      message.SetExtension(UnitTestProtoFile.RepeatedInt64Extension, 1, 502L);
-      message.SetExtension(UnitTestProtoFile.RepeatedUint32Extension, 1, 503U);
-      message.SetExtension(UnitTestProtoFile.RepeatedUint64Extension, 1, 504UL);
-      message.SetExtension(UnitTestProtoFile.RepeatedSint32Extension, 1, 505);
-      message.SetExtension(UnitTestProtoFile.RepeatedSint64Extension, 1, 506L);
-      message.SetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 1, 507U);
-      message.SetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 1, 508UL);
-      message.SetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 1, 509);
-      message.SetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 1, 510L);
-      message.SetExtension(UnitTestProtoFile.RepeatedFloatExtension, 1, 511F);
-      message.SetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1, 512D);
-      message.SetExtension(UnitTestProtoFile.RepeatedBoolExtension, 1, true);
-      message.SetExtension(UnitTestProtoFile.RepeatedStringExtension, 1, "515");
-      message.SetExtension(UnitTestProtoFile.RepeatedBytesExtension, 1, ToBytes("516"));
-
-      message.SetExtension(UnitTestProtoFile.RepeatedGroupExtension, 1, RepeatedGroup_extension.CreateBuilder().SetA(517).Build());
-      message.SetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, 1, TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(518).Build());
-      message.SetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 1, ForeignMessage.CreateBuilder().SetC(519).Build());
-      message.SetExtension(UnitTestProtoFile.RepeatedImportMessageExtension, 1, ImportMessage.CreateBuilder().SetD(520).Build());
-
-      message.SetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 1, TestAllTypes.Types.NestedEnum.FOO);
-      message.SetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 1, ForeignEnum.FOREIGN_FOO);
-      message.SetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 1, ImportEnum.IMPORT_FOO);
-
-      message.SetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 1, "524");
-      message.SetExtension(UnitTestProtoFile.RepeatedCordExtension, 1, "525");
-    }
-
-    /// <summary>
-    /// Asserts that all repeated extensions are set to the values assigned by
-    /// SetAllExtensions follwed by ModifyRepeatedExtensions.
-    /// </summary>
-    internal static void AssertRepeatedExtensionsModified(TestAllExtensions message) {
-      // ModifyRepeatedFields only sets the second repeated element of each
-      // field.  In addition to verifying this, we also verify that the first
-      // element and size were *not* modified.
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFloatExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedBoolExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedBytesExtension));
-
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedGroupExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedMessageExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignMessageExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportMessageExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedEnumExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignEnumExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportEnumExtension));
-
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringPieceExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedCordExtension));
-
-      Assert.AreEqual(201, message.GetExtension(UnitTestProtoFile.RepeatedInt32Extension, 0));
-      Assert.AreEqual(202L, message.GetExtension(UnitTestProtoFile.RepeatedInt64Extension, 0));
-      Assert.AreEqual(203U, message.GetExtension(UnitTestProtoFile.RepeatedUint32Extension, 0));
-      Assert.AreEqual(204UL, message.GetExtension(UnitTestProtoFile.RepeatedUint64Extension, 0));
-      Assert.AreEqual(205, message.GetExtension(UnitTestProtoFile.RepeatedSint32Extension, 0));
-      Assert.AreEqual(206L, message.GetExtension(UnitTestProtoFile.RepeatedSint64Extension, 0));
-      Assert.AreEqual(207U, message.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 0));
-      Assert.AreEqual(208UL, message.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 0));
-      Assert.AreEqual(209, message.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 0));
-      Assert.AreEqual(210L, message.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 0));
-      Assert.AreEqual(211F, message.GetExtension(UnitTestProtoFile.RepeatedFloatExtension, 0));
-      Assert.AreEqual(212D, message.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 0));
-      Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.RepeatedBoolExtension, 0));
-      Assert.AreEqual("215", message.GetExtension(UnitTestProtoFile.RepeatedStringExtension, 0));
-      Assert.AreEqual(ToBytes("216"), message.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 0));
-
-      Assert.AreEqual(217, message.GetExtension(UnitTestProtoFile.RepeatedGroupExtension, 0).A);
-      Assert.AreEqual(218, message.GetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, 0).Bb);
-      Assert.AreEqual(219, message.GetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 0).C);
-      Assert.AreEqual(220, message.GetExtension(UnitTestProtoFile.RepeatedImportMessageExtension, 0).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 0));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 0));
-      Assert.AreEqual(ImportEnum.IMPORT_BAR, message.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 0));
-
-      Assert.AreEqual("224", message.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 0));
-      Assert.AreEqual("225", message.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 0));
-
-      // Actually verify the second (modified) elements now.
-      Assert.AreEqual(501, message.GetExtension(UnitTestProtoFile.RepeatedInt32Extension, 1));
-      Assert.AreEqual(502L, message.GetExtension(UnitTestProtoFile.RepeatedInt64Extension, 1));
-      Assert.AreEqual(503U, message.GetExtension(UnitTestProtoFile.RepeatedUint32Extension, 1));
-      Assert.AreEqual(504UL, message.GetExtension(UnitTestProtoFile.RepeatedUint64Extension, 1));
-      Assert.AreEqual(505, message.GetExtension(UnitTestProtoFile.RepeatedSint32Extension, 1));
-      Assert.AreEqual(506L, message.GetExtension(UnitTestProtoFile.RepeatedSint64Extension, 1));
-      Assert.AreEqual(507U, message.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 1));
-      Assert.AreEqual(508UL, message.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 1));
-      Assert.AreEqual(509, message.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 1));
-      Assert.AreEqual(510L, message.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 1));
-      Assert.AreEqual(511F, message.GetExtension(UnitTestProtoFile.RepeatedFloatExtension, 1));
-      Assert.AreEqual(512D, message.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1));
-      Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.RepeatedBoolExtension, 1));
-      Assert.AreEqual("515", message.GetExtension(UnitTestProtoFile.RepeatedStringExtension, 1));
-      Assert.AreEqual(ToBytes("516"), message.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 1));
-
-      Assert.AreEqual(517, message.GetExtension(UnitTestProtoFile.RepeatedGroupExtension, 1).A);
-      Assert.AreEqual(518, message.GetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, 1).Bb);
-      Assert.AreEqual(519, message.GetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 1).C);
-      Assert.AreEqual(520, message.GetExtension(UnitTestProtoFile.RepeatedImportMessageExtension, 1).D);
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 1));
-      Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 1));
-      Assert.AreEqual(ImportEnum.IMPORT_FOO, message.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 1));
-
-      Assert.AreEqual("524", message.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 1));
-      Assert.AreEqual("525", message.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 1));
-    }
-
-    internal static void AssertExtensionsClear(TestAllExtensions message) {
-      // HasBlah() should initially be false for all optional fields.
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalInt64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalUint32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalUint64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalSint32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalSint64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalFixed32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalFixed64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalSfixed32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalSfixed64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalFloatExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalDoubleExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalBoolExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalStringExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalBytesExtension));
-
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalGroupExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalNestedMessageExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalForeignMessageExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalImportMessageExtension));
-
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalImportEnumExtension));
-
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalStringPieceExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalCordExtension));
-
-      // Optional fields without defaults are set to zero or something like it.
-      Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
-      Assert.AreEqual(0L, message.GetExtension(UnitTestProtoFile.OptionalInt64Extension));
-      Assert.AreEqual(0U, message.GetExtension(UnitTestProtoFile.OptionalUint32Extension));
-      Assert.AreEqual(0UL, message.GetExtension(UnitTestProtoFile.OptionalUint64Extension));
-      Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalSint32Extension));
-      Assert.AreEqual(0L, message.GetExtension(UnitTestProtoFile.OptionalSint64Extension));
-      Assert.AreEqual(0U, message.GetExtension(UnitTestProtoFile.OptionalFixed32Extension));
-      Assert.AreEqual(0UL, message.GetExtension(UnitTestProtoFile.OptionalFixed64Extension));
-      Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalSfixed32Extension));
-      Assert.AreEqual(0L, message.GetExtension(UnitTestProtoFile.OptionalSfixed64Extension));
-      Assert.AreEqual(0F, message.GetExtension(UnitTestProtoFile.OptionalFloatExtension));
-      Assert.AreEqual(0D, message.GetExtension(UnitTestProtoFile.OptionalDoubleExtension));
-      Assert.AreEqual(false, message.GetExtension(UnitTestProtoFile.OptionalBoolExtension));
-      Assert.AreEqual("", message.GetExtension(UnitTestProtoFile.OptionalStringExtension));
-      Assert.AreEqual(ByteString.Empty, message.GetExtension(UnitTestProtoFile.OptionalBytesExtension));
-
-      // Embedded messages should also be clear.
-      Assert.IsFalse(message.GetExtension(UnitTestProtoFile.OptionalGroupExtension).HasA);
-      Assert.IsFalse(message.GetExtension(UnitTestProtoFile.OptionalNestedMessageExtension).HasBb);
-      Assert.IsFalse(message.GetExtension(UnitTestProtoFile.OptionalForeignMessageExtension).HasC);
-      Assert.IsFalse(message.GetExtension(UnitTestProtoFile.OptionalImportMessageExtension).HasD);
-
-      Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalGroupExtension).A);
-      Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalNestedMessageExtension).Bb);
-      Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalForeignMessageExtension).C);
-      Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalImportMessageExtension).D);
-
-      // Enums without defaults are set to the first value in the enum.
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
-      Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.GetExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
-      Assert.AreEqual(ImportEnum.IMPORT_FOO, message.GetExtension(UnitTestProtoFile.OptionalImportEnumExtension));
-
-      Assert.AreEqual("", message.GetExtension(UnitTestProtoFile.OptionalStringPieceExtension));
-      Assert.AreEqual("", message.GetExtension(UnitTestProtoFile.OptionalCordExtension));
-
-      // Repeated fields are empty.
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt64Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint32Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint64Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint32Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint64Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed32Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed64Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed32Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed64Extension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedFloatExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedBoolExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedBytesExtension));
-
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedGroupExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedMessageExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignMessageExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportMessageExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedEnumExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignEnumExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportEnumExtension));
-
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringPieceExtension));
-      Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedCordExtension));
-
-      // HasBlah() should also be false for all default fields.
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultInt32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultInt64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultUint32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultUint64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultSint32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultSint64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultFixed32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultFixed64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultSfixed32Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultSfixed64Extension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultFloatExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultDoubleExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultBoolExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultStringExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultBytesExtension));
-
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultNestedEnumExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultImportEnumExtension));
-
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultStringPieceExtension));
-      Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultCordExtension));
-
-      // Fields with defaults have their default values (duh).
-      Assert.AreEqual(41, message.GetExtension(UnitTestProtoFile.DefaultInt32Extension));
-      Assert.AreEqual(42L, message.GetExtension(UnitTestProtoFile.DefaultInt64Extension));
-      Assert.AreEqual(43U, message.GetExtension(UnitTestProtoFile.DefaultUint32Extension));
-      Assert.AreEqual(44UL, message.GetExtension(UnitTestProtoFile.DefaultUint64Extension));
-      Assert.AreEqual(-45, message.GetExtension(UnitTestProtoFile.DefaultSint32Extension));
-      Assert.AreEqual(46L, message.GetExtension(UnitTestProtoFile.DefaultSint64Extension));
-      Assert.AreEqual(47U, message.GetExtension(UnitTestProtoFile.DefaultFixed32Extension));
-      Assert.AreEqual(48UL, message.GetExtension(UnitTestProtoFile.DefaultFixed64Extension));
-      Assert.AreEqual(49, message.GetExtension(UnitTestProtoFile.DefaultSfixed32Extension));
-      Assert.AreEqual(-50L, message.GetExtension(UnitTestProtoFile.DefaultSfixed64Extension));
-      Assert.AreEqual(51.5F, message.GetExtension(UnitTestProtoFile.DefaultFloatExtension));
-      Assert.AreEqual(52e3D, message.GetExtension(UnitTestProtoFile.DefaultDoubleExtension));
-      Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.DefaultBoolExtension));
-      Assert.AreEqual("hello", message.GetExtension(UnitTestProtoFile.DefaultStringExtension));
-      Assert.AreEqual(ToBytes("world"), message.GetExtension(UnitTestProtoFile.DefaultBytesExtension));
-
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.GetExtension(UnitTestProtoFile.DefaultNestedEnumExtension));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
-      Assert.AreEqual(ImportEnum.IMPORT_BAR, message.GetExtension(UnitTestProtoFile.DefaultImportEnumExtension));
-
-      Assert.AreEqual("abc", message.GetExtension(UnitTestProtoFile.DefaultStringPieceExtension));
-      Assert.AreEqual("123", message.GetExtension(UnitTestProtoFile.DefaultCordExtension));
-    }
-
-    /// <summary>
-    /// Set every field of the specified message to a unique value.
-    /// </summary>
-    public static void SetPackedFields(TestPackedTypes.Builder message) {
-      message.AddPackedInt32(601);
-      message.AddPackedInt64(602);
-      message.AddPackedUint32(603);
-      message.AddPackedUint64(604);
-      message.AddPackedSint32(605);
-      message.AddPackedSint64(606);
-      message.AddPackedFixed32(607);
-      message.AddPackedFixed64(608);
-      message.AddPackedSfixed32(609);
-      message.AddPackedSfixed64(610);
-      message.AddPackedFloat(611);
-      message.AddPackedDouble(612);
-      message.AddPackedBool(true);
-      message.AddPackedEnum(ForeignEnum.FOREIGN_BAR);
-      // Add a second one of each field.
-      message.AddPackedInt32(701);
-      message.AddPackedInt64(702);
-      message.AddPackedUint32(703);
-      message.AddPackedUint64(704);
-      message.AddPackedSint32(705);
-      message.AddPackedSint64(706);
-      message.AddPackedFixed32(707);
-      message.AddPackedFixed64(708);
-      message.AddPackedSfixed32(709);
-      message.AddPackedSfixed64(710);
-      message.AddPackedFloat(711);
-      message.AddPackedDouble(712);
-      message.AddPackedBool(false);
-      message.AddPackedEnum(ForeignEnum.FOREIGN_BAZ);
-    }
-
-    /// <summary>
-    /// Asserts that all the fields of the specified message are set to the values assigned
-    /// in SetPackedFields.
-    /// </summary>
-    public static void AssertPackedFieldsSet(TestPackedTypes message) {
-      Assert.AreEqual(2, message.PackedInt32Count);
-      Assert.AreEqual(2, message.PackedInt64Count);
-      Assert.AreEqual(2, message.PackedUint32Count);
-      Assert.AreEqual(2, message.PackedUint64Count);
-      Assert.AreEqual(2, message.PackedSint32Count);
-      Assert.AreEqual(2, message.PackedSint64Count);
-      Assert.AreEqual(2, message.PackedFixed32Count);
-      Assert.AreEqual(2, message.PackedFixed64Count);
-      Assert.AreEqual(2, message.PackedSfixed32Count);
-      Assert.AreEqual(2, message.PackedSfixed64Count);
-      Assert.AreEqual(2, message.PackedFloatCount);
-      Assert.AreEqual(2, message.PackedDoubleCount);
-      Assert.AreEqual(2, message.PackedBoolCount);
-      Assert.AreEqual(2, message.PackedEnumCount);
-      Assert.AreEqual(601, message.GetPackedInt32(0));
-      Assert.AreEqual(602, message.GetPackedInt64(0));
-      Assert.AreEqual(603, message.GetPackedUint32(0));
-      Assert.AreEqual(604, message.GetPackedUint64(0));
-      Assert.AreEqual(605, message.GetPackedSint32(0));
-      Assert.AreEqual(606, message.GetPackedSint64(0));
-      Assert.AreEqual(607, message.GetPackedFixed32(0));
-      Assert.AreEqual(608, message.GetPackedFixed64(0));
-      Assert.AreEqual(609, message.GetPackedSfixed32(0));
-      Assert.AreEqual(610, message.GetPackedSfixed64(0));
-      Assert.AreEqual(611, message.GetPackedFloat(0), 0.0);
-      Assert.AreEqual(612, message.GetPackedDouble(0), 0.0);
-      Assert.AreEqual(true, message.GetPackedBool(0));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetPackedEnum(0));
-      Assert.AreEqual(701, message.GetPackedInt32(1));
-      Assert.AreEqual(702, message.GetPackedInt64(1));
-      Assert.AreEqual(703, message.GetPackedUint32(1));
-      Assert.AreEqual(704, message.GetPackedUint64(1));
-      Assert.AreEqual(705, message.GetPackedSint32(1));
-      Assert.AreEqual(706, message.GetPackedSint64(1));
-      Assert.AreEqual(707, message.GetPackedFixed32(1));
-      Assert.AreEqual(708, message.GetPackedFixed64(1));
-      Assert.AreEqual(709, message.GetPackedSfixed32(1));
-      Assert.AreEqual(710, message.GetPackedSfixed64(1));
-      Assert.AreEqual(711, message.GetPackedFloat(1), 0.0);
-      Assert.AreEqual(712, message.GetPackedDouble(1), 0.0);
-      Assert.AreEqual(false, message.GetPackedBool(1));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.GetPackedEnum(1));
-    }
-
-    public static void SetPackedExtensions(TestPackedExtensions.Builder message) {
-      message.AddExtension(UnitTestProtoFile.PackedInt32Extension, 601);
-      message.AddExtension(UnitTestProtoFile.PackedInt64Extension, 602L);
-      message.AddExtension(UnitTestProtoFile.PackedUint32Extension, 603U);
-      message.AddExtension(UnitTestProtoFile.PackedUint64Extension, 604UL);
-      message.AddExtension(UnitTestProtoFile.PackedSint32Extension, 605);
-      message.AddExtension(UnitTestProtoFile.PackedSint64Extension, 606L);
-      message.AddExtension(UnitTestProtoFile.PackedFixed32Extension, 607U);
-      message.AddExtension(UnitTestProtoFile.PackedFixed64Extension, 608UL);
-      message.AddExtension(UnitTestProtoFile.PackedSfixed32Extension, 609);
-      message.AddExtension(UnitTestProtoFile.PackedSfixed64Extension, 610L);
-      message.AddExtension(UnitTestProtoFile.PackedFloatExtension, 611F);
-      message.AddExtension(UnitTestProtoFile.PackedDoubleExtension, 612D);
-      message.AddExtension(UnitTestProtoFile.PackedBoolExtension, true);
-      message.AddExtension(UnitTestProtoFile.PackedEnumExtension, ForeignEnum.FOREIGN_BAR);
-      // Add a second one of each field.
-      message.AddExtension(UnitTestProtoFile.PackedInt32Extension, 701);
-      message.AddExtension(UnitTestProtoFile.PackedInt64Extension, 702L);
-      message.AddExtension(UnitTestProtoFile.PackedUint32Extension, 703U);
-      message.AddExtension(UnitTestProtoFile.PackedUint64Extension, 704UL);
-      message.AddExtension(UnitTestProtoFile.PackedSint32Extension, 705);
-      message.AddExtension(UnitTestProtoFile.PackedSint64Extension, 706L);
-      message.AddExtension(UnitTestProtoFile.PackedFixed32Extension, 707U);
-      message.AddExtension(UnitTestProtoFile.PackedFixed64Extension, 708UL);
-      message.AddExtension(UnitTestProtoFile.PackedSfixed32Extension, 709);
-      message.AddExtension(UnitTestProtoFile.PackedSfixed64Extension, 710L);
-      message.AddExtension(UnitTestProtoFile.PackedFloatExtension, 711F);
-      message.AddExtension(UnitTestProtoFile.PackedDoubleExtension, 712D);
-      message.AddExtension(UnitTestProtoFile.PackedBoolExtension, false);
-      message.AddExtension(UnitTestProtoFile.PackedEnumExtension, ForeignEnum.FOREIGN_BAZ);
-    }
-
-    public static void AssertPackedExtensionsSet(TestPackedExtensions message) {
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedInt32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedInt64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedUint32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedUint64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedSint32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedSint64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedFixed32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedFixed64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedSfixed32Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedSfixed64Extension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedFloatExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedDoubleExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedBoolExtension));
-      Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedEnumExtension));
-      Assert.AreEqual(601, message.GetExtension(UnitTestProtoFile.PackedInt32Extension, 0));
-      Assert.AreEqual(602L, message.GetExtension(UnitTestProtoFile.PackedInt64Extension, 0));
-      Assert.AreEqual(603, message.GetExtension(UnitTestProtoFile.PackedUint32Extension, 0));
-      Assert.AreEqual(604L, message.GetExtension(UnitTestProtoFile.PackedUint64Extension, 0));
-      Assert.AreEqual(605, message.GetExtension(UnitTestProtoFile.PackedSint32Extension, 0));
-      Assert.AreEqual(606L, message.GetExtension(UnitTestProtoFile.PackedSint64Extension, 0));
-      Assert.AreEqual(607, message.GetExtension(UnitTestProtoFile.PackedFixed32Extension, 0));
-      Assert.AreEqual(608L, message.GetExtension(UnitTestProtoFile.PackedFixed64Extension, 0));
-      Assert.AreEqual(609, message.GetExtension(UnitTestProtoFile.PackedSfixed32Extension, 0));
-      Assert.AreEqual(610L, message.GetExtension(UnitTestProtoFile.PackedSfixed64Extension, 0));
-      Assert.AreEqual(611F, message.GetExtension(UnitTestProtoFile.PackedFloatExtension, 0));
-      Assert.AreEqual(612D, message.GetExtension(UnitTestProtoFile.PackedDoubleExtension, 0));
-      Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.PackedBoolExtension, 0));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAR,
-                            message.GetExtension(UnitTestProtoFile.PackedEnumExtension, 0));
-      Assert.AreEqual(701, message.GetExtension(UnitTestProtoFile.PackedInt32Extension, 1));
-      Assert.AreEqual(702L, message.GetExtension(UnitTestProtoFile.PackedInt64Extension, 1));
-      Assert.AreEqual(703, message.GetExtension(UnitTestProtoFile.PackedUint32Extension, 1));
-      Assert.AreEqual(704L, message.GetExtension(UnitTestProtoFile.PackedUint64Extension, 1));
-      Assert.AreEqual(705, message.GetExtension(UnitTestProtoFile.PackedSint32Extension, 1));
-      Assert.AreEqual(706L, message.GetExtension(UnitTestProtoFile.PackedSint64Extension, 1));
-      Assert.AreEqual(707, message.GetExtension(UnitTestProtoFile.PackedFixed32Extension, 1));
-      Assert.AreEqual(708L, message.GetExtension(UnitTestProtoFile.PackedFixed64Extension, 1));
-      Assert.AreEqual(709, message.GetExtension(UnitTestProtoFile.PackedSfixed32Extension, 1));
-      Assert.AreEqual(710L, message.GetExtension(UnitTestProtoFile.PackedSfixed64Extension, 1));
-      Assert.AreEqual(711F, message.GetExtension(UnitTestProtoFile.PackedFloatExtension, 1));
-      Assert.AreEqual(712D, message.GetExtension(UnitTestProtoFile.PackedDoubleExtension, 1));
-      Assert.AreEqual(false, message.GetExtension(UnitTestProtoFile.PackedBoolExtension, 1));
-      Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.GetExtension(UnitTestProtoFile.PackedEnumExtension, 1));
-    }
-
-    private static ByteString goldenPackedFieldsMessage = null;
-
-    /// <summary>
-    /// Get the bytes of the "golden packed fields message".  This is a serialized
-    /// TestPackedTypes with all fields set as they would be by SetPackedFields,
-    /// but it is loaded from a file on disk rather than generated dynamically.
-    /// The file is actually generated by C++ code, so testing against it verifies compatibility
-    /// with C++.
-    /// </summary>
-    public static ByteString GetGoldenPackedFieldsMessage() {
-      if (goldenPackedFieldsMessage == null) {
-        goldenPackedFieldsMessage = ReadBytesFromFile("golden_packed_fields_message");
-      }
-      return goldenPackedFieldsMessage;
-    }
-
-    private static readonly string[] TestCultures = { "en-US", "en-GB", "fr-FR", "de-DE" };
-
-    public static void TestInMultipleCultures(Action test) {
-      CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
-      foreach (string culture in TestCultures) {
-        try {
-          Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
-          test();
-        } finally {
-          Thread.CurrentThread.CurrentCulture = originalCulture;
-        }
-      }
-    }
-    
-    /// <summary>
-    /// Helper to construct a byte array from a bunch of bytes.
-    /// </summary>
-    internal static byte[] Bytes(params byte[] bytesAsInts) {
-      byte[] bytes = new byte[bytesAsInts.Length];
-      for (int i = 0; i < bytesAsInts.Length; i++) {
-        bytes[i] = (byte)bytesAsInts[i];
-      }
-      return bytes;
-    }
-
-    internal static void AssertArgumentNullException(Action action) {
-      try {
-        action();
-        Assert.Fail("Exception was not thrown");
-      } catch (ArgumentNullException) {
-        // We expect this exception.
-      }
-    }
-  }
-}
+#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 System.Threading;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    internal static class TestUtil
+    {
+        private static string testDataDirectory;
+        private static ByteString goldenMessage = null;
+
+        internal static string TestDataDirectory
+        {
+            get
+            {
+                if (testDataDirectory != null)
+                {
+                    return testDataDirectory;
+                }
+
+                DirectoryInfo ancestor = new DirectoryInfo(".");
+                // Search each parent directory looking for "testdata".
+                while (ancestor != null)
+                {
+                    string candidate = Path.Combine(ancestor.FullName, "testdata");
+                    if (Directory.Exists(candidate))
+                    {
+                        testDataDirectory = candidate;
+                        return candidate;
+                    }
+                    ancestor = ancestor.Parent;
+                }
+                // TODO(jonskeet): Come up with a better exception to throw
+                throw new Exception("Unable to find directory containing test files");
+            }
+        }
+
+        internal static ByteString GoldenMessage
+        {
+            get
+            {
+                if (goldenMessage == null)
+                {
+                    goldenMessage = ReadBytesFromFile("golden_message");
+                }
+                return goldenMessage;
+            }
+        }
+
+        /// <summary>
+        /// Creates an unmodifiable ExtensionRegistry containing all the extensions
+        /// of TestAllExtensions.
+        /// </summary>
+        /// <returns></returns>
+        internal static ExtensionRegistry CreateExtensionRegistry()
+        {
+            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+            RegisterAllExtensions(registry);
+            return registry.AsReadOnly();
+        }
+
+        /// <summary>
+        /// Registers all of the extensions in TestAllExtensions with the given
+        /// ExtensionRegistry.
+        /// </summary>
+        internal static void RegisterAllExtensions(ExtensionRegistry registry)
+        {
+            registry.Add(UnitTestProtoFile.OptionalInt32Extension);
+            registry.Add(UnitTestProtoFile.OptionalInt64Extension);
+            registry.Add(UnitTestProtoFile.OptionalUint32Extension);
+            registry.Add(UnitTestProtoFile.OptionalUint64Extension);
+            registry.Add(UnitTestProtoFile.OptionalSint32Extension);
+            registry.Add(UnitTestProtoFile.OptionalSint64Extension);
+            registry.Add(UnitTestProtoFile.OptionalFixed32Extension);
+            registry.Add(UnitTestProtoFile.OptionalFixed64Extension);
+            registry.Add(UnitTestProtoFile.OptionalSfixed32Extension);
+            registry.Add(UnitTestProtoFile.OptionalSfixed64Extension);
+            registry.Add(UnitTestProtoFile.OptionalFloatExtension);
+            registry.Add(UnitTestProtoFile.OptionalDoubleExtension);
+            registry.Add(UnitTestProtoFile.OptionalBoolExtension);
+            registry.Add(UnitTestProtoFile.OptionalStringExtension);
+            registry.Add(UnitTestProtoFile.OptionalBytesExtension);
+            registry.Add(UnitTestProtoFile.OptionalGroupExtension);
+            registry.Add(UnitTestProtoFile.OptionalNestedMessageExtension);
+            registry.Add(UnitTestProtoFile.OptionalForeignMessageExtension);
+            registry.Add(UnitTestProtoFile.OptionalImportMessageExtension);
+            registry.Add(UnitTestProtoFile.OptionalNestedEnumExtension);
+            registry.Add(UnitTestProtoFile.OptionalForeignEnumExtension);
+            registry.Add(UnitTestProtoFile.OptionalImportEnumExtension);
+            registry.Add(UnitTestProtoFile.OptionalStringPieceExtension);
+            registry.Add(UnitTestProtoFile.OptionalCordExtension);
+
+            registry.Add(UnitTestProtoFile.RepeatedInt32Extension);
+            registry.Add(UnitTestProtoFile.RepeatedInt64Extension);
+            registry.Add(UnitTestProtoFile.RepeatedUint32Extension);
+            registry.Add(UnitTestProtoFile.RepeatedUint64Extension);
+            registry.Add(UnitTestProtoFile.RepeatedSint32Extension);
+            registry.Add(UnitTestProtoFile.RepeatedSint64Extension);
+            registry.Add(UnitTestProtoFile.RepeatedFixed32Extension);
+            registry.Add(UnitTestProtoFile.RepeatedFixed64Extension);
+            registry.Add(UnitTestProtoFile.RepeatedSfixed32Extension);
+            registry.Add(UnitTestProtoFile.RepeatedSfixed64Extension);
+            registry.Add(UnitTestProtoFile.RepeatedFloatExtension);
+            registry.Add(UnitTestProtoFile.RepeatedDoubleExtension);
+            registry.Add(UnitTestProtoFile.RepeatedBoolExtension);
+            registry.Add(UnitTestProtoFile.RepeatedStringExtension);
+            registry.Add(UnitTestProtoFile.RepeatedBytesExtension);
+            registry.Add(UnitTestProtoFile.RepeatedGroupExtension);
+            registry.Add(UnitTestProtoFile.RepeatedNestedMessageExtension);
+            registry.Add(UnitTestProtoFile.RepeatedForeignMessageExtension);
+            registry.Add(UnitTestProtoFile.RepeatedImportMessageExtension);
+            registry.Add(UnitTestProtoFile.RepeatedNestedEnumExtension);
+            registry.Add(UnitTestProtoFile.RepeatedForeignEnumExtension);
+            registry.Add(UnitTestProtoFile.RepeatedImportEnumExtension);
+            registry.Add(UnitTestProtoFile.RepeatedStringPieceExtension);
+            registry.Add(UnitTestProtoFile.RepeatedCordExtension);
+
+            registry.Add(UnitTestProtoFile.DefaultInt32Extension);
+            registry.Add(UnitTestProtoFile.DefaultInt64Extension);
+            registry.Add(UnitTestProtoFile.DefaultUint32Extension);
+            registry.Add(UnitTestProtoFile.DefaultUint64Extension);
+            registry.Add(UnitTestProtoFile.DefaultSint32Extension);
+            registry.Add(UnitTestProtoFile.DefaultSint64Extension);
+            registry.Add(UnitTestProtoFile.DefaultFixed32Extension);
+            registry.Add(UnitTestProtoFile.DefaultFixed64Extension);
+            registry.Add(UnitTestProtoFile.DefaultSfixed32Extension);
+            registry.Add(UnitTestProtoFile.DefaultSfixed64Extension);
+            registry.Add(UnitTestProtoFile.DefaultFloatExtension);
+            registry.Add(UnitTestProtoFile.DefaultDoubleExtension);
+            registry.Add(UnitTestProtoFile.DefaultBoolExtension);
+            registry.Add(UnitTestProtoFile.DefaultStringExtension);
+            registry.Add(UnitTestProtoFile.DefaultBytesExtension);
+            registry.Add(UnitTestProtoFile.DefaultNestedEnumExtension);
+            registry.Add(UnitTestProtoFile.DefaultForeignEnumExtension);
+            registry.Add(UnitTestProtoFile.DefaultImportEnumExtension);
+            registry.Add(UnitTestProtoFile.DefaultStringPieceExtension);
+            registry.Add(UnitTestProtoFile.DefaultCordExtension);
+
+            registry.Add(UnitTestProtoFile.PackedInt32Extension);
+            registry.Add(UnitTestProtoFile.PackedInt64Extension);
+            registry.Add(UnitTestProtoFile.PackedUint32Extension);
+            registry.Add(UnitTestProtoFile.PackedUint64Extension);
+            registry.Add(UnitTestProtoFile.PackedSint32Extension);
+            registry.Add(UnitTestProtoFile.PackedSint64Extension);
+            registry.Add(UnitTestProtoFile.PackedFixed32Extension);
+            registry.Add(UnitTestProtoFile.PackedFixed64Extension);
+            registry.Add(UnitTestProtoFile.PackedSfixed32Extension);
+            registry.Add(UnitTestProtoFile.PackedSfixed64Extension);
+            registry.Add(UnitTestProtoFile.PackedFloatExtension);
+            registry.Add(UnitTestProtoFile.PackedDoubleExtension);
+            registry.Add(UnitTestProtoFile.PackedBoolExtension);
+            registry.Add(UnitTestProtoFile.PackedEnumExtension);
+        }
+
+        internal static string ReadTextFromFile(string filePath)
+        {
+            return ReadBytesFromFile(filePath).ToStringUtf8();
+        }
+
+        internal static ByteString ReadBytesFromFile(String filename)
+        {
+            byte[] data = File.ReadAllBytes(Path.Combine(TestDataDirectory, filename));
+            return ByteString.CopyFrom(data);
+        }
+
+        /// <summary>
+        /// Helper to convert a String to ByteString.
+        /// </summary>
+        internal static ByteString ToBytes(String str)
+        {
+            return ByteString.CopyFrom(Encoding.UTF8.GetBytes(str));
+        }
+
+        internal static TestAllTypes GetAllSet()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            SetAllFields(builder);
+            return builder.Build();
+        }
+
+        /// <summary>
+        /// Sets every field of the specified message to the values expected by
+        /// AssertAllFieldsSet.
+        /// </summary>
+        internal static void SetAllFields(TestAllTypes.Builder message)
+        {
+            message.SetOptionalInt32(101);
+            message.SetOptionalInt64(102);
+            message.SetOptionalUint32(103);
+            message.SetOptionalUint64(104);
+            message.SetOptionalSint32(105);
+            message.SetOptionalSint64(106);
+            message.SetOptionalFixed32(107);
+            message.SetOptionalFixed64(108);
+            message.SetOptionalSfixed32(109);
+            message.SetOptionalSfixed64(110);
+            message.SetOptionalFloat(111);
+            message.SetOptionalDouble(112);
+            message.SetOptionalBool(true);
+            message.SetOptionalString("115");
+            message.SetOptionalBytes(ToBytes("116"));
+
+            message.SetOptionalGroup(TestAllTypes.Types.OptionalGroup.CreateBuilder().SetA(117).Build());
+            message.SetOptionalNestedMessage(TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(118).Build());
+            message.SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(119).Build());
+            message.SetOptionalImportMessage(ImportMessage.CreateBuilder().SetD(120).Build());
+
+            message.SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.BAZ);
+            message.SetOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ);
+            message.SetOptionalImportEnum(ImportEnum.IMPORT_BAZ);
+
+            message.SetOptionalStringPiece("124");
+            message.SetOptionalCord("125");
+
+            // -----------------------------------------------------------------
+
+            message.AddRepeatedInt32(201);
+            message.AddRepeatedInt64(202);
+            message.AddRepeatedUint32(203);
+            message.AddRepeatedUint64(204);
+            message.AddRepeatedSint32(205);
+            message.AddRepeatedSint64(206);
+            message.AddRepeatedFixed32(207);
+            message.AddRepeatedFixed64(208);
+            message.AddRepeatedSfixed32(209);
+            message.AddRepeatedSfixed64(210);
+            message.AddRepeatedFloat(211);
+            message.AddRepeatedDouble(212);
+            message.AddRepeatedBool(true);
+            message.AddRepeatedString("215");
+            message.AddRepeatedBytes(ToBytes("216"));
+
+            message.AddRepeatedGroup(TestAllTypes.Types.RepeatedGroup.CreateBuilder().SetA(217).Build());
+            message.AddRepeatedNestedMessage(TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(218).Build());
+            message.AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(219).Build());
+            message.AddRepeatedImportMessage(ImportMessage.CreateBuilder().SetD(220).Build());
+
+            message.AddRepeatedNestedEnum(TestAllTypes.Types.NestedEnum.BAR);
+            message.AddRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR);
+            message.AddRepeatedImportEnum(ImportEnum.IMPORT_BAR);
+
+            message.AddRepeatedStringPiece("224");
+            message.AddRepeatedCord("225");
+
+            // Add a second one of each field.
+            message.AddRepeatedInt32(301);
+            message.AddRepeatedInt64(302);
+            message.AddRepeatedUint32(303);
+            message.AddRepeatedUint64(304);
+            message.AddRepeatedSint32(305);
+            message.AddRepeatedSint64(306);
+            message.AddRepeatedFixed32(307);
+            message.AddRepeatedFixed64(308);
+            message.AddRepeatedSfixed32(309);
+            message.AddRepeatedSfixed64(310);
+            message.AddRepeatedFloat(311);
+            message.AddRepeatedDouble(312);
+            message.AddRepeatedBool(false);
+            message.AddRepeatedString("315");
+            message.AddRepeatedBytes(ToBytes("316"));
+
+            message.AddRepeatedGroup(TestAllTypes.Types.RepeatedGroup.CreateBuilder().SetA(317).Build());
+            message.AddRepeatedNestedMessage(TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(318).Build());
+            message.AddRepeatedForeignMessage(ForeignMessage.CreateBuilder().SetC(319).Build());
+            message.AddRepeatedImportMessage(ImportMessage.CreateBuilder().SetD(320).Build());
+
+            message.AddRepeatedNestedEnum(TestAllTypes.Types.NestedEnum.BAZ);
+            message.AddRepeatedForeignEnum(ForeignEnum.FOREIGN_BAZ);
+            message.AddRepeatedImportEnum(ImportEnum.IMPORT_BAZ);
+
+            message.AddRepeatedStringPiece("324");
+            message.AddRepeatedCord("325");
+
+            // -----------------------------------------------------------------
+
+            message.SetDefaultInt32(401);
+            message.SetDefaultInt64(402);
+            message.SetDefaultUint32(403);
+            message.SetDefaultUint64(404);
+            message.SetDefaultSint32(405);
+            message.SetDefaultSint64(406);
+            message.SetDefaultFixed32(407);
+            message.SetDefaultFixed64(408);
+            message.SetDefaultSfixed32(409);
+            message.SetDefaultSfixed64(410);
+            message.SetDefaultFloat(411);
+            message.SetDefaultDouble(412);
+            message.SetDefaultBool(false);
+            message.SetDefaultString("415");
+            message.SetDefaultBytes(ToBytes("416"));
+
+            message.SetDefaultNestedEnum(TestAllTypes.Types.NestedEnum.FOO);
+            message.SetDefaultForeignEnum(ForeignEnum.FOREIGN_FOO);
+            message.SetDefaultImportEnum(ImportEnum.IMPORT_FOO);
+
+            message.SetDefaultStringPiece("424");
+            message.SetDefaultCord("425");
+        }
+
+        /// <summary>
+        /// Asserts that all fields of the specified message are set to the values
+        /// assigned by SetAllFields.
+        /// </summary>
+        internal static void AssertAllFieldsSet(TestAllTypes message)
+        {
+            Assert.IsTrue(message.HasOptionalInt32);
+            Assert.IsTrue(message.HasOptionalInt64);
+            Assert.IsTrue(message.HasOptionalUint32);
+            Assert.IsTrue(message.HasOptionalUint64);
+            Assert.IsTrue(message.HasOptionalSint32);
+            Assert.IsTrue(message.HasOptionalSint64);
+            Assert.IsTrue(message.HasOptionalFixed32);
+            Assert.IsTrue(message.HasOptionalFixed64);
+            Assert.IsTrue(message.HasOptionalSfixed32);
+            Assert.IsTrue(message.HasOptionalSfixed64);
+            Assert.IsTrue(message.HasOptionalFloat);
+            Assert.IsTrue(message.HasOptionalDouble);
+            Assert.IsTrue(message.HasOptionalBool);
+            Assert.IsTrue(message.HasOptionalString);
+            Assert.IsTrue(message.HasOptionalBytes);
+
+            Assert.IsTrue(message.HasOptionalGroup);
+            Assert.IsTrue(message.HasOptionalNestedMessage);
+            Assert.IsTrue(message.HasOptionalForeignMessage);
+            Assert.IsTrue(message.HasOptionalImportMessage);
+
+            Assert.IsTrue(message.OptionalGroup.HasA);
+            Assert.IsTrue(message.OptionalNestedMessage.HasBb);
+            Assert.IsTrue(message.OptionalForeignMessage.HasC);
+            Assert.IsTrue(message.OptionalImportMessage.HasD);
+
+            Assert.IsTrue(message.HasOptionalNestedEnum);
+            Assert.IsTrue(message.HasOptionalForeignEnum);
+            Assert.IsTrue(message.HasOptionalImportEnum);
+
+            Assert.IsTrue(message.HasOptionalStringPiece);
+            Assert.IsTrue(message.HasOptionalCord);
+
+            Assert.AreEqual(101, message.OptionalInt32);
+            Assert.AreEqual(102, message.OptionalInt64);
+            Assert.AreEqual(103, message.OptionalUint32);
+            Assert.AreEqual(104, message.OptionalUint64);
+            Assert.AreEqual(105, message.OptionalSint32);
+            Assert.AreEqual(106, message.OptionalSint64);
+            Assert.AreEqual(107, message.OptionalFixed32);
+            Assert.AreEqual(108, message.OptionalFixed64);
+            Assert.AreEqual(109, message.OptionalSfixed32);
+            Assert.AreEqual(110, message.OptionalSfixed64);
+            Assert.AreEqual(111, message.OptionalFloat);
+            Assert.AreEqual(112, message.OptionalDouble);
+            Assert.AreEqual(true, message.OptionalBool);
+            Assert.AreEqual("115", message.OptionalString);
+            Assert.AreEqual(ToBytes("116"), message.OptionalBytes);
+
+            Assert.AreEqual(117, message.OptionalGroup.A);
+            Assert.AreEqual(118, message.OptionalNestedMessage.Bb);
+            Assert.AreEqual(119, message.OptionalForeignMessage.C);
+            Assert.AreEqual(120, message.OptionalImportMessage.D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAZ, message.OptionalNestedEnum);
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.OptionalForeignEnum);
+            Assert.AreEqual(ImportEnum.IMPORT_BAZ, message.OptionalImportEnum);
+
+            Assert.AreEqual("124", message.OptionalStringPiece);
+            Assert.AreEqual("125", message.OptionalCord);
+
+            // -----------------------------------------------------------------
+
+            Assert.AreEqual(2, message.RepeatedInt32Count);
+            Assert.AreEqual(2, message.RepeatedInt64Count);
+            Assert.AreEqual(2, message.RepeatedUint32Count);
+            Assert.AreEqual(2, message.RepeatedUint64Count);
+            Assert.AreEqual(2, message.RepeatedSint32Count);
+            Assert.AreEqual(2, message.RepeatedSint64Count);
+            Assert.AreEqual(2, message.RepeatedFixed32Count);
+            Assert.AreEqual(2, message.RepeatedFixed64Count);
+            Assert.AreEqual(2, message.RepeatedSfixed32Count);
+            Assert.AreEqual(2, message.RepeatedSfixed64Count);
+            Assert.AreEqual(2, message.RepeatedFloatCount);
+            Assert.AreEqual(2, message.RepeatedDoubleCount);
+            Assert.AreEqual(2, message.RepeatedBoolCount);
+            Assert.AreEqual(2, message.RepeatedStringCount);
+            Assert.AreEqual(2, message.RepeatedBytesCount);
+
+            Assert.AreEqual(2, message.RepeatedGroupCount);
+            Assert.AreEqual(2, message.RepeatedNestedMessageCount);
+            Assert.AreEqual(2, message.RepeatedForeignMessageCount);
+            Assert.AreEqual(2, message.RepeatedImportMessageCount);
+            Assert.AreEqual(2, message.RepeatedNestedEnumCount);
+            Assert.AreEqual(2, message.RepeatedForeignEnumCount);
+            Assert.AreEqual(2, message.RepeatedImportEnumCount);
+
+            Assert.AreEqual(2, message.RepeatedStringPieceCount);
+            Assert.AreEqual(2, message.RepeatedCordCount);
+
+            Assert.AreEqual(201, message.GetRepeatedInt32(0));
+            Assert.AreEqual(202, message.GetRepeatedInt64(0));
+            Assert.AreEqual(203, message.GetRepeatedUint32(0));
+            Assert.AreEqual(204, message.GetRepeatedUint64(0));
+            Assert.AreEqual(205, message.GetRepeatedSint32(0));
+            Assert.AreEqual(206, message.GetRepeatedSint64(0));
+            Assert.AreEqual(207, message.GetRepeatedFixed32(0));
+            Assert.AreEqual(208, message.GetRepeatedFixed64(0));
+            Assert.AreEqual(209, message.GetRepeatedSfixed32(0));
+            Assert.AreEqual(210, message.GetRepeatedSfixed64(0));
+            Assert.AreEqual(211, message.GetRepeatedFloat(0));
+            Assert.AreEqual(212, message.GetRepeatedDouble(0));
+            Assert.AreEqual(true, message.GetRepeatedBool(0));
+            Assert.AreEqual("215", message.GetRepeatedString(0));
+            Assert.AreEqual(ToBytes("216"), message.GetRepeatedBytes(0));
+
+            Assert.AreEqual(217, message.GetRepeatedGroup(0).A);
+            Assert.AreEqual(218, message.GetRepeatedNestedMessage(0).Bb);
+            Assert.AreEqual(219, message.GetRepeatedForeignMessage(0).C);
+            Assert.AreEqual(220, message.GetRepeatedImportMessage(0).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.GetRepeatedNestedEnum(0));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetRepeatedForeignEnum(0));
+            Assert.AreEqual(ImportEnum.IMPORT_BAR, message.GetRepeatedImportEnum(0));
+
+            Assert.AreEqual("224", message.GetRepeatedStringPiece(0));
+            Assert.AreEqual("225", message.GetRepeatedCord(0));
+
+            Assert.AreEqual(301, message.GetRepeatedInt32(1));
+            Assert.AreEqual(302, message.GetRepeatedInt64(1));
+            Assert.AreEqual(303, message.GetRepeatedUint32(1));
+            Assert.AreEqual(304, message.GetRepeatedUint64(1));
+            Assert.AreEqual(305, message.GetRepeatedSint32(1));
+            Assert.AreEqual(306, message.GetRepeatedSint64(1));
+            Assert.AreEqual(307, message.GetRepeatedFixed32(1));
+            Assert.AreEqual(308, message.GetRepeatedFixed64(1));
+            Assert.AreEqual(309, message.GetRepeatedSfixed32(1));
+            Assert.AreEqual(310, message.GetRepeatedSfixed64(1));
+            Assert.AreEqual(311, message.GetRepeatedFloat(1), 0.0);
+            Assert.AreEqual(312, message.GetRepeatedDouble(1), 0.0);
+            Assert.AreEqual(false, message.GetRepeatedBool(1));
+            Assert.AreEqual("315", message.GetRepeatedString(1));
+            Assert.AreEqual(ToBytes("316"), message.GetRepeatedBytes(1));
+
+            Assert.AreEqual(317, message.GetRepeatedGroup(1).A);
+            Assert.AreEqual(318, message.GetRepeatedNestedMessage(1).Bb);
+            Assert.AreEqual(319, message.GetRepeatedForeignMessage(1).C);
+            Assert.AreEqual(320, message.GetRepeatedImportMessage(1).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAZ, message.GetRepeatedNestedEnum(1));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.GetRepeatedForeignEnum(1));
+            Assert.AreEqual(ImportEnum.IMPORT_BAZ, message.GetRepeatedImportEnum(1));
+
+            Assert.AreEqual("324", message.GetRepeatedStringPiece(1));
+            Assert.AreEqual("325", message.GetRepeatedCord(1));
+
+            // -----------------------------------------------------------------
+
+            Assert.IsTrue(message.HasDefaultInt32);
+            Assert.IsTrue(message.HasDefaultInt64);
+            Assert.IsTrue(message.HasDefaultUint32);
+            Assert.IsTrue(message.HasDefaultUint64);
+            Assert.IsTrue(message.HasDefaultSint32);
+            Assert.IsTrue(message.HasDefaultSint64);
+            Assert.IsTrue(message.HasDefaultFixed32);
+            Assert.IsTrue(message.HasDefaultFixed64);
+            Assert.IsTrue(message.HasDefaultSfixed32);
+            Assert.IsTrue(message.HasDefaultSfixed64);
+            Assert.IsTrue(message.HasDefaultFloat);
+            Assert.IsTrue(message.HasDefaultDouble);
+            Assert.IsTrue(message.HasDefaultBool);
+            Assert.IsTrue(message.HasDefaultString);
+            Assert.IsTrue(message.HasDefaultBytes);
+
+            Assert.IsTrue(message.HasDefaultNestedEnum);
+            Assert.IsTrue(message.HasDefaultForeignEnum);
+            Assert.IsTrue(message.HasDefaultImportEnum);
+
+            Assert.IsTrue(message.HasDefaultStringPiece);
+            Assert.IsTrue(message.HasDefaultCord);
+
+            Assert.AreEqual(401, message.DefaultInt32);
+            Assert.AreEqual(402, message.DefaultInt64);
+            Assert.AreEqual(403, message.DefaultUint32);
+            Assert.AreEqual(404, message.DefaultUint64);
+            Assert.AreEqual(405, message.DefaultSint32);
+            Assert.AreEqual(406, message.DefaultSint64);
+            Assert.AreEqual(407, message.DefaultFixed32);
+            Assert.AreEqual(408, message.DefaultFixed64);
+            Assert.AreEqual(409, message.DefaultSfixed32);
+            Assert.AreEqual(410, message.DefaultSfixed64);
+            Assert.AreEqual(411, message.DefaultFloat);
+            Assert.AreEqual(412, message.DefaultDouble);
+            Assert.AreEqual(false, message.DefaultBool);
+            Assert.AreEqual("415", message.DefaultString);
+            Assert.AreEqual(ToBytes("416"), message.DefaultBytes);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.DefaultNestedEnum);
+            Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.DefaultForeignEnum);
+            Assert.AreEqual(ImportEnum.IMPORT_FOO, message.DefaultImportEnum);
+
+            Assert.AreEqual("424", message.DefaultStringPiece);
+            Assert.AreEqual("425", message.DefaultCord);
+        }
+
+        internal static void AssertClear(TestAllTypes message)
+        {
+            // HasBlah() should initially be false for all optional fields.
+            Assert.IsFalse(message.HasOptionalInt32);
+            Assert.IsFalse(message.HasOptionalInt64);
+            Assert.IsFalse(message.HasOptionalUint32);
+            Assert.IsFalse(message.HasOptionalUint64);
+            Assert.IsFalse(message.HasOptionalSint32);
+            Assert.IsFalse(message.HasOptionalSint64);
+            Assert.IsFalse(message.HasOptionalFixed32);
+            Assert.IsFalse(message.HasOptionalFixed64);
+            Assert.IsFalse(message.HasOptionalSfixed32);
+            Assert.IsFalse(message.HasOptionalSfixed64);
+            Assert.IsFalse(message.HasOptionalFloat);
+            Assert.IsFalse(message.HasOptionalDouble);
+            Assert.IsFalse(message.HasOptionalBool);
+            Assert.IsFalse(message.HasOptionalString);
+            Assert.IsFalse(message.HasOptionalBytes);
+
+            Assert.IsFalse(message.HasOptionalGroup);
+            Assert.IsFalse(message.HasOptionalNestedMessage);
+            Assert.IsFalse(message.HasOptionalForeignMessage);
+            Assert.IsFalse(message.HasOptionalImportMessage);
+
+            Assert.IsFalse(message.HasOptionalNestedEnum);
+            Assert.IsFalse(message.HasOptionalForeignEnum);
+            Assert.IsFalse(message.HasOptionalImportEnum);
+
+            Assert.IsFalse(message.HasOptionalStringPiece);
+            Assert.IsFalse(message.HasOptionalCord);
+
+            // Optional fields without defaults are set to zero or something like it.
+            Assert.AreEqual(0, message.OptionalInt32);
+            Assert.AreEqual(0, message.OptionalInt64);
+            Assert.AreEqual(0, message.OptionalUint32);
+            Assert.AreEqual(0, message.OptionalUint64);
+            Assert.AreEqual(0, message.OptionalSint32);
+            Assert.AreEqual(0, message.OptionalSint64);
+            Assert.AreEqual(0, message.OptionalFixed32);
+            Assert.AreEqual(0, message.OptionalFixed64);
+            Assert.AreEqual(0, message.OptionalSfixed32);
+            Assert.AreEqual(0, message.OptionalSfixed64);
+            Assert.AreEqual(0, message.OptionalFloat);
+            Assert.AreEqual(0, message.OptionalDouble);
+            Assert.AreEqual(false, message.OptionalBool);
+            Assert.AreEqual("", message.OptionalString);
+            Assert.AreEqual(ByteString.Empty, message.OptionalBytes);
+
+            // Embedded messages should also be clear.
+            Assert.IsFalse(message.OptionalGroup.HasA);
+            Assert.IsFalse(message.OptionalNestedMessage.HasBb);
+            Assert.IsFalse(message.OptionalForeignMessage.HasC);
+            Assert.IsFalse(message.OptionalImportMessage.HasD);
+
+            Assert.AreEqual(0, message.OptionalGroup.A);
+            Assert.AreEqual(0, message.OptionalNestedMessage.Bb);
+            Assert.AreEqual(0, message.OptionalForeignMessage.C);
+            Assert.AreEqual(0, message.OptionalImportMessage.D);
+
+            // Enums without defaults are set to the first value in the enum.
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.OptionalNestedEnum);
+            Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.OptionalForeignEnum);
+            Assert.AreEqual(ImportEnum.IMPORT_FOO, message.OptionalImportEnum);
+
+            Assert.AreEqual("", message.OptionalStringPiece);
+            Assert.AreEqual("", message.OptionalCord);
+
+            // Repeated fields are empty.
+            Assert.AreEqual(0, message.RepeatedInt32Count);
+            Assert.AreEqual(0, message.RepeatedInt64Count);
+            Assert.AreEqual(0, message.RepeatedUint32Count);
+            Assert.AreEqual(0, message.RepeatedUint64Count);
+            Assert.AreEqual(0, message.RepeatedSint32Count);
+            Assert.AreEqual(0, message.RepeatedSint64Count);
+            Assert.AreEqual(0, message.RepeatedFixed32Count);
+            Assert.AreEqual(0, message.RepeatedFixed64Count);
+            Assert.AreEqual(0, message.RepeatedSfixed32Count);
+            Assert.AreEqual(0, message.RepeatedSfixed64Count);
+            Assert.AreEqual(0, message.RepeatedFloatCount);
+            Assert.AreEqual(0, message.RepeatedDoubleCount);
+            Assert.AreEqual(0, message.RepeatedBoolCount);
+            Assert.AreEqual(0, message.RepeatedStringCount);
+            Assert.AreEqual(0, message.RepeatedBytesCount);
+
+            Assert.AreEqual(0, message.RepeatedGroupCount);
+            Assert.AreEqual(0, message.RepeatedNestedMessageCount);
+            Assert.AreEqual(0, message.RepeatedForeignMessageCount);
+            Assert.AreEqual(0, message.RepeatedImportMessageCount);
+            Assert.AreEqual(0, message.RepeatedNestedEnumCount);
+            Assert.AreEqual(0, message.RepeatedForeignEnumCount);
+            Assert.AreEqual(0, message.RepeatedImportEnumCount);
+
+            Assert.AreEqual(0, message.RepeatedStringPieceCount);
+            Assert.AreEqual(0, message.RepeatedCordCount);
+
+            // HasBlah() should also be false for all default fields.
+            Assert.IsFalse(message.HasDefaultInt32);
+            Assert.IsFalse(message.HasDefaultInt64);
+            Assert.IsFalse(message.HasDefaultUint32);
+            Assert.IsFalse(message.HasDefaultUint64);
+            Assert.IsFalse(message.HasDefaultSint32);
+            Assert.IsFalse(message.HasDefaultSint64);
+            Assert.IsFalse(message.HasDefaultFixed32);
+            Assert.IsFalse(message.HasDefaultFixed64);
+            Assert.IsFalse(message.HasDefaultSfixed32);
+            Assert.IsFalse(message.HasDefaultSfixed64);
+            Assert.IsFalse(message.HasDefaultFloat);
+            Assert.IsFalse(message.HasDefaultDouble);
+            Assert.IsFalse(message.HasDefaultBool);
+            Assert.IsFalse(message.HasDefaultString);
+            Assert.IsFalse(message.HasDefaultBytes);
+
+            Assert.IsFalse(message.HasDefaultNestedEnum);
+            Assert.IsFalse(message.HasDefaultForeignEnum);
+            Assert.IsFalse(message.HasDefaultImportEnum);
+
+            Assert.IsFalse(message.HasDefaultStringPiece);
+            Assert.IsFalse(message.HasDefaultCord);
+
+            // Fields with defaults have their default values (duh).
+            Assert.AreEqual(41, message.DefaultInt32);
+            Assert.AreEqual(42, message.DefaultInt64);
+            Assert.AreEqual(43, message.DefaultUint32);
+            Assert.AreEqual(44, message.DefaultUint64);
+            Assert.AreEqual(-45, message.DefaultSint32);
+            Assert.AreEqual(46, message.DefaultSint64);
+            Assert.AreEqual(47, message.DefaultFixed32);
+            Assert.AreEqual(48, message.DefaultFixed64);
+            Assert.AreEqual(49, message.DefaultSfixed32);
+            Assert.AreEqual(-50, message.DefaultSfixed64);
+            Assert.AreEqual(51.5, message.DefaultFloat, 0.0);
+            Assert.AreEqual(52e3, message.DefaultDouble, 0.0);
+            Assert.AreEqual(true, message.DefaultBool);
+            Assert.AreEqual("hello", message.DefaultString);
+            Assert.AreEqual(ToBytes("world"), message.DefaultBytes);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.DefaultNestedEnum);
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.DefaultForeignEnum);
+            Assert.AreEqual(ImportEnum.IMPORT_BAR, message.DefaultImportEnum);
+
+            Assert.AreEqual("abc", message.DefaultStringPiece);
+            Assert.AreEqual("123", message.DefaultCord);
+        }
+
+        /// <summary>
+        /// Get a TestAllExtensions with all fields set as they would be by
+        /// SetAllExtensions(TestAllExtensions.Builder).
+        /// </summary>
+        internal static TestAllExtensions GetAllExtensionsSet()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            SetAllExtensions(builder);
+            return builder.Build();
+        }
+
+        public static TestPackedTypes GetPackedSet()
+        {
+            TestPackedTypes.Builder builder = TestPackedTypes.CreateBuilder();
+            SetPackedFields(builder);
+            return builder.Build();
+        }
+
+        public static TestPackedExtensions GetPackedExtensionsSet()
+        {
+            TestPackedExtensions.Builder builder = TestPackedExtensions.CreateBuilder();
+            SetPackedExtensions(builder);
+            return builder.Build();
+        }
+
+        /// <summary>
+        /// Sets every field of the specified builder to the values expected by
+        /// AssertAllExtensionsSet.
+        /// </summary>
+        internal static void SetAllExtensions(TestAllExtensions.Builder message)
+        {
+            message.SetExtension(UnitTestProtoFile.OptionalInt32Extension, 101);
+            message.SetExtension(UnitTestProtoFile.OptionalInt64Extension, 102L);
+            message.SetExtension(UnitTestProtoFile.OptionalUint32Extension, 103U);
+            message.SetExtension(UnitTestProtoFile.OptionalUint64Extension, 104UL);
+            message.SetExtension(UnitTestProtoFile.OptionalSint32Extension, 105);
+            message.SetExtension(UnitTestProtoFile.OptionalSint64Extension, 106L);
+            message.SetExtension(UnitTestProtoFile.OptionalFixed32Extension, 107U);
+            message.SetExtension(UnitTestProtoFile.OptionalFixed64Extension, 108UL);
+            message.SetExtension(UnitTestProtoFile.OptionalSfixed32Extension, 109);
+            message.SetExtension(UnitTestProtoFile.OptionalSfixed64Extension, 110L);
+            message.SetExtension(UnitTestProtoFile.OptionalFloatExtension, 111F);
+            message.SetExtension(UnitTestProtoFile.OptionalDoubleExtension, 112D);
+            message.SetExtension(UnitTestProtoFile.OptionalBoolExtension, true);
+            message.SetExtension(UnitTestProtoFile.OptionalStringExtension, "115");
+            message.SetExtension(UnitTestProtoFile.OptionalBytesExtension, ToBytes("116"));
+
+            message.SetExtension(UnitTestProtoFile.OptionalGroupExtension,
+                                 OptionalGroup_extension.CreateBuilder().SetA(117).Build());
+            message.SetExtension(UnitTestProtoFile.OptionalNestedMessageExtension,
+                                 TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(118).Build());
+            message.SetExtension(UnitTestProtoFile.OptionalForeignMessageExtension,
+                                 ForeignMessage.CreateBuilder().SetC(119).Build());
+            message.SetExtension(UnitTestProtoFile.OptionalImportMessageExtension,
+                                 ImportMessage.CreateBuilder().SetD(120).Build());
+
+            message.SetExtension(UnitTestProtoFile.OptionalNestedEnumExtension, TestAllTypes.Types.NestedEnum.BAZ);
+            message.SetExtension(UnitTestProtoFile.OptionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+            message.SetExtension(UnitTestProtoFile.OptionalImportEnumExtension, ImportEnum.IMPORT_BAZ);
+
+            message.SetExtension(UnitTestProtoFile.OptionalStringPieceExtension, "124");
+            message.SetExtension(UnitTestProtoFile.OptionalCordExtension, "125");
+
+            // -----------------------------------------------------------------
+
+            message.AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 201);
+            message.AddExtension(UnitTestProtoFile.RepeatedInt64Extension, 202L);
+            message.AddExtension(UnitTestProtoFile.RepeatedUint32Extension, 203U);
+            message.AddExtension(UnitTestProtoFile.RepeatedUint64Extension, 204UL);
+            message.AddExtension(UnitTestProtoFile.RepeatedSint32Extension, 205);
+            message.AddExtension(UnitTestProtoFile.RepeatedSint64Extension, 206L);
+            message.AddExtension(UnitTestProtoFile.RepeatedFixed32Extension, 207U);
+            message.AddExtension(UnitTestProtoFile.RepeatedFixed64Extension, 208UL);
+            message.AddExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 209);
+            message.AddExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 210L);
+            message.AddExtension(UnitTestProtoFile.RepeatedFloatExtension, 211F);
+            message.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 212D);
+            message.AddExtension(UnitTestProtoFile.RepeatedBoolExtension, true);
+            message.AddExtension(UnitTestProtoFile.RepeatedStringExtension, "215");
+            message.AddExtension(UnitTestProtoFile.RepeatedBytesExtension, ToBytes("216"));
+
+            message.AddExtension(UnitTestProtoFile.RepeatedGroupExtension,
+                                 RepeatedGroup_extension.CreateBuilder().SetA(217).Build());
+            message.AddExtension(UnitTestProtoFile.RepeatedNestedMessageExtension,
+                                 TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(218).Build());
+            message.AddExtension(UnitTestProtoFile.RepeatedForeignMessageExtension,
+                                 ForeignMessage.CreateBuilder().SetC(219).Build());
+            message.AddExtension(UnitTestProtoFile.RepeatedImportMessageExtension,
+                                 ImportMessage.CreateBuilder().SetD(220).Build());
+
+            message.AddExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, TestAllTypes.Types.NestedEnum.BAR);
+            message.AddExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAR);
+            message.AddExtension(UnitTestProtoFile.RepeatedImportEnumExtension, ImportEnum.IMPORT_BAR);
+
+            message.AddExtension(UnitTestProtoFile.RepeatedStringPieceExtension, "224");
+            message.AddExtension(UnitTestProtoFile.RepeatedCordExtension, "225");
+
+            // Add a second one of each field.
+            message.AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 301);
+            message.AddExtension(UnitTestProtoFile.RepeatedInt64Extension, 302L);
+            message.AddExtension(UnitTestProtoFile.RepeatedUint32Extension, 303U);
+            message.AddExtension(UnitTestProtoFile.RepeatedUint64Extension, 304UL);
+            message.AddExtension(UnitTestProtoFile.RepeatedSint32Extension, 305);
+            message.AddExtension(UnitTestProtoFile.RepeatedSint64Extension, 306L);
+            message.AddExtension(UnitTestProtoFile.RepeatedFixed32Extension, 307U);
+            message.AddExtension(UnitTestProtoFile.RepeatedFixed64Extension, 308UL);
+            message.AddExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 309);
+            message.AddExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 310L);
+            message.AddExtension(UnitTestProtoFile.RepeatedFloatExtension, 311F);
+            message.AddExtension(UnitTestProtoFile.RepeatedDoubleExtension, 312D);
+            message.AddExtension(UnitTestProtoFile.RepeatedBoolExtension, false);
+            message.AddExtension(UnitTestProtoFile.RepeatedStringExtension, "315");
+            message.AddExtension(UnitTestProtoFile.RepeatedBytesExtension, ToBytes("316"));
+
+            message.AddExtension(UnitTestProtoFile.RepeatedGroupExtension,
+                                 RepeatedGroup_extension.CreateBuilder().SetA(317).Build());
+            message.AddExtension(UnitTestProtoFile.RepeatedNestedMessageExtension,
+                                 TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(318).Build());
+            message.AddExtension(UnitTestProtoFile.RepeatedForeignMessageExtension,
+                                 ForeignMessage.CreateBuilder().SetC(319).Build());
+            message.AddExtension(UnitTestProtoFile.RepeatedImportMessageExtension,
+                                 ImportMessage.CreateBuilder().SetD(320).Build());
+
+            message.AddExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, TestAllTypes.Types.NestedEnum.BAZ);
+            message.AddExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+            message.AddExtension(UnitTestProtoFile.RepeatedImportEnumExtension, ImportEnum.IMPORT_BAZ);
+
+            message.AddExtension(UnitTestProtoFile.RepeatedStringPieceExtension, "324");
+            message.AddExtension(UnitTestProtoFile.RepeatedCordExtension, "325");
+
+            // -----------------------------------------------------------------
+
+            message.SetExtension(UnitTestProtoFile.DefaultInt32Extension, 401);
+            message.SetExtension(UnitTestProtoFile.DefaultInt64Extension, 402L);
+            message.SetExtension(UnitTestProtoFile.DefaultUint32Extension, 403U);
+            message.SetExtension(UnitTestProtoFile.DefaultUint64Extension, 404UL);
+            message.SetExtension(UnitTestProtoFile.DefaultSint32Extension, 405);
+            message.SetExtension(UnitTestProtoFile.DefaultSint64Extension, 406L);
+            message.SetExtension(UnitTestProtoFile.DefaultFixed32Extension, 407U);
+            message.SetExtension(UnitTestProtoFile.DefaultFixed64Extension, 408UL);
+            message.SetExtension(UnitTestProtoFile.DefaultSfixed32Extension, 409);
+            message.SetExtension(UnitTestProtoFile.DefaultSfixed64Extension, 410L);
+            message.SetExtension(UnitTestProtoFile.DefaultFloatExtension, 411F);
+            message.SetExtension(UnitTestProtoFile.DefaultDoubleExtension, 412D);
+            message.SetExtension(UnitTestProtoFile.DefaultBoolExtension, false);
+            message.SetExtension(UnitTestProtoFile.DefaultStringExtension, "415");
+            message.SetExtension(UnitTestProtoFile.DefaultBytesExtension, ToBytes("416"));
+
+            message.SetExtension(UnitTestProtoFile.DefaultNestedEnumExtension, TestAllTypes.Types.NestedEnum.FOO);
+            message.SetExtension(UnitTestProtoFile.DefaultForeignEnumExtension, ForeignEnum.FOREIGN_FOO);
+            message.SetExtension(UnitTestProtoFile.DefaultImportEnumExtension, ImportEnum.IMPORT_FOO);
+
+            message.SetExtension(UnitTestProtoFile.DefaultStringPieceExtension, "424");
+            message.SetExtension(UnitTestProtoFile.DefaultCordExtension, "425");
+        }
+
+        internal static void ModifyRepeatedFields(TestAllTypes.Builder message)
+        {
+            message.SetRepeatedInt32(1, 501);
+            message.SetRepeatedInt64(1, 502);
+            message.SetRepeatedUint32(1, 503);
+            message.SetRepeatedUint64(1, 504);
+            message.SetRepeatedSint32(1, 505);
+            message.SetRepeatedSint64(1, 506);
+            message.SetRepeatedFixed32(1, 507);
+            message.SetRepeatedFixed64(1, 508);
+            message.SetRepeatedSfixed32(1, 509);
+            message.SetRepeatedSfixed64(1, 510);
+            message.SetRepeatedFloat(1, 511);
+            message.SetRepeatedDouble(1, 512);
+            message.SetRepeatedBool(1, true);
+            message.SetRepeatedString(1, "515");
+            message.SetRepeatedBytes(1, ToBytes("516"));
+
+            message.SetRepeatedGroup(1, TestAllTypes.Types.RepeatedGroup.CreateBuilder().SetA(517).Build());
+            message.SetRepeatedNestedMessage(1, TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(518).Build());
+            message.SetRepeatedForeignMessage(1, ForeignMessage.CreateBuilder().SetC(519).Build());
+            message.SetRepeatedImportMessage(1, ImportMessage.CreateBuilder().SetD(520).Build());
+
+            message.SetRepeatedNestedEnum(1, TestAllTypes.Types.NestedEnum.FOO);
+            message.SetRepeatedForeignEnum(1, ForeignEnum.FOREIGN_FOO);
+            message.SetRepeatedImportEnum(1, ImportEnum.IMPORT_FOO);
+
+            message.SetRepeatedStringPiece(1, "524");
+            message.SetRepeatedCord(1, "525");
+        }
+
+        internal static void AssertRepeatedFieldsModified(TestAllTypes message)
+        {
+            // ModifyRepeatedFields only sets the second repeated element of each
+            // field.  In addition to verifying this, we also verify that the first
+            // element and size were *not* modified.
+            Assert.AreEqual(2, message.RepeatedInt32Count);
+            Assert.AreEqual(2, message.RepeatedInt64Count);
+            Assert.AreEqual(2, message.RepeatedUint32Count);
+            Assert.AreEqual(2, message.RepeatedUint64Count);
+            Assert.AreEqual(2, message.RepeatedSint32Count);
+            Assert.AreEqual(2, message.RepeatedSint64Count);
+            Assert.AreEqual(2, message.RepeatedFixed32Count);
+            Assert.AreEqual(2, message.RepeatedFixed64Count);
+            Assert.AreEqual(2, message.RepeatedSfixed32Count);
+            Assert.AreEqual(2, message.RepeatedSfixed64Count);
+            Assert.AreEqual(2, message.RepeatedFloatCount);
+            Assert.AreEqual(2, message.RepeatedDoubleCount);
+            Assert.AreEqual(2, message.RepeatedBoolCount);
+            Assert.AreEqual(2, message.RepeatedStringCount);
+            Assert.AreEqual(2, message.RepeatedBytesCount);
+
+            Assert.AreEqual(2, message.RepeatedGroupCount);
+            Assert.AreEqual(2, message.RepeatedNestedMessageCount);
+            Assert.AreEqual(2, message.RepeatedForeignMessageCount);
+            Assert.AreEqual(2, message.RepeatedImportMessageCount);
+            Assert.AreEqual(2, message.RepeatedNestedEnumCount);
+            Assert.AreEqual(2, message.RepeatedForeignEnumCount);
+            Assert.AreEqual(2, message.RepeatedImportEnumCount);
+
+            Assert.AreEqual(2, message.RepeatedStringPieceCount);
+            Assert.AreEqual(2, message.RepeatedCordCount);
+
+            Assert.AreEqual(201, message.GetRepeatedInt32(0));
+            Assert.AreEqual(202L, message.GetRepeatedInt64(0));
+            Assert.AreEqual(203U, message.GetRepeatedUint32(0));
+            Assert.AreEqual(204UL, message.GetRepeatedUint64(0));
+            Assert.AreEqual(205, message.GetRepeatedSint32(0));
+            Assert.AreEqual(206L, message.GetRepeatedSint64(0));
+            Assert.AreEqual(207U, message.GetRepeatedFixed32(0));
+            Assert.AreEqual(208UL, message.GetRepeatedFixed64(0));
+            Assert.AreEqual(209, message.GetRepeatedSfixed32(0));
+            Assert.AreEqual(210L, message.GetRepeatedSfixed64(0));
+            Assert.AreEqual(211F, message.GetRepeatedFloat(0));
+            Assert.AreEqual(212D, message.GetRepeatedDouble(0));
+            Assert.AreEqual(true, message.GetRepeatedBool(0));
+            Assert.AreEqual("215", message.GetRepeatedString(0));
+            Assert.AreEqual(ToBytes("216"), message.GetRepeatedBytes(0));
+
+            Assert.AreEqual(217, message.GetRepeatedGroup(0).A);
+            Assert.AreEqual(218, message.GetRepeatedNestedMessage(0).Bb);
+            Assert.AreEqual(219, message.GetRepeatedForeignMessage(0).C);
+            Assert.AreEqual(220, message.GetRepeatedImportMessage(0).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, message.GetRepeatedNestedEnum(0));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetRepeatedForeignEnum(0));
+            Assert.AreEqual(ImportEnum.IMPORT_BAR, message.GetRepeatedImportEnum(0));
+
+            Assert.AreEqual("224", message.GetRepeatedStringPiece(0));
+            Assert.AreEqual("225", message.GetRepeatedCord(0));
+
+            // Actually verify the second (modified) elements now.
+            Assert.AreEqual(501, message.GetRepeatedInt32(1));
+            Assert.AreEqual(502L, message.GetRepeatedInt64(1));
+            Assert.AreEqual(503U, message.GetRepeatedUint32(1));
+            Assert.AreEqual(504UL, message.GetRepeatedUint64(1));
+            Assert.AreEqual(505, message.GetRepeatedSint32(1));
+            Assert.AreEqual(506L, message.GetRepeatedSint64(1));
+            Assert.AreEqual(507U, message.GetRepeatedFixed32(1));
+            Assert.AreEqual(508UL, message.GetRepeatedFixed64(1));
+            Assert.AreEqual(509, message.GetRepeatedSfixed32(1));
+            Assert.AreEqual(510L, message.GetRepeatedSfixed64(1));
+            Assert.AreEqual(511F, message.GetRepeatedFloat(1));
+            Assert.AreEqual(512D, message.GetRepeatedDouble(1));
+            Assert.AreEqual(true, message.GetRepeatedBool(1));
+            Assert.AreEqual("515", message.GetRepeatedString(1));
+            Assert.AreEqual(ToBytes("516"), message.GetRepeatedBytes(1));
+
+            Assert.AreEqual(517, message.GetRepeatedGroup(1).A);
+            Assert.AreEqual(518, message.GetRepeatedNestedMessage(1).Bb);
+            Assert.AreEqual(519, message.GetRepeatedForeignMessage(1).C);
+            Assert.AreEqual(520, message.GetRepeatedImportMessage(1).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO, message.GetRepeatedNestedEnum(1));
+            Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.GetRepeatedForeignEnum(1));
+            Assert.AreEqual(ImportEnum.IMPORT_FOO, message.GetRepeatedImportEnum(1));
+
+            Assert.AreEqual("524", message.GetRepeatedStringPiece(1));
+            Assert.AreEqual("525", message.GetRepeatedCord(1));
+        }
+
+        /// <summary>
+        /// Helper to assert that sequences are equal.
+        /// </summary>
+        internal static void AssertEqual<T>(IEnumerable<T> first, IEnumerable<T> second)
+        {
+            using (IEnumerator<T> firstEnumerator = first.GetEnumerator())
+            {
+                foreach (T secondElement in second)
+                {
+                    Assert.IsTrue(firstEnumerator.MoveNext(), "First enumerator ran out of elements too early.");
+                    Assert.AreEqual(firstEnumerator.Current, secondElement);
+                }
+                Assert.IsFalse(firstEnumerator.MoveNext(), "Second enumerator ran out of elements too early.");
+            }
+        }
+
+        internal static void AssertEqualBytes(byte[] expected, byte[] actual)
+        {
+            Assert.AreEqual(ByteString.CopyFrom(expected), ByteString.CopyFrom(actual));
+        }
+
+        internal static void AssertAllExtensionsSet(TestAllExtensions message)
+        {
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalInt64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalUint32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalUint64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalSint32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalSint64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalFixed32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalFixed64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalSfixed32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalSfixed64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalFloatExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalDoubleExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalBoolExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalStringExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalBytesExtension));
+
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalGroupExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalNestedMessageExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalForeignMessageExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalImportMessageExtension));
+
+            Assert.IsTrue(message.GetExtension(UnitTestProtoFile.OptionalGroupExtension).HasA);
+            Assert.IsTrue(message.GetExtension(UnitTestProtoFile.OptionalNestedMessageExtension).HasBb);
+            Assert.IsTrue(message.GetExtension(UnitTestProtoFile.OptionalForeignMessageExtension).HasC);
+            Assert.IsTrue(message.GetExtension(UnitTestProtoFile.OptionalImportMessageExtension).HasD);
+
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalImportEnumExtension));
+
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalStringPieceExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.OptionalCordExtension));
+
+            Assert.AreEqual(101, message.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.AreEqual(102L, message.GetExtension(UnitTestProtoFile.OptionalInt64Extension));
+            Assert.AreEqual(103U, message.GetExtension(UnitTestProtoFile.OptionalUint32Extension));
+            Assert.AreEqual(104UL, message.GetExtension(UnitTestProtoFile.OptionalUint64Extension));
+            Assert.AreEqual(105, message.GetExtension(UnitTestProtoFile.OptionalSint32Extension));
+            Assert.AreEqual(106L, message.GetExtension(UnitTestProtoFile.OptionalSint64Extension));
+            Assert.AreEqual(107U, message.GetExtension(UnitTestProtoFile.OptionalFixed32Extension));
+            Assert.AreEqual(108UL, message.GetExtension(UnitTestProtoFile.OptionalFixed64Extension));
+            Assert.AreEqual(109, message.GetExtension(UnitTestProtoFile.OptionalSfixed32Extension));
+            Assert.AreEqual(110L, message.GetExtension(UnitTestProtoFile.OptionalSfixed64Extension));
+            Assert.AreEqual(111F, message.GetExtension(UnitTestProtoFile.OptionalFloatExtension));
+            Assert.AreEqual(112D, message.GetExtension(UnitTestProtoFile.OptionalDoubleExtension));
+            Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.OptionalBoolExtension));
+            Assert.AreEqual("115", message.GetExtension(UnitTestProtoFile.OptionalStringExtension));
+            Assert.AreEqual(ToBytes("116"), message.GetExtension(UnitTestProtoFile.OptionalBytesExtension));
+
+            Assert.AreEqual(117, message.GetExtension(UnitTestProtoFile.OptionalGroupExtension).A);
+            Assert.AreEqual(118, message.GetExtension(UnitTestProtoFile.OptionalNestedMessageExtension).Bb);
+            Assert.AreEqual(119, message.GetExtension(UnitTestProtoFile.OptionalForeignMessageExtension).C);
+            Assert.AreEqual(120, message.GetExtension(UnitTestProtoFile.OptionalImportMessageExtension).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAZ,
+                            message.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ,
+                            message.GetExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
+            Assert.AreEqual(ImportEnum.IMPORT_BAZ, message.GetExtension(UnitTestProtoFile.OptionalImportEnumExtension));
+
+            Assert.AreEqual("124", message.GetExtension(UnitTestProtoFile.OptionalStringPieceExtension));
+            Assert.AreEqual("125", message.GetExtension(UnitTestProtoFile.OptionalCordExtension));
+
+            // -----------------------------------------------------------------
+
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFloatExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedBoolExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedBytesExtension));
+
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedGroupExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedMessageExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignMessageExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportMessageExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedEnumExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignEnumExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportEnumExtension));
+
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringPieceExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedCordExtension));
+
+            Assert.AreEqual(201, message.GetExtension(UnitTestProtoFile.RepeatedInt32Extension, 0));
+            Assert.AreEqual(202L, message.GetExtension(UnitTestProtoFile.RepeatedInt64Extension, 0));
+            Assert.AreEqual(203U, message.GetExtension(UnitTestProtoFile.RepeatedUint32Extension, 0));
+            Assert.AreEqual(204UL, message.GetExtension(UnitTestProtoFile.RepeatedUint64Extension, 0));
+            Assert.AreEqual(205, message.GetExtension(UnitTestProtoFile.RepeatedSint32Extension, 0));
+            Assert.AreEqual(206L, message.GetExtension(UnitTestProtoFile.RepeatedSint64Extension, 0));
+            Assert.AreEqual(207U, message.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 0));
+            Assert.AreEqual(208UL, message.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 0));
+            Assert.AreEqual(209, message.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 0));
+            Assert.AreEqual(210L, message.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 0));
+            Assert.AreEqual(211F, message.GetExtension(UnitTestProtoFile.RepeatedFloatExtension, 0));
+            Assert.AreEqual(212D, message.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 0));
+            Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.RepeatedBoolExtension, 0));
+            Assert.AreEqual("215", message.GetExtension(UnitTestProtoFile.RepeatedStringExtension, 0));
+            Assert.AreEqual(ToBytes("216"), message.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 0));
+
+            Assert.AreEqual(217, message.GetExtension(UnitTestProtoFile.RepeatedGroupExtension, 0).A);
+            Assert.AreEqual(218, message.GetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, 0).Bb);
+            Assert.AreEqual(219, message.GetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 0).C);
+            Assert.AreEqual(220, message.GetExtension(UnitTestProtoFile.RepeatedImportMessageExtension, 0).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
+                            message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 0));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAR,
+                            message.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 0));
+            Assert.AreEqual(ImportEnum.IMPORT_BAR,
+                            message.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 0));
+
+            Assert.AreEqual("224", message.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 0));
+            Assert.AreEqual("225", message.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 0));
+
+            Assert.AreEqual(301, message.GetExtension(UnitTestProtoFile.RepeatedInt32Extension, 1));
+            Assert.AreEqual(302L, message.GetExtension(UnitTestProtoFile.RepeatedInt64Extension, 1));
+            Assert.AreEqual(303U, message.GetExtension(UnitTestProtoFile.RepeatedUint32Extension, 1));
+            Assert.AreEqual(304UL, message.GetExtension(UnitTestProtoFile.RepeatedUint64Extension, 1));
+            Assert.AreEqual(305, message.GetExtension(UnitTestProtoFile.RepeatedSint32Extension, 1));
+            Assert.AreEqual(306L, message.GetExtension(UnitTestProtoFile.RepeatedSint64Extension, 1));
+            Assert.AreEqual(307U, message.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 1));
+            Assert.AreEqual(308UL, message.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 1));
+            Assert.AreEqual(309, message.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 1));
+            Assert.AreEqual(310L, message.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 1));
+            Assert.AreEqual(311F, message.GetExtension(UnitTestProtoFile.RepeatedFloatExtension, 1));
+            Assert.AreEqual(312D, message.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1));
+            Assert.AreEqual(false, message.GetExtension(UnitTestProtoFile.RepeatedBoolExtension, 1));
+            Assert.AreEqual("315", message.GetExtension(UnitTestProtoFile.RepeatedStringExtension, 1));
+            Assert.AreEqual(ToBytes("316"), message.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 1));
+
+            Assert.AreEqual(317, message.GetExtension(UnitTestProtoFile.RepeatedGroupExtension, 1).A);
+            Assert.AreEqual(318, message.GetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, 1).Bb);
+            Assert.AreEqual(319, message.GetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 1).C);
+            Assert.AreEqual(320, message.GetExtension(UnitTestProtoFile.RepeatedImportMessageExtension, 1).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAZ,
+                            message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 1));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ,
+                            message.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 1));
+            Assert.AreEqual(ImportEnum.IMPORT_BAZ,
+                            message.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 1));
+
+            Assert.AreEqual("324", message.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 1));
+            Assert.AreEqual("325", message.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 1));
+
+            // -----------------------------------------------------------------
+
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultInt32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultInt64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultUint32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultUint64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultSint32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultSint64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultFixed32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultFixed64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultSfixed32Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultSfixed64Extension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultFloatExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultDoubleExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultBoolExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultStringExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultBytesExtension));
+
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultNestedEnumExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultImportEnumExtension));
+
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultStringPieceExtension));
+            Assert.IsTrue(message.HasExtension(UnitTestProtoFile.DefaultCordExtension));
+
+            Assert.AreEqual(401, message.GetExtension(UnitTestProtoFile.DefaultInt32Extension));
+            Assert.AreEqual(402L, message.GetExtension(UnitTestProtoFile.DefaultInt64Extension));
+            Assert.AreEqual(403U, message.GetExtension(UnitTestProtoFile.DefaultUint32Extension));
+            Assert.AreEqual(404UL, message.GetExtension(UnitTestProtoFile.DefaultUint64Extension));
+            Assert.AreEqual(405, message.GetExtension(UnitTestProtoFile.DefaultSint32Extension));
+            Assert.AreEqual(406L, message.GetExtension(UnitTestProtoFile.DefaultSint64Extension));
+            Assert.AreEqual(407U, message.GetExtension(UnitTestProtoFile.DefaultFixed32Extension));
+            Assert.AreEqual(408UL, message.GetExtension(UnitTestProtoFile.DefaultFixed64Extension));
+            Assert.AreEqual(409, message.GetExtension(UnitTestProtoFile.DefaultSfixed32Extension));
+            Assert.AreEqual(410L, message.GetExtension(UnitTestProtoFile.DefaultSfixed64Extension));
+            Assert.AreEqual(411F, message.GetExtension(UnitTestProtoFile.DefaultFloatExtension));
+            Assert.AreEqual(412D, message.GetExtension(UnitTestProtoFile.DefaultDoubleExtension));
+            Assert.AreEqual(false, message.GetExtension(UnitTestProtoFile.DefaultBoolExtension));
+            Assert.AreEqual("415", message.GetExtension(UnitTestProtoFile.DefaultStringExtension));
+            Assert.AreEqual(ToBytes("416"), message.GetExtension(UnitTestProtoFile.DefaultBytesExtension));
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO,
+                            message.GetExtension(UnitTestProtoFile.DefaultNestedEnumExtension));
+            Assert.AreEqual(ForeignEnum.FOREIGN_FOO, message.GetExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
+            Assert.AreEqual(ImportEnum.IMPORT_FOO, message.GetExtension(UnitTestProtoFile.DefaultImportEnumExtension));
+
+            Assert.AreEqual("424", message.GetExtension(UnitTestProtoFile.DefaultStringPieceExtension));
+            Assert.AreEqual("425", message.GetExtension(UnitTestProtoFile.DefaultCordExtension));
+        }
+
+        /// <summary>
+        /// Modifies the repeated extensions of the given message to contain the values
+        /// expected by AssertRepeatedExtensionsModified.
+        /// </summary>
+        internal static void ModifyRepeatedExtensions(TestAllExtensions.Builder message)
+        {
+            message.SetExtension(UnitTestProtoFile.RepeatedInt32Extension, 1, 501);
+            message.SetExtension(UnitTestProtoFile.RepeatedInt64Extension, 1, 502L);
+            message.SetExtension(UnitTestProtoFile.RepeatedUint32Extension, 1, 503U);
+            message.SetExtension(UnitTestProtoFile.RepeatedUint64Extension, 1, 504UL);
+            message.SetExtension(UnitTestProtoFile.RepeatedSint32Extension, 1, 505);
+            message.SetExtension(UnitTestProtoFile.RepeatedSint64Extension, 1, 506L);
+            message.SetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 1, 507U);
+            message.SetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 1, 508UL);
+            message.SetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 1, 509);
+            message.SetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 1, 510L);
+            message.SetExtension(UnitTestProtoFile.RepeatedFloatExtension, 1, 511F);
+            message.SetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1, 512D);
+            message.SetExtension(UnitTestProtoFile.RepeatedBoolExtension, 1, true);
+            message.SetExtension(UnitTestProtoFile.RepeatedStringExtension, 1, "515");
+            message.SetExtension(UnitTestProtoFile.RepeatedBytesExtension, 1, ToBytes("516"));
+
+            message.SetExtension(UnitTestProtoFile.RepeatedGroupExtension, 1,
+                                 RepeatedGroup_extension.CreateBuilder().SetA(517).Build());
+            message.SetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, 1,
+                                 TestAllTypes.Types.NestedMessage.CreateBuilder().SetBb(518).Build());
+            message.SetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 1,
+                                 ForeignMessage.CreateBuilder().SetC(519).Build());
+            message.SetExtension(UnitTestProtoFile.RepeatedImportMessageExtension, 1,
+                                 ImportMessage.CreateBuilder().SetD(520).Build());
+
+            message.SetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 1, TestAllTypes.Types.NestedEnum.FOO);
+            message.SetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 1, ForeignEnum.FOREIGN_FOO);
+            message.SetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 1, ImportEnum.IMPORT_FOO);
+
+            message.SetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 1, "524");
+            message.SetExtension(UnitTestProtoFile.RepeatedCordExtension, 1, "525");
+        }
+
+        /// <summary>
+        /// Asserts that all repeated extensions are set to the values assigned by
+        /// SetAllExtensions follwed by ModifyRepeatedExtensions.
+        /// </summary>
+        internal static void AssertRepeatedExtensionsModified(TestAllExtensions message)
+        {
+            // ModifyRepeatedFields only sets the second repeated element of each
+            // field.  In addition to verifying this, we also verify that the first
+            // element and size were *not* modified.
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedFloatExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedBoolExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedBytesExtension));
+
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedGroupExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedMessageExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignMessageExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportMessageExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedEnumExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignEnumExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportEnumExtension));
+
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringPieceExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.RepeatedCordExtension));
+
+            Assert.AreEqual(201, message.GetExtension(UnitTestProtoFile.RepeatedInt32Extension, 0));
+            Assert.AreEqual(202L, message.GetExtension(UnitTestProtoFile.RepeatedInt64Extension, 0));
+            Assert.AreEqual(203U, message.GetExtension(UnitTestProtoFile.RepeatedUint32Extension, 0));
+            Assert.AreEqual(204UL, message.GetExtension(UnitTestProtoFile.RepeatedUint64Extension, 0));
+            Assert.AreEqual(205, message.GetExtension(UnitTestProtoFile.RepeatedSint32Extension, 0));
+            Assert.AreEqual(206L, message.GetExtension(UnitTestProtoFile.RepeatedSint64Extension, 0));
+            Assert.AreEqual(207U, message.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 0));
+            Assert.AreEqual(208UL, message.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 0));
+            Assert.AreEqual(209, message.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 0));
+            Assert.AreEqual(210L, message.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 0));
+            Assert.AreEqual(211F, message.GetExtension(UnitTestProtoFile.RepeatedFloatExtension, 0));
+            Assert.AreEqual(212D, message.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 0));
+            Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.RepeatedBoolExtension, 0));
+            Assert.AreEqual("215", message.GetExtension(UnitTestProtoFile.RepeatedStringExtension, 0));
+            Assert.AreEqual(ToBytes("216"), message.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 0));
+
+            Assert.AreEqual(217, message.GetExtension(UnitTestProtoFile.RepeatedGroupExtension, 0).A);
+            Assert.AreEqual(218, message.GetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, 0).Bb);
+            Assert.AreEqual(219, message.GetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 0).C);
+            Assert.AreEqual(220, message.GetExtension(UnitTestProtoFile.RepeatedImportMessageExtension, 0).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
+                            message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 0));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAR,
+                            message.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 0));
+            Assert.AreEqual(ImportEnum.IMPORT_BAR,
+                            message.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 0));
+
+            Assert.AreEqual("224", message.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 0));
+            Assert.AreEqual("225", message.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 0));
+
+            // Actually verify the second (modified) elements now.
+            Assert.AreEqual(501, message.GetExtension(UnitTestProtoFile.RepeatedInt32Extension, 1));
+            Assert.AreEqual(502L, message.GetExtension(UnitTestProtoFile.RepeatedInt64Extension, 1));
+            Assert.AreEqual(503U, message.GetExtension(UnitTestProtoFile.RepeatedUint32Extension, 1));
+            Assert.AreEqual(504UL, message.GetExtension(UnitTestProtoFile.RepeatedUint64Extension, 1));
+            Assert.AreEqual(505, message.GetExtension(UnitTestProtoFile.RepeatedSint32Extension, 1));
+            Assert.AreEqual(506L, message.GetExtension(UnitTestProtoFile.RepeatedSint64Extension, 1));
+            Assert.AreEqual(507U, message.GetExtension(UnitTestProtoFile.RepeatedFixed32Extension, 1));
+            Assert.AreEqual(508UL, message.GetExtension(UnitTestProtoFile.RepeatedFixed64Extension, 1));
+            Assert.AreEqual(509, message.GetExtension(UnitTestProtoFile.RepeatedSfixed32Extension, 1));
+            Assert.AreEqual(510L, message.GetExtension(UnitTestProtoFile.RepeatedSfixed64Extension, 1));
+            Assert.AreEqual(511F, message.GetExtension(UnitTestProtoFile.RepeatedFloatExtension, 1));
+            Assert.AreEqual(512D, message.GetExtension(UnitTestProtoFile.RepeatedDoubleExtension, 1));
+            Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.RepeatedBoolExtension, 1));
+            Assert.AreEqual("515", message.GetExtension(UnitTestProtoFile.RepeatedStringExtension, 1));
+            Assert.AreEqual(ToBytes("516"), message.GetExtension(UnitTestProtoFile.RepeatedBytesExtension, 1));
+
+            Assert.AreEqual(517, message.GetExtension(UnitTestProtoFile.RepeatedGroupExtension, 1).A);
+            Assert.AreEqual(518, message.GetExtension(UnitTestProtoFile.RepeatedNestedMessageExtension, 1).Bb);
+            Assert.AreEqual(519, message.GetExtension(UnitTestProtoFile.RepeatedForeignMessageExtension, 1).C);
+            Assert.AreEqual(520, message.GetExtension(UnitTestProtoFile.RepeatedImportMessageExtension, 1).D);
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO,
+                            message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension, 1));
+            Assert.AreEqual(ForeignEnum.FOREIGN_FOO,
+                            message.GetExtension(UnitTestProtoFile.RepeatedForeignEnumExtension, 1));
+            Assert.AreEqual(ImportEnum.IMPORT_FOO,
+                            message.GetExtension(UnitTestProtoFile.RepeatedImportEnumExtension, 1));
+
+            Assert.AreEqual("524", message.GetExtension(UnitTestProtoFile.RepeatedStringPieceExtension, 1));
+            Assert.AreEqual("525", message.GetExtension(UnitTestProtoFile.RepeatedCordExtension, 1));
+        }
+
+        internal static void AssertExtensionsClear(TestAllExtensions message)
+        {
+            // HasBlah() should initially be false for all optional fields.
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalInt64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalUint32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalUint64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalSint32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalSint64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalFixed32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalFixed64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalSfixed32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalSfixed64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalFloatExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalDoubleExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalBoolExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalStringExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalBytesExtension));
+
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalGroupExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalNestedMessageExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalForeignMessageExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalImportMessageExtension));
+
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalImportEnumExtension));
+
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalStringPieceExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.OptionalCordExtension));
+
+            // Optional fields without defaults are set to zero or something like it.
+            Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
+            Assert.AreEqual(0L, message.GetExtension(UnitTestProtoFile.OptionalInt64Extension));
+            Assert.AreEqual(0U, message.GetExtension(UnitTestProtoFile.OptionalUint32Extension));
+            Assert.AreEqual(0UL, message.GetExtension(UnitTestProtoFile.OptionalUint64Extension));
+            Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalSint32Extension));
+            Assert.AreEqual(0L, message.GetExtension(UnitTestProtoFile.OptionalSint64Extension));
+            Assert.AreEqual(0U, message.GetExtension(UnitTestProtoFile.OptionalFixed32Extension));
+            Assert.AreEqual(0UL, message.GetExtension(UnitTestProtoFile.OptionalFixed64Extension));
+            Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalSfixed32Extension));
+            Assert.AreEqual(0L, message.GetExtension(UnitTestProtoFile.OptionalSfixed64Extension));
+            Assert.AreEqual(0F, message.GetExtension(UnitTestProtoFile.OptionalFloatExtension));
+            Assert.AreEqual(0D, message.GetExtension(UnitTestProtoFile.OptionalDoubleExtension));
+            Assert.AreEqual(false, message.GetExtension(UnitTestProtoFile.OptionalBoolExtension));
+            Assert.AreEqual("", message.GetExtension(UnitTestProtoFile.OptionalStringExtension));
+            Assert.AreEqual(ByteString.Empty, message.GetExtension(UnitTestProtoFile.OptionalBytesExtension));
+
+            // Embedded messages should also be clear.
+            Assert.IsFalse(message.GetExtension(UnitTestProtoFile.OptionalGroupExtension).HasA);
+            Assert.IsFalse(message.GetExtension(UnitTestProtoFile.OptionalNestedMessageExtension).HasBb);
+            Assert.IsFalse(message.GetExtension(UnitTestProtoFile.OptionalForeignMessageExtension).HasC);
+            Assert.IsFalse(message.GetExtension(UnitTestProtoFile.OptionalImportMessageExtension).HasD);
+
+            Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalGroupExtension).A);
+            Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalNestedMessageExtension).Bb);
+            Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalForeignMessageExtension).C);
+            Assert.AreEqual(0, message.GetExtension(UnitTestProtoFile.OptionalImportMessageExtension).D);
+
+            // Enums without defaults are set to the first value in the enum.
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.FOO,
+                            message.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
+            Assert.AreEqual(ForeignEnum.FOREIGN_FOO,
+                            message.GetExtension(UnitTestProtoFile.OptionalForeignEnumExtension));
+            Assert.AreEqual(ImportEnum.IMPORT_FOO, message.GetExtension(UnitTestProtoFile.OptionalImportEnumExtension));
+
+            Assert.AreEqual("", message.GetExtension(UnitTestProtoFile.OptionalStringPieceExtension));
+            Assert.AreEqual("", message.GetExtension(UnitTestProtoFile.OptionalCordExtension));
+
+            // Repeated fields are empty.
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedInt64Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint32Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedUint64Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint32Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedSint64Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed32Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedFixed64Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed32Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedSfixed64Extension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedFloatExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedDoubleExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedBoolExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedBytesExtension));
+
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedGroupExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedMessageExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignMessageExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportMessageExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedNestedEnumExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedForeignEnumExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedImportEnumExtension));
+
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedStringPieceExtension));
+            Assert.AreEqual(0, message.GetExtensionCount(UnitTestProtoFile.RepeatedCordExtension));
+
+            // HasBlah() should also be false for all default fields.
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultInt32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultInt64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultUint32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultUint64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultSint32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultSint64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultFixed32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultFixed64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultSfixed32Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultSfixed64Extension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultFloatExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultDoubleExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultBoolExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultStringExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultBytesExtension));
+
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultNestedEnumExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultImportEnumExtension));
+
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultStringPieceExtension));
+            Assert.IsFalse(message.HasExtension(UnitTestProtoFile.DefaultCordExtension));
+
+            // Fields with defaults have their default values (duh).
+            Assert.AreEqual(41, message.GetExtension(UnitTestProtoFile.DefaultInt32Extension));
+            Assert.AreEqual(42L, message.GetExtension(UnitTestProtoFile.DefaultInt64Extension));
+            Assert.AreEqual(43U, message.GetExtension(UnitTestProtoFile.DefaultUint32Extension));
+            Assert.AreEqual(44UL, message.GetExtension(UnitTestProtoFile.DefaultUint64Extension));
+            Assert.AreEqual(-45, message.GetExtension(UnitTestProtoFile.DefaultSint32Extension));
+            Assert.AreEqual(46L, message.GetExtension(UnitTestProtoFile.DefaultSint64Extension));
+            Assert.AreEqual(47U, message.GetExtension(UnitTestProtoFile.DefaultFixed32Extension));
+            Assert.AreEqual(48UL, message.GetExtension(UnitTestProtoFile.DefaultFixed64Extension));
+            Assert.AreEqual(49, message.GetExtension(UnitTestProtoFile.DefaultSfixed32Extension));
+            Assert.AreEqual(-50L, message.GetExtension(UnitTestProtoFile.DefaultSfixed64Extension));
+            Assert.AreEqual(51.5F, message.GetExtension(UnitTestProtoFile.DefaultFloatExtension));
+            Assert.AreEqual(52e3D, message.GetExtension(UnitTestProtoFile.DefaultDoubleExtension));
+            Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.DefaultBoolExtension));
+            Assert.AreEqual("hello", message.GetExtension(UnitTestProtoFile.DefaultStringExtension));
+            Assert.AreEqual(ToBytes("world"), message.GetExtension(UnitTestProtoFile.DefaultBytesExtension));
+
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
+                            message.GetExtension(UnitTestProtoFile.DefaultNestedEnumExtension));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetExtension(UnitTestProtoFile.DefaultForeignEnumExtension));
+            Assert.AreEqual(ImportEnum.IMPORT_BAR, message.GetExtension(UnitTestProtoFile.DefaultImportEnumExtension));
+
+            Assert.AreEqual("abc", message.GetExtension(UnitTestProtoFile.DefaultStringPieceExtension));
+            Assert.AreEqual("123", message.GetExtension(UnitTestProtoFile.DefaultCordExtension));
+        }
+
+        /// <summary>
+        /// Set every field of the specified message to a unique value.
+        /// </summary>
+        public static void SetPackedFields(TestPackedTypes.Builder message)
+        {
+            message.AddPackedInt32(601);
+            message.AddPackedInt64(602);
+            message.AddPackedUint32(603);
+            message.AddPackedUint64(604);
+            message.AddPackedSint32(605);
+            message.AddPackedSint64(606);
+            message.AddPackedFixed32(607);
+            message.AddPackedFixed64(608);
+            message.AddPackedSfixed32(609);
+            message.AddPackedSfixed64(610);
+            message.AddPackedFloat(611);
+            message.AddPackedDouble(612);
+            message.AddPackedBool(true);
+            message.AddPackedEnum(ForeignEnum.FOREIGN_BAR);
+            // Add a second one of each field.
+            message.AddPackedInt32(701);
+            message.AddPackedInt64(702);
+            message.AddPackedUint32(703);
+            message.AddPackedUint64(704);
+            message.AddPackedSint32(705);
+            message.AddPackedSint64(706);
+            message.AddPackedFixed32(707);
+            message.AddPackedFixed64(708);
+            message.AddPackedSfixed32(709);
+            message.AddPackedSfixed64(710);
+            message.AddPackedFloat(711);
+            message.AddPackedDouble(712);
+            message.AddPackedBool(false);
+            message.AddPackedEnum(ForeignEnum.FOREIGN_BAZ);
+        }
+
+        /// <summary>
+        /// Asserts that all the fields of the specified message are set to the values assigned
+        /// in SetPackedFields.
+        /// </summary>
+        public static void AssertPackedFieldsSet(TestPackedTypes message)
+        {
+            Assert.AreEqual(2, message.PackedInt32Count);
+            Assert.AreEqual(2, message.PackedInt64Count);
+            Assert.AreEqual(2, message.PackedUint32Count);
+            Assert.AreEqual(2, message.PackedUint64Count);
+            Assert.AreEqual(2, message.PackedSint32Count);
+            Assert.AreEqual(2, message.PackedSint64Count);
+            Assert.AreEqual(2, message.PackedFixed32Count);
+            Assert.AreEqual(2, message.PackedFixed64Count);
+            Assert.AreEqual(2, message.PackedSfixed32Count);
+            Assert.AreEqual(2, message.PackedSfixed64Count);
+            Assert.AreEqual(2, message.PackedFloatCount);
+            Assert.AreEqual(2, message.PackedDoubleCount);
+            Assert.AreEqual(2, message.PackedBoolCount);
+            Assert.AreEqual(2, message.PackedEnumCount);
+            Assert.AreEqual(601, message.GetPackedInt32(0));
+            Assert.AreEqual(602, message.GetPackedInt64(0));
+            Assert.AreEqual(603, message.GetPackedUint32(0));
+            Assert.AreEqual(604, message.GetPackedUint64(0));
+            Assert.AreEqual(605, message.GetPackedSint32(0));
+            Assert.AreEqual(606, message.GetPackedSint64(0));
+            Assert.AreEqual(607, message.GetPackedFixed32(0));
+            Assert.AreEqual(608, message.GetPackedFixed64(0));
+            Assert.AreEqual(609, message.GetPackedSfixed32(0));
+            Assert.AreEqual(610, message.GetPackedSfixed64(0));
+            Assert.AreEqual(611, message.GetPackedFloat(0), 0.0);
+            Assert.AreEqual(612, message.GetPackedDouble(0), 0.0);
+            Assert.AreEqual(true, message.GetPackedBool(0));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAR, message.GetPackedEnum(0));
+            Assert.AreEqual(701, message.GetPackedInt32(1));
+            Assert.AreEqual(702, message.GetPackedInt64(1));
+            Assert.AreEqual(703, message.GetPackedUint32(1));
+            Assert.AreEqual(704, message.GetPackedUint64(1));
+            Assert.AreEqual(705, message.GetPackedSint32(1));
+            Assert.AreEqual(706, message.GetPackedSint64(1));
+            Assert.AreEqual(707, message.GetPackedFixed32(1));
+            Assert.AreEqual(708, message.GetPackedFixed64(1));
+            Assert.AreEqual(709, message.GetPackedSfixed32(1));
+            Assert.AreEqual(710, message.GetPackedSfixed64(1));
+            Assert.AreEqual(711, message.GetPackedFloat(1), 0.0);
+            Assert.AreEqual(712, message.GetPackedDouble(1), 0.0);
+            Assert.AreEqual(false, message.GetPackedBool(1));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.GetPackedEnum(1));
+        }
+
+        public static void SetPackedExtensions(TestPackedExtensions.Builder message)
+        {
+            message.AddExtension(UnitTestProtoFile.PackedInt32Extension, 601);
+            message.AddExtension(UnitTestProtoFile.PackedInt64Extension, 602L);
+            message.AddExtension(UnitTestProtoFile.PackedUint32Extension, 603U);
+            message.AddExtension(UnitTestProtoFile.PackedUint64Extension, 604UL);
+            message.AddExtension(UnitTestProtoFile.PackedSint32Extension, 605);
+            message.AddExtension(UnitTestProtoFile.PackedSint64Extension, 606L);
+            message.AddExtension(UnitTestProtoFile.PackedFixed32Extension, 607U);
+            message.AddExtension(UnitTestProtoFile.PackedFixed64Extension, 608UL);
+            message.AddExtension(UnitTestProtoFile.PackedSfixed32Extension, 609);
+            message.AddExtension(UnitTestProtoFile.PackedSfixed64Extension, 610L);
+            message.AddExtension(UnitTestProtoFile.PackedFloatExtension, 611F);
+            message.AddExtension(UnitTestProtoFile.PackedDoubleExtension, 612D);
+            message.AddExtension(UnitTestProtoFile.PackedBoolExtension, true);
+            message.AddExtension(UnitTestProtoFile.PackedEnumExtension, ForeignEnum.FOREIGN_BAR);
+            // Add a second one of each field.
+            message.AddExtension(UnitTestProtoFile.PackedInt32Extension, 701);
+            message.AddExtension(UnitTestProtoFile.PackedInt64Extension, 702L);
+            message.AddExtension(UnitTestProtoFile.PackedUint32Extension, 703U);
+            message.AddExtension(UnitTestProtoFile.PackedUint64Extension, 704UL);
+            message.AddExtension(UnitTestProtoFile.PackedSint32Extension, 705);
+            message.AddExtension(UnitTestProtoFile.PackedSint64Extension, 706L);
+            message.AddExtension(UnitTestProtoFile.PackedFixed32Extension, 707U);
+            message.AddExtension(UnitTestProtoFile.PackedFixed64Extension, 708UL);
+            message.AddExtension(UnitTestProtoFile.PackedSfixed32Extension, 709);
+            message.AddExtension(UnitTestProtoFile.PackedSfixed64Extension, 710L);
+            message.AddExtension(UnitTestProtoFile.PackedFloatExtension, 711F);
+            message.AddExtension(UnitTestProtoFile.PackedDoubleExtension, 712D);
+            message.AddExtension(UnitTestProtoFile.PackedBoolExtension, false);
+            message.AddExtension(UnitTestProtoFile.PackedEnumExtension, ForeignEnum.FOREIGN_BAZ);
+        }
+
+        public static void AssertPackedExtensionsSet(TestPackedExtensions message)
+        {
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedInt32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedInt64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedUint32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedUint64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedSint32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedSint64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedFixed32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedFixed64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedSfixed32Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedSfixed64Extension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedFloatExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedDoubleExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedBoolExtension));
+            Assert.AreEqual(2, message.GetExtensionCount(UnitTestProtoFile.PackedEnumExtension));
+            Assert.AreEqual(601, message.GetExtension(UnitTestProtoFile.PackedInt32Extension, 0));
+            Assert.AreEqual(602L, message.GetExtension(UnitTestProtoFile.PackedInt64Extension, 0));
+            Assert.AreEqual(603, message.GetExtension(UnitTestProtoFile.PackedUint32Extension, 0));
+            Assert.AreEqual(604L, message.GetExtension(UnitTestProtoFile.PackedUint64Extension, 0));
+            Assert.AreEqual(605, message.GetExtension(UnitTestProtoFile.PackedSint32Extension, 0));
+            Assert.AreEqual(606L, message.GetExtension(UnitTestProtoFile.PackedSint64Extension, 0));
+            Assert.AreEqual(607, message.GetExtension(UnitTestProtoFile.PackedFixed32Extension, 0));
+            Assert.AreEqual(608L, message.GetExtension(UnitTestProtoFile.PackedFixed64Extension, 0));
+            Assert.AreEqual(609, message.GetExtension(UnitTestProtoFile.PackedSfixed32Extension, 0));
+            Assert.AreEqual(610L, message.GetExtension(UnitTestProtoFile.PackedSfixed64Extension, 0));
+            Assert.AreEqual(611F, message.GetExtension(UnitTestProtoFile.PackedFloatExtension, 0));
+            Assert.AreEqual(612D, message.GetExtension(UnitTestProtoFile.PackedDoubleExtension, 0));
+            Assert.AreEqual(true, message.GetExtension(UnitTestProtoFile.PackedBoolExtension, 0));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAR,
+                            message.GetExtension(UnitTestProtoFile.PackedEnumExtension, 0));
+            Assert.AreEqual(701, message.GetExtension(UnitTestProtoFile.PackedInt32Extension, 1));
+            Assert.AreEqual(702L, message.GetExtension(UnitTestProtoFile.PackedInt64Extension, 1));
+            Assert.AreEqual(703, message.GetExtension(UnitTestProtoFile.PackedUint32Extension, 1));
+            Assert.AreEqual(704L, message.GetExtension(UnitTestProtoFile.PackedUint64Extension, 1));
+            Assert.AreEqual(705, message.GetExtension(UnitTestProtoFile.PackedSint32Extension, 1));
+            Assert.AreEqual(706L, message.GetExtension(UnitTestProtoFile.PackedSint64Extension, 1));
+            Assert.AreEqual(707, message.GetExtension(UnitTestProtoFile.PackedFixed32Extension, 1));
+            Assert.AreEqual(708L, message.GetExtension(UnitTestProtoFile.PackedFixed64Extension, 1));
+            Assert.AreEqual(709, message.GetExtension(UnitTestProtoFile.PackedSfixed32Extension, 1));
+            Assert.AreEqual(710L, message.GetExtension(UnitTestProtoFile.PackedSfixed64Extension, 1));
+            Assert.AreEqual(711F, message.GetExtension(UnitTestProtoFile.PackedFloatExtension, 1));
+            Assert.AreEqual(712D, message.GetExtension(UnitTestProtoFile.PackedDoubleExtension, 1));
+            Assert.AreEqual(false, message.GetExtension(UnitTestProtoFile.PackedBoolExtension, 1));
+            Assert.AreEqual(ForeignEnum.FOREIGN_BAZ, message.GetExtension(UnitTestProtoFile.PackedEnumExtension, 1));
+        }
+
+        private static ByteString goldenPackedFieldsMessage = null;
+
+        /// <summary>
+        /// Get the bytes of the "golden packed fields message".  This is a serialized
+        /// TestPackedTypes with all fields set as they would be by SetPackedFields,
+        /// but it is loaded from a file on disk rather than generated dynamically.
+        /// The file is actually generated by C++ code, so testing against it verifies compatibility
+        /// with C++.
+        /// </summary>
+        public static ByteString GetGoldenPackedFieldsMessage()
+        {
+            if (goldenPackedFieldsMessage == null)
+            {
+                goldenPackedFieldsMessage = ReadBytesFromFile("golden_packed_fields_message");
+            }
+            return goldenPackedFieldsMessage;
+        }
+
+        private static readonly string[] TestCultures = {"en-US", "en-GB", "fr-FR", "de-DE"};
+
+        public static void TestInMultipleCultures(Action test)
+        {
+            CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
+            foreach (string culture in TestCultures)
+            {
+                try
+                {
+                    Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
+                    test();
+                }
+                finally
+                {
+                    Thread.CurrentThread.CurrentCulture = originalCulture;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Helper to construct a byte array from a bunch of bytes.
+        /// </summary>
+        internal static byte[] Bytes(params byte[] bytesAsInts)
+        {
+            byte[] bytes = new byte[bytesAsInts.Length];
+            for (int i = 0; i < bytesAsInts.Length; i++)
+            {
+                bytes[i] = (byte) bytesAsInts[i];
+            }
+            return bytes;
+        }
+
+        internal static void AssertArgumentNullException(Action action)
+        {
+            try
+            {
+                action();
+                Assert.Fail("Exception was not thrown");
+            }
+            catch (ArgumentNullException)
+            {
+                // We expect this exception.
+            }
+        }
+    }
+}

+ 571 - 536
src/ProtocolBuffers.Test/TextFormatTest.cs

@@ -1,536 +1,571 @@
-#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;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-using System.Globalization;
-using System.Threading;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class TextFormatTest {
-
-    private static readonly string AllFieldsSetText = TestUtil.ReadTextFromFile("text_format_unittest_data.txt");
-    private static readonly string AllExtensionsSetText = TestUtil.ReadTextFromFile("text_format_unittest_extensions_data.txt");
-
-    /// <summary>
-    /// Note that this is slightly different to the Java - 123.0 becomes 123, and 1.23E17 becomes 1.23E+17.
-    /// Both of these differences can be parsed by the Java and the C++, and we can parse their output too.
-    /// </summary>
-    private const string ExoticText =
-      "repeated_int32: -1\n" +
-      "repeated_int32: -2147483648\n" +
-      "repeated_int64: -1\n" +
-      "repeated_int64: -9223372036854775808\n" +
-      "repeated_uint32: 4294967295\n" +
-      "repeated_uint32: 2147483648\n" +
-      "repeated_uint64: 18446744073709551615\n" +
-      "repeated_uint64: 9223372036854775808\n" +
-      "repeated_double: 123\n" +
-      "repeated_double: 123.5\n" +
-      "repeated_double: 0.125\n" +
-      "repeated_double: 1.23E+17\n" +
-      "repeated_double: 1.235E+22\n" +
-      "repeated_double: 1.235E-18\n" +
-      "repeated_double: 123.456789\n" +
-      "repeated_double: Infinity\n" +
-      "repeated_double: -Infinity\n" +
-      "repeated_double: NaN\n" +
-      "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" +
-        "\\341\\210\\264\"\n" +
-      "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n";
-
-    private const string MessageSetText =
-      "[protobuf_unittest.TestMessageSetExtension1] {\n" +
-      "  i: 123\n" +
-      "}\n" +
-      "[protobuf_unittest.TestMessageSetExtension2] {\n" +
-      "  str: \"foo\"\n" +
-      "}\n";
-    
-    /// <summary>
-    /// Print TestAllTypes and compare with golden file. 
-    /// </summary>
-    [Test]
-    public void PrintMessage() {
-      TestUtil.TestInMultipleCultures(() => {
-        string text = TextFormat.PrintToString(TestUtil.GetAllSet());
-        Assert.AreEqual(AllFieldsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n"));
-      });
-    }
-
-    /// <summary>
-    /// Print TestAllExtensions and compare with golden file.
-    /// </summary>
-    [Test]
-    public void PrintExtensions() {
-      string text = TextFormat.PrintToString(TestUtil.GetAllExtensionsSet());
-
-      Assert.AreEqual(AllExtensionsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n"));
-    }
-
-    /// <summary>
-    /// Test printing of unknown fields in a message.
-    /// </summary>
-    [Test]
-    public void PrintUnknownFields() {
-      TestEmptyMessage message =
-        TestEmptyMessage.CreateBuilder()
-          .SetUnknownFields(
-            UnknownFieldSet.CreateBuilder()
-              .AddField(5,
-                UnknownField.CreateBuilder()
-                  .AddVarint(1)
-                  .AddFixed32(2)
-                  .AddFixed64(3)
-                  .AddLengthDelimited(ByteString.CopyFromUtf8("4"))
-                  .AddGroup(
-                    UnknownFieldSet.CreateBuilder()
-                      .AddField(10,
-                        UnknownField.CreateBuilder()
-                          .AddVarint(5)
-                          .Build())
-                      .Build())
-                  .Build())
-              .AddField(8,
-                UnknownField.CreateBuilder()
-                  .AddVarint(1)
-                  .AddVarint(2)
-                  .AddVarint(3)
-                  .Build())
-              .AddField(15,
-                UnknownField.CreateBuilder()
-                  .AddVarint(0xABCDEF1234567890L)
-                  .AddFixed32(0xABCD1234)
-                  .AddFixed64(0xABCDEF1234567890L)
-                  .Build())
-              .Build())
-          .Build();
-
-      Assert.AreEqual(
-        "5: 1\n" +
-        "5: 0x00000002\n" +
-        "5: 0x0000000000000003\n" +
-        "5: \"4\"\n" +
-        "5 {\n" +
-        "  10: 5\n" +
-        "}\n" +
-        "8: 1\n" +
-        "8: 2\n" +
-        "8: 3\n" +
-        "15: 12379813812177893520\n" +
-        "15: 0xabcd1234\n" +
-        "15: 0xabcdef1234567890\n",
-        TextFormat.PrintToString(message));
-    }
-
-    /// <summary>
-    /// Helper to construct a ByteString from a string containing only 8-bit
-    /// characters. The characters are converted directly to bytes, *not*
-    /// encoded using UTF-8.
-    /// </summary>
-    private static ByteString Bytes(string str) {
-      return ByteString.CopyFrom(Encoding.GetEncoding(28591).GetBytes(str));
-    }   
-
-    [Test]
-    public void PrintExotic() {
-      IMessage message = TestAllTypes.CreateBuilder()
-        // Signed vs. unsigned numbers.
-        .AddRepeatedInt32 (-1)
-        .AddRepeatedUint32(uint.MaxValue)
-        .AddRepeatedInt64 (-1)
-        .AddRepeatedUint64(ulong.MaxValue)
-
-        .AddRepeatedInt32 (1  << 31)
-        .AddRepeatedUint32(1U  << 31)
-        .AddRepeatedInt64 (1L << 63)
-        .AddRepeatedUint64(1UL << 63)
-
-        // Floats of various precisions and exponents.
-        .AddRepeatedDouble(123)
-        .AddRepeatedDouble(123.5)
-        .AddRepeatedDouble(0.125)
-        .AddRepeatedDouble(123e15)
-        .AddRepeatedDouble(123.5e20)
-        .AddRepeatedDouble(123.5e-20)
-        .AddRepeatedDouble(123.456789)
-        .AddRepeatedDouble(Double.PositiveInfinity)
-        .AddRepeatedDouble(Double.NegativeInfinity)
-        .AddRepeatedDouble(Double.NaN)
-
-        // Strings and bytes that needing escaping.
-        .AddRepeatedString("\0\u0001\u0007\b\f\n\r\t\v\\\'\"\u1234")
-        .AddRepeatedBytes(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\"\u00fe"))
-        .Build();
-
-      Assert.AreEqual(ExoticText, message.ToString());
-    }
-
-    [Test]
-    public void PrintMessageSet() {
-      TestMessageSet messageSet =
-        TestMessageSet.CreateBuilder()
-          .SetExtension(
-            TestMessageSetExtension1.MessageSetExtension,
-            TestMessageSetExtension1.CreateBuilder().SetI(123).Build())
-          .SetExtension(
-            TestMessageSetExtension2.MessageSetExtension,
-            TestMessageSetExtension2.CreateBuilder().SetStr("foo").Build())
-          .Build();
-
-      Assert.AreEqual(MessageSetText, messageSet.ToString());
-    }
-
-    // =================================================================
-
-    [Test]
-    public void Parse() {
-      TestUtil.TestInMultipleCultures(() => {
-        TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-        TextFormat.Merge(AllFieldsSetText, builder);
-        TestUtil.AssertAllFieldsSet(builder.Build());
-      });
-    }
-
-    [Test]
-    public void ParseReader() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TextFormat.Merge(new StringReader(AllFieldsSetText), builder);
-      TestUtil.AssertAllFieldsSet(builder.Build());
-    }
-
-    [Test]
-    public void ParseExtensions() {
-      TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
-      TextFormat.Merge(AllExtensionsSetText,
-                       TestUtil.CreateExtensionRegistry(),
-                       builder);
-      TestUtil.AssertAllExtensionsSet(builder.Build());
-    }
-
-    [Test]
-    public void ParseCompatibility() {
-      string original = "repeated_float: inf\n" +
-                        "repeated_float: -inf\n" +
-                        "repeated_float: nan\n" +
-                        "repeated_float: inff\n" +
-                        "repeated_float: -inff\n" +
-                        "repeated_float: nanf\n" +
-                        "repeated_float: 1.0f\n" +
-                        "repeated_float: infinityf\n" +
-                        "repeated_float: -Infinityf\n" +
-                        "repeated_double: infinity\n" +
-                        "repeated_double: -infinity\n" +
-                        "repeated_double: nan\n";
-      string canonical = "repeated_float: Infinity\n" +
-                          "repeated_float: -Infinity\n" +
-                          "repeated_float: NaN\n" +
-                          "repeated_float: Infinity\n" +
-                          "repeated_float: -Infinity\n" +
-                          "repeated_float: NaN\n" +
-                          "repeated_float: 1\n" + // Java has 1.0; this is fine
-                          "repeated_float: Infinity\n" +
-                          "repeated_float: -Infinity\n" +
-                          "repeated_double: Infinity\n" +
-                          "repeated_double: -Infinity\n" +
-                          "repeated_double: NaN\n";
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TextFormat.Merge(original, builder);
-      Assert.AreEqual(canonical, builder.Build().ToString());
-    }
-
-    [Test]
-    public void ParseExotic() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TextFormat.Merge(ExoticText, builder);
-
-      // Too lazy to check things individually.  Don't try to debug this
-      // if testPrintExotic() is Assert.Failing.
-      Assert.AreEqual(ExoticText, builder.Build().ToString());
-    }
-
-    [Test]
-    public void ParseMessageSet() {
-      ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
-      extensionRegistry.Add(TestMessageSetExtension1.MessageSetExtension);
-      extensionRegistry.Add(TestMessageSetExtension2.MessageSetExtension);
-
-      TestMessageSet.Builder builder = TestMessageSet.CreateBuilder();
-      TextFormat.Merge(MessageSetText, extensionRegistry, builder);
-      TestMessageSet messageSet = builder.Build();
-
-      Assert.IsTrue(messageSet.HasExtension(TestMessageSetExtension1.MessageSetExtension));
-      Assert.AreEqual(123, messageSet.GetExtension(TestMessageSetExtension1.MessageSetExtension).I);
-      Assert.IsTrue(messageSet.HasExtension(TestMessageSetExtension2.MessageSetExtension));
-      Assert.AreEqual("foo", messageSet.GetExtension(TestMessageSetExtension2.MessageSetExtension).Str);
-    }
-
-    [Test]
-    public void ParseNumericEnum() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TextFormat.Merge("optional_nested_enum: 2", builder);
-      Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, builder.OptionalNestedEnum);
-    }
-
-    [Test]
-    public void ParseAngleBrackets() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TextFormat.Merge("OptionalGroup: < a: 1 >", builder);
-      Assert.IsTrue(builder.HasOptionalGroup);
-      Assert.AreEqual(1, builder.OptionalGroup.A);
-    }
-
-    [Test]
-    public void ParseComment() {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TextFormat.Merge(
-        "# this is a comment\n" +
-        "optional_int32: 1  # another comment\n" +
-        "optional_int64: 2\n" +
-        "# EOF comment", builder);
-      Assert.AreEqual(1, builder.OptionalInt32);
-      Assert.AreEqual(2, builder.OptionalInt64);
-    }
-
-
-    private static void AssertParseError(string error, string text) {
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      try {
-        TextFormat.Merge(text, TestUtil.CreateExtensionRegistry(), builder);
-        Assert.Fail("Expected parse exception.");
-      } catch (FormatException e) {
-        Assert.AreEqual(error, e.Message);
-      }
-    }
-
-    [Test]
-    public void ParseErrors() {
-      AssertParseError(
-        "1:16: Expected \":\".",
-        "optional_int32 123");
-      AssertParseError(
-        "1:23: Expected identifier.",
-        "optional_nested_enum: ?");
-      AssertParseError(
-        "1:18: Couldn't parse integer: Number must be positive: -1",
-        "optional_uint32: -1");
-      AssertParseError(
-        "1:17: Couldn't parse integer: Number out of range for 32-bit signed " +
-          "integer: 82301481290849012385230157",
-        "optional_int32: 82301481290849012385230157");
-      AssertParseError(
-        "1:16: Expected \"true\" or \"false\".",
-        "optional_bool: maybe");
-      AssertParseError(
-        "1:18: Expected string.",
-        "optional_string: 123");
-      AssertParseError(
-        "1:18: String missing ending quote.",
-        "optional_string: \"ueoauaoe");
-      AssertParseError(
-        "1:18: String missing ending quote.",
-        "optional_string: \"ueoauaoe\n" +
-        "optional_int32: 123");
-      AssertParseError(
-        "1:18: Invalid escape sequence: '\\z'",
-        "optional_string: \"\\z\"");
-      AssertParseError(
-        "1:18: String missing ending quote.",
-        "optional_string: \"ueoauaoe\n" +
-        "optional_int32: 123");
-      AssertParseError(
-        "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.",
-        "[nosuchext]: 123");
-      AssertParseError(
-        "1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " +
-          "not extend message type \"protobuf_unittest.TestAllTypes\".",
-        "[protobuf_unittest.optional_int32_extension]: 123");
-      AssertParseError(
-        "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " +
-          "named \"nosuchfield\".",
-        "nosuchfield: 123");
-      AssertParseError(
-        "1:21: Expected \">\".",
-        "OptionalGroup < a: 1");
-      AssertParseError(
-        "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
-          "value named \"NO_SUCH_VALUE\".",
-        "optional_nested_enum: NO_SUCH_VALUE");
-      AssertParseError(
-        "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
-          "value with number 123.",
-        "optional_nested_enum: 123");
-
-      // Delimiters must match.
-      AssertParseError(
-        "1:22: Expected identifier.",
-        "OptionalGroup < a: 1 }");
-      AssertParseError(
-        "1:22: Expected identifier.",
-        "OptionalGroup { a: 1 >");
-    }
-
-    // =================================================================
-
-    private static ByteString Bytes(params byte[] bytes) {
-      return ByteString.CopyFrom(bytes);
-    }
-
-    private delegate void FormattingAction();
-
-    private static void AssertFormatException(FormattingAction action) {
-      try {
-        action();
-        Assert.Fail("Should have thrown an exception.");
-      } catch (FormatException) {
-        // success
-      }
-    }
-
-    [Test]
-    public void Escape() {
-      // Escape sequences.
-      Assert.AreEqual("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
-        TextFormat.EscapeBytes(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\"")));
-      Assert.AreEqual("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
-        TextFormat.EscapeText("\0\u0001\u0007\b\f\n\r\t\v\\\'\""));
-      Assert.AreEqual(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\""),
-        TextFormat.UnescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
-      Assert.AreEqual("\0\u0001\u0007\b\f\n\r\t\v\\\'\"",
-        TextFormat.UnescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
-
-      // Unicode handling.
-      Assert.AreEqual("\\341\\210\\264", TextFormat.EscapeText("\u1234"));
-      Assert.AreEqual("\\341\\210\\264", TextFormat.EscapeBytes(Bytes(0xe1, 0x88, 0xb4)));
-      Assert.AreEqual("\u1234", TextFormat.UnescapeText("\\341\\210\\264"));
-      Assert.AreEqual(Bytes(0xe1, 0x88, 0xb4), TextFormat.UnescapeBytes("\\341\\210\\264"));
-      Assert.AreEqual("\u1234", TextFormat.UnescapeText("\\xe1\\x88\\xb4"));
-      Assert.AreEqual(Bytes(0xe1, 0x88, 0xb4), TextFormat.UnescapeBytes("\\xe1\\x88\\xb4"));
-
-      // Errors.
-      AssertFormatException(() => TextFormat.UnescapeText("\\x"));
-      AssertFormatException(() => TextFormat.UnescapeText("\\z"));
-      AssertFormatException(() => TextFormat.UnescapeText("\\"));
-    }
-
-    [Test]
-    public void ParseInteger() {
-      Assert.AreEqual(          0, TextFormat.ParseInt32(          "0"));
-      Assert.AreEqual(          1, TextFormat.ParseInt32(          "1"));
-      Assert.AreEqual(         -1, TextFormat.ParseInt32(         "-1"));
-      Assert.AreEqual(      12345, TextFormat.ParseInt32(      "12345"));
-      Assert.AreEqual(     -12345, TextFormat.ParseInt32(     "-12345"));
-      Assert.AreEqual( 2147483647, TextFormat.ParseInt32( "2147483647"));
-      Assert.AreEqual(-2147483648, TextFormat.ParseInt32("-2147483648"));
-
-      Assert.AreEqual(          0, TextFormat.ParseUInt32(         "0"));
-      Assert.AreEqual(          1, TextFormat.ParseUInt32(         "1"));
-      Assert.AreEqual(      12345, TextFormat.ParseUInt32(     "12345"));
-      Assert.AreEqual( 2147483647, TextFormat.ParseUInt32("2147483647"));
-      Assert.AreEqual(2147483648U, TextFormat.ParseUInt32("2147483648"));
-      Assert.AreEqual(4294967295U, TextFormat.ParseUInt32("4294967295"));
-
-      Assert.AreEqual(          0L, TextFormat.ParseInt64(          "0"));
-      Assert.AreEqual(          1L, TextFormat.ParseInt64(          "1"));
-      Assert.AreEqual(         -1L, TextFormat.ParseInt64(         "-1"));
-      Assert.AreEqual(      12345L, TextFormat.ParseInt64(      "12345"));
-      Assert.AreEqual(     -12345L, TextFormat.ParseInt64(     "-12345"));
-      Assert.AreEqual( 2147483647L, TextFormat.ParseInt64( "2147483647"));
-      Assert.AreEqual(-2147483648L, TextFormat.ParseInt64("-2147483648"));
-      Assert.AreEqual( 4294967295L, TextFormat.ParseInt64( "4294967295"));
-      Assert.AreEqual( 4294967296L, TextFormat.ParseInt64( "4294967296"));
-      Assert.AreEqual(9223372036854775807L, TextFormat.ParseInt64("9223372036854775807"));
-      Assert.AreEqual(-9223372036854775808L, TextFormat.ParseInt64("-9223372036854775808"));
-
-      Assert.AreEqual(          0L, TextFormat.ParseUInt64(          "0"));
-      Assert.AreEqual(          1L, TextFormat.ParseUInt64(          "1"));
-      Assert.AreEqual(      12345L, TextFormat.ParseUInt64(      "12345"));
-      Assert.AreEqual( 2147483647L, TextFormat.ParseUInt64( "2147483647"));
-      Assert.AreEqual( 4294967295L, TextFormat.ParseUInt64( "4294967295"));
-      Assert.AreEqual( 4294967296L, TextFormat.ParseUInt64( "4294967296"));
-      Assert.AreEqual(9223372036854775807UL, TextFormat.ParseUInt64("9223372036854775807"));
-      Assert.AreEqual(9223372036854775808UL, TextFormat.ParseUInt64("9223372036854775808"));
-      Assert.AreEqual(18446744073709551615UL, TextFormat.ParseUInt64("18446744073709551615"));
-
-      // Hex
-      Assert.AreEqual(0x1234abcd, TextFormat.ParseInt32("0x1234abcd"));
-      Assert.AreEqual(-0x1234abcd, TextFormat.ParseInt32("-0x1234abcd"));
-      Assert.AreEqual(0xffffffffffffffffUL, TextFormat.ParseUInt64("0xffffffffffffffff"));
-      Assert.AreEqual(0x7fffffffffffffffL,
-                   TextFormat.ParseInt64("0x7fffffffffffffff"));
-
-      // Octal
-      Assert.AreEqual(342391, TextFormat.ParseInt32("01234567"));
-
-      // Out-of-range
-      AssertFormatException(() => TextFormat.ParseInt32("2147483648"));
-      AssertFormatException(() => TextFormat.ParseInt32("-2147483649"));
-      AssertFormatException(() => TextFormat.ParseUInt32("4294967296"));
-      AssertFormatException(() => TextFormat.ParseUInt32("-1"));
-      AssertFormatException(() => TextFormat.ParseInt64("9223372036854775808"));
-      AssertFormatException(() => TextFormat.ParseInt64("-9223372036854775809"));
-      AssertFormatException(() => TextFormat.ParseUInt64("18446744073709551616"));
-      AssertFormatException(() => TextFormat.ParseUInt64("-1"));
-      AssertFormatException(() => TextFormat.ParseInt32("abcd"));
-    }
-
-    [Test]
-    public void ParseLongString() {
-      string longText =
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890" +
-        "123456789012345678901234567890123456789012345678901234567890";
-      TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
-      TextFormat.Merge("optional_string: \"" + longText + "\"", builder);
-      Assert.AreEqual(longText, builder.OptionalString);
-    }
-  }
-}
+#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;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+using System.Globalization;
+using System.Threading;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class TextFormatTest
+    {
+        private static readonly string AllFieldsSetText = TestUtil.ReadTextFromFile("text_format_unittest_data.txt");
+
+        private static readonly string AllExtensionsSetText =
+            TestUtil.ReadTextFromFile("text_format_unittest_extensions_data.txt");
+
+        /// <summary>
+        /// Note that this is slightly different to the Java - 123.0 becomes 123, and 1.23E17 becomes 1.23E+17.
+        /// Both of these differences can be parsed by the Java and the C++, and we can parse their output too.
+        /// </summary>
+        private const string ExoticText =
+            "repeated_int32: -1\n" +
+            "repeated_int32: -2147483648\n" +
+            "repeated_int64: -1\n" +
+            "repeated_int64: -9223372036854775808\n" +
+            "repeated_uint32: 4294967295\n" +
+            "repeated_uint32: 2147483648\n" +
+            "repeated_uint64: 18446744073709551615\n" +
+            "repeated_uint64: 9223372036854775808\n" +
+            "repeated_double: 123\n" +
+            "repeated_double: 123.5\n" +
+            "repeated_double: 0.125\n" +
+            "repeated_double: 1.23E+17\n" +
+            "repeated_double: 1.235E+22\n" +
+            "repeated_double: 1.235E-18\n" +
+            "repeated_double: 123.456789\n" +
+            "repeated_double: Infinity\n" +
+            "repeated_double: -Infinity\n" +
+            "repeated_double: NaN\n" +
+            "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" +
+            "\\341\\210\\264\"\n" +
+            "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n";
+
+        private const string MessageSetText =
+            "[protobuf_unittest.TestMessageSetExtension1] {\n" +
+            "  i: 123\n" +
+            "}\n" +
+            "[protobuf_unittest.TestMessageSetExtension2] {\n" +
+            "  str: \"foo\"\n" +
+            "}\n";
+
+        /// <summary>
+        /// Print TestAllTypes and compare with golden file. 
+        /// </summary>
+        [Test]
+        public void PrintMessage()
+        {
+            TestUtil.TestInMultipleCultures(() =>
+                                                {
+                                                    string text = TextFormat.PrintToString(TestUtil.GetAllSet());
+                                                    Assert.AreEqual(AllFieldsSetText.Replace("\r\n", "\n"),
+                                                                    text.Replace("\r\n", "\n"));
+                                                });
+        }
+
+        /// <summary>
+        /// Print TestAllExtensions and compare with golden file.
+        /// </summary>
+        [Test]
+        public void PrintExtensions()
+        {
+            string text = TextFormat.PrintToString(TestUtil.GetAllExtensionsSet());
+
+            Assert.AreEqual(AllExtensionsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n"));
+        }
+
+        /// <summary>
+        /// Test printing of unknown fields in a message.
+        /// </summary>
+        [Test]
+        public void PrintUnknownFields()
+        {
+            TestEmptyMessage message =
+                TestEmptyMessage.CreateBuilder()
+                    .SetUnknownFields(
+                        UnknownFieldSet.CreateBuilder()
+                            .AddField(5,
+                                      UnknownField.CreateBuilder()
+                                          .AddVarint(1)
+                                          .AddFixed32(2)
+                                          .AddFixed64(3)
+                                          .AddLengthDelimited(ByteString.CopyFromUtf8("4"))
+                                          .AddGroup(
+                                              UnknownFieldSet.CreateBuilder()
+                                                  .AddField(10,
+                                                            UnknownField.CreateBuilder()
+                                                                .AddVarint(5)
+                                                                .Build())
+                                                  .Build())
+                                          .Build())
+                            .AddField(8,
+                                      UnknownField.CreateBuilder()
+                                          .AddVarint(1)
+                                          .AddVarint(2)
+                                          .AddVarint(3)
+                                          .Build())
+                            .AddField(15,
+                                      UnknownField.CreateBuilder()
+                                          .AddVarint(0xABCDEF1234567890L)
+                                          .AddFixed32(0xABCD1234)
+                                          .AddFixed64(0xABCDEF1234567890L)
+                                          .Build())
+                            .Build())
+                    .Build();
+
+            Assert.AreEqual(
+                "5: 1\n" +
+                "5: 0x00000002\n" +
+                "5: 0x0000000000000003\n" +
+                "5: \"4\"\n" +
+                "5 {\n" +
+                "  10: 5\n" +
+                "}\n" +
+                "8: 1\n" +
+                "8: 2\n" +
+                "8: 3\n" +
+                "15: 12379813812177893520\n" +
+                "15: 0xabcd1234\n" +
+                "15: 0xabcdef1234567890\n",
+                TextFormat.PrintToString(message));
+        }
+
+        /// <summary>
+        /// Helper to construct a ByteString from a string containing only 8-bit
+        /// characters. The characters are converted directly to bytes, *not*
+        /// encoded using UTF-8.
+        /// </summary>
+        private static ByteString Bytes(string str)
+        {
+            return ByteString.CopyFrom(Encoding.GetEncoding(28591).GetBytes(str));
+        }
+
+        [Test]
+        public void PrintExotic()
+        {
+            IMessage message = TestAllTypes.CreateBuilder()
+                // Signed vs. unsigned numbers.
+                .AddRepeatedInt32(-1)
+                .AddRepeatedUint32(uint.MaxValue)
+                .AddRepeatedInt64(-1)
+                .AddRepeatedUint64(ulong.MaxValue)
+                .AddRepeatedInt32(1 << 31)
+                .AddRepeatedUint32(1U << 31)
+                .AddRepeatedInt64(1L << 63)
+                .AddRepeatedUint64(1UL << 63)
+
+                // Floats of various precisions and exponents.
+                .AddRepeatedDouble(123)
+                .AddRepeatedDouble(123.5)
+                .AddRepeatedDouble(0.125)
+                .AddRepeatedDouble(123e15)
+                .AddRepeatedDouble(123.5e20)
+                .AddRepeatedDouble(123.5e-20)
+                .AddRepeatedDouble(123.456789)
+                .AddRepeatedDouble(Double.PositiveInfinity)
+                .AddRepeatedDouble(Double.NegativeInfinity)
+                .AddRepeatedDouble(Double.NaN)
+
+                // Strings and bytes that needing escaping.
+                .AddRepeatedString("\0\u0001\u0007\b\f\n\r\t\v\\\'\"\u1234")
+                .AddRepeatedBytes(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\"\u00fe"))
+                .Build();
+
+            Assert.AreEqual(ExoticText, message.ToString());
+        }
+
+        [Test]
+        public void PrintMessageSet()
+        {
+            TestMessageSet messageSet =
+                TestMessageSet.CreateBuilder()
+                    .SetExtension(
+                        TestMessageSetExtension1.MessageSetExtension,
+                        TestMessageSetExtension1.CreateBuilder().SetI(123).Build())
+                    .SetExtension(
+                        TestMessageSetExtension2.MessageSetExtension,
+                        TestMessageSetExtension2.CreateBuilder().SetStr("foo").Build())
+                    .Build();
+
+            Assert.AreEqual(MessageSetText, messageSet.ToString());
+        }
+
+        // =================================================================
+
+        [Test]
+        public void Parse()
+        {
+            TestUtil.TestInMultipleCultures(() =>
+                                                {
+                                                    TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+                                                    TextFormat.Merge(AllFieldsSetText, builder);
+                                                    TestUtil.AssertAllFieldsSet(builder.Build());
+                                                });
+        }
+
+        [Test]
+        public void ParseReader()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TextFormat.Merge(new StringReader(AllFieldsSetText), builder);
+            TestUtil.AssertAllFieldsSet(builder.Build());
+        }
+
+        [Test]
+        public void ParseExtensions()
+        {
+            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
+            TextFormat.Merge(AllExtensionsSetText,
+                             TestUtil.CreateExtensionRegistry(),
+                             builder);
+            TestUtil.AssertAllExtensionsSet(builder.Build());
+        }
+
+        [Test]
+        public void ParseCompatibility()
+        {
+            string original = "repeated_float: inf\n" +
+                              "repeated_float: -inf\n" +
+                              "repeated_float: nan\n" +
+                              "repeated_float: inff\n" +
+                              "repeated_float: -inff\n" +
+                              "repeated_float: nanf\n" +
+                              "repeated_float: 1.0f\n" +
+                              "repeated_float: infinityf\n" +
+                              "repeated_float: -Infinityf\n" +
+                              "repeated_double: infinity\n" +
+                              "repeated_double: -infinity\n" +
+                              "repeated_double: nan\n";
+            string canonical = "repeated_float: Infinity\n" +
+                               "repeated_float: -Infinity\n" +
+                               "repeated_float: NaN\n" +
+                               "repeated_float: Infinity\n" +
+                               "repeated_float: -Infinity\n" +
+                               "repeated_float: NaN\n" +
+                               "repeated_float: 1\n" + // Java has 1.0; this is fine
+                               "repeated_float: Infinity\n" +
+                               "repeated_float: -Infinity\n" +
+                               "repeated_double: Infinity\n" +
+                               "repeated_double: -Infinity\n" +
+                               "repeated_double: NaN\n";
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TextFormat.Merge(original, builder);
+            Assert.AreEqual(canonical, builder.Build().ToString());
+        }
+
+        [Test]
+        public void ParseExotic()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TextFormat.Merge(ExoticText, builder);
+
+            // Too lazy to check things individually.  Don't try to debug this
+            // if testPrintExotic() is Assert.Failing.
+            Assert.AreEqual(ExoticText, builder.Build().ToString());
+        }
+
+        [Test]
+        public void ParseMessageSet()
+        {
+            ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
+            extensionRegistry.Add(TestMessageSetExtension1.MessageSetExtension);
+            extensionRegistry.Add(TestMessageSetExtension2.MessageSetExtension);
+
+            TestMessageSet.Builder builder = TestMessageSet.CreateBuilder();
+            TextFormat.Merge(MessageSetText, extensionRegistry, builder);
+            TestMessageSet messageSet = builder.Build();
+
+            Assert.IsTrue(messageSet.HasExtension(TestMessageSetExtension1.MessageSetExtension));
+            Assert.AreEqual(123, messageSet.GetExtension(TestMessageSetExtension1.MessageSetExtension).I);
+            Assert.IsTrue(messageSet.HasExtension(TestMessageSetExtension2.MessageSetExtension));
+            Assert.AreEqual("foo", messageSet.GetExtension(TestMessageSetExtension2.MessageSetExtension).Str);
+        }
+
+        [Test]
+        public void ParseNumericEnum()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TextFormat.Merge("optional_nested_enum: 2", builder);
+            Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, builder.OptionalNestedEnum);
+        }
+
+        [Test]
+        public void ParseAngleBrackets()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TextFormat.Merge("OptionalGroup: < a: 1 >", builder);
+            Assert.IsTrue(builder.HasOptionalGroup);
+            Assert.AreEqual(1, builder.OptionalGroup.A);
+        }
+
+        [Test]
+        public void ParseComment()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TextFormat.Merge(
+                "# this is a comment\n" +
+                "optional_int32: 1  # another comment\n" +
+                "optional_int64: 2\n" +
+                "# EOF comment", builder);
+            Assert.AreEqual(1, builder.OptionalInt32);
+            Assert.AreEqual(2, builder.OptionalInt64);
+        }
+
+
+        private static void AssertParseError(string error, string text)
+        {
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            try
+            {
+                TextFormat.Merge(text, TestUtil.CreateExtensionRegistry(), builder);
+                Assert.Fail("Expected parse exception.");
+            }
+            catch (FormatException e)
+            {
+                Assert.AreEqual(error, e.Message);
+            }
+        }
+
+        [Test]
+        public void ParseErrors()
+        {
+            AssertParseError(
+                "1:16: Expected \":\".",
+                "optional_int32 123");
+            AssertParseError(
+                "1:23: Expected identifier.",
+                "optional_nested_enum: ?");
+            AssertParseError(
+                "1:18: Couldn't parse integer: Number must be positive: -1",
+                "optional_uint32: -1");
+            AssertParseError(
+                "1:17: Couldn't parse integer: Number out of range for 32-bit signed " +
+                "integer: 82301481290849012385230157",
+                "optional_int32: 82301481290849012385230157");
+            AssertParseError(
+                "1:16: Expected \"true\" or \"false\".",
+                "optional_bool: maybe");
+            AssertParseError(
+                "1:18: Expected string.",
+                "optional_string: 123");
+            AssertParseError(
+                "1:18: String missing ending quote.",
+                "optional_string: \"ueoauaoe");
+            AssertParseError(
+                "1:18: String missing ending quote.",
+                "optional_string: \"ueoauaoe\n" +
+                "optional_int32: 123");
+            AssertParseError(
+                "1:18: Invalid escape sequence: '\\z'",
+                "optional_string: \"\\z\"");
+            AssertParseError(
+                "1:18: String missing ending quote.",
+                "optional_string: \"ueoauaoe\n" +
+                "optional_int32: 123");
+            AssertParseError(
+                "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.",
+                "[nosuchext]: 123");
+            AssertParseError(
+                "1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " +
+                "not extend message type \"protobuf_unittest.TestAllTypes\".",
+                "[protobuf_unittest.optional_int32_extension]: 123");
+            AssertParseError(
+                "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " +
+                "named \"nosuchfield\".",
+                "nosuchfield: 123");
+            AssertParseError(
+                "1:21: Expected \">\".",
+                "OptionalGroup < a: 1");
+            AssertParseError(
+                "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
+                "value named \"NO_SUCH_VALUE\".",
+                "optional_nested_enum: NO_SUCH_VALUE");
+            AssertParseError(
+                "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
+                "value with number 123.",
+                "optional_nested_enum: 123");
+
+            // Delimiters must match.
+            AssertParseError(
+                "1:22: Expected identifier.",
+                "OptionalGroup < a: 1 }");
+            AssertParseError(
+                "1:22: Expected identifier.",
+                "OptionalGroup { a: 1 >");
+        }
+
+        // =================================================================
+
+        private static ByteString Bytes(params byte[] bytes)
+        {
+            return ByteString.CopyFrom(bytes);
+        }
+
+        private delegate void FormattingAction();
+
+        private static void AssertFormatException(FormattingAction action)
+        {
+            try
+            {
+                action();
+                Assert.Fail("Should have thrown an exception.");
+            }
+            catch (FormatException)
+            {
+                // success
+            }
+        }
+
+        [Test]
+        public void Escape()
+        {
+            // Escape sequences.
+            Assert.AreEqual("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
+                            TextFormat.EscapeBytes(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\"")));
+            Assert.AreEqual("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
+                            TextFormat.EscapeText("\0\u0001\u0007\b\f\n\r\t\v\\\'\""));
+            Assert.AreEqual(Bytes("\0\u0001\u0007\b\f\n\r\t\v\\\'\""),
+                            TextFormat.UnescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
+            Assert.AreEqual("\0\u0001\u0007\b\f\n\r\t\v\\\'\"",
+                            TextFormat.UnescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
+
+            // Unicode handling.
+            Assert.AreEqual("\\341\\210\\264", TextFormat.EscapeText("\u1234"));
+            Assert.AreEqual("\\341\\210\\264", TextFormat.EscapeBytes(Bytes(0xe1, 0x88, 0xb4)));
+            Assert.AreEqual("\u1234", TextFormat.UnescapeText("\\341\\210\\264"));
+            Assert.AreEqual(Bytes(0xe1, 0x88, 0xb4), TextFormat.UnescapeBytes("\\341\\210\\264"));
+            Assert.AreEqual("\u1234", TextFormat.UnescapeText("\\xe1\\x88\\xb4"));
+            Assert.AreEqual(Bytes(0xe1, 0x88, 0xb4), TextFormat.UnescapeBytes("\\xe1\\x88\\xb4"));
+
+            // Errors.
+            AssertFormatException(() => TextFormat.UnescapeText("\\x"));
+            AssertFormatException(() => TextFormat.UnescapeText("\\z"));
+            AssertFormatException(() => TextFormat.UnescapeText("\\"));
+        }
+
+        [Test]
+        public void ParseInteger()
+        {
+            Assert.AreEqual(0, TextFormat.ParseInt32("0"));
+            Assert.AreEqual(1, TextFormat.ParseInt32("1"));
+            Assert.AreEqual(-1, TextFormat.ParseInt32("-1"));
+            Assert.AreEqual(12345, TextFormat.ParseInt32("12345"));
+            Assert.AreEqual(-12345, TextFormat.ParseInt32("-12345"));
+            Assert.AreEqual(2147483647, TextFormat.ParseInt32("2147483647"));
+            Assert.AreEqual(-2147483648, TextFormat.ParseInt32("-2147483648"));
+
+            Assert.AreEqual(0, TextFormat.ParseUInt32("0"));
+            Assert.AreEqual(1, TextFormat.ParseUInt32("1"));
+            Assert.AreEqual(12345, TextFormat.ParseUInt32("12345"));
+            Assert.AreEqual(2147483647, TextFormat.ParseUInt32("2147483647"));
+            Assert.AreEqual(2147483648U, TextFormat.ParseUInt32("2147483648"));
+            Assert.AreEqual(4294967295U, TextFormat.ParseUInt32("4294967295"));
+
+            Assert.AreEqual(0L, TextFormat.ParseInt64("0"));
+            Assert.AreEqual(1L, TextFormat.ParseInt64("1"));
+            Assert.AreEqual(-1L, TextFormat.ParseInt64("-1"));
+            Assert.AreEqual(12345L, TextFormat.ParseInt64("12345"));
+            Assert.AreEqual(-12345L, TextFormat.ParseInt64("-12345"));
+            Assert.AreEqual(2147483647L, TextFormat.ParseInt64("2147483647"));
+            Assert.AreEqual(-2147483648L, TextFormat.ParseInt64("-2147483648"));
+            Assert.AreEqual(4294967295L, TextFormat.ParseInt64("4294967295"));
+            Assert.AreEqual(4294967296L, TextFormat.ParseInt64("4294967296"));
+            Assert.AreEqual(9223372036854775807L, TextFormat.ParseInt64("9223372036854775807"));
+            Assert.AreEqual(-9223372036854775808L, TextFormat.ParseInt64("-9223372036854775808"));
+
+            Assert.AreEqual(0L, TextFormat.ParseUInt64("0"));
+            Assert.AreEqual(1L, TextFormat.ParseUInt64("1"));
+            Assert.AreEqual(12345L, TextFormat.ParseUInt64("12345"));
+            Assert.AreEqual(2147483647L, TextFormat.ParseUInt64("2147483647"));
+            Assert.AreEqual(4294967295L, TextFormat.ParseUInt64("4294967295"));
+            Assert.AreEqual(4294967296L, TextFormat.ParseUInt64("4294967296"));
+            Assert.AreEqual(9223372036854775807UL, TextFormat.ParseUInt64("9223372036854775807"));
+            Assert.AreEqual(9223372036854775808UL, TextFormat.ParseUInt64("9223372036854775808"));
+            Assert.AreEqual(18446744073709551615UL, TextFormat.ParseUInt64("18446744073709551615"));
+
+            // Hex
+            Assert.AreEqual(0x1234abcd, TextFormat.ParseInt32("0x1234abcd"));
+            Assert.AreEqual(-0x1234abcd, TextFormat.ParseInt32("-0x1234abcd"));
+            Assert.AreEqual(0xffffffffffffffffUL, TextFormat.ParseUInt64("0xffffffffffffffff"));
+            Assert.AreEqual(0x7fffffffffffffffL,
+                            TextFormat.ParseInt64("0x7fffffffffffffff"));
+
+            // Octal
+            Assert.AreEqual(342391, TextFormat.ParseInt32("01234567"));
+
+            // Out-of-range
+            AssertFormatException(() => TextFormat.ParseInt32("2147483648"));
+            AssertFormatException(() => TextFormat.ParseInt32("-2147483649"));
+            AssertFormatException(() => TextFormat.ParseUInt32("4294967296"));
+            AssertFormatException(() => TextFormat.ParseUInt32("-1"));
+            AssertFormatException(() => TextFormat.ParseInt64("9223372036854775808"));
+            AssertFormatException(() => TextFormat.ParseInt64("-9223372036854775809"));
+            AssertFormatException(() => TextFormat.ParseUInt64("18446744073709551616"));
+            AssertFormatException(() => TextFormat.ParseUInt64("-1"));
+            AssertFormatException(() => TextFormat.ParseInt32("abcd"));
+        }
+
+        [Test]
+        public void ParseLongString()
+        {
+            string longText =
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890123456789012345678901234567890";
+            TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
+            TextFormat.Merge("optional_string: \"" + longText + "\"", builder);
+            Assert.AreEqual(longText, builder.OptionalString);
+        }
+    }
+}

+ 433 - 400
src/ProtocolBuffers.Test/UnknownFieldSetTest.cs

@@ -1,400 +1,433 @@
-#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.Descriptors;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class UnknownFieldSetTest {
-
-    private MessageDescriptor descriptor;
-    private TestAllTypes allFields;
-    private ByteString allFieldsData;
-
-    /// <summary>
-    /// An empty message that has been parsed from allFieldsData.  So, it has
-    /// unknown fields of every type.
-    /// </summary>
-    private TestEmptyMessage emptyMessage;
-    private UnknownFieldSet unknownFields;
-
-    [SetUp]
-    public void SetUp() {
-      descriptor = TestAllTypes.Descriptor;
-      allFields = TestUtil.GetAllSet();
-      allFieldsData = allFields.ToByteString();
-      emptyMessage = TestEmptyMessage.ParseFrom(allFieldsData);
-      unknownFields = emptyMessage.UnknownFields;
-    }
-
-    private UnknownField GetField(String name) {
-      FieldDescriptor field = descriptor.FindDescriptor<FieldDescriptor>(name);
-      Assert.IsNotNull(field);
-      return unknownFields.FieldDictionary[field.FieldNumber];
-    }
-
-    /// <summary>
-    /// Constructs a protocol buffer which contains fields with all the same
-    /// numbers as allFieldsData except that each field is some other wire
-    /// type.
-    /// </summary>
-    private ByteString GetBizarroData() {
-      UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.CreateBuilder();
-
-      UnknownField varintField = UnknownField.CreateBuilder().AddVarint(1).Build();
-      UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build();
-
-      foreach (KeyValuePair<int, UnknownField> entry in unknownFields.FieldDictionary) {
-        if (entry.Value.VarintList.Count == 0) {
-          // Original field is not a varint, so use a varint.
-          bizarroFields.AddField(entry.Key, varintField);
-        } else {
-          // Original field *is* a varint, so use something else.
-          bizarroFields.AddField(entry.Key, fixed32Field);
-        }
-      }
-
-      return bizarroFields.Build().ToByteString();
-    }
-
-    // =================================================================
-
-    [Test]
-    public void Varint() {
-      UnknownField field = GetField("optional_int32");
-      Assert.AreEqual(1, field.VarintList.Count);
-      Assert.AreEqual(allFields.OptionalInt32, (long) field.VarintList[0]);
-    }
-
-    [Test]
-    public void Fixed32() {
-      UnknownField field = GetField("optional_fixed32");
-      Assert.AreEqual(1, field.Fixed32List.Count);
-      Assert.AreEqual(allFields.OptionalFixed32, (int) field.Fixed32List[0]);
-    }
-
-    [Test]
-    public void Fixed64() {
-      UnknownField field = GetField("optional_fixed64");
-      Assert.AreEqual(1, field.Fixed64List.Count);
-      Assert.AreEqual(allFields.OptionalFixed64, (long) field.Fixed64List[0]);
-    }
-
-    [Test]
-    public void LengthDelimited() {
-      UnknownField field = GetField("optional_bytes");
-      Assert.AreEqual(1, field.LengthDelimitedList.Count);
-      Assert.AreEqual(allFields.OptionalBytes, field.LengthDelimitedList[0]);
-    }
-
-    [Test]
-    public void Group() {
-      FieldDescriptor nestedFieldDescriptor =
-        TestAllTypes.Types.OptionalGroup.Descriptor.FindDescriptor<FieldDescriptor>("a");
-      Assert.IsNotNull(nestedFieldDescriptor);
-
-      UnknownField field = GetField("optionalgroup");
-      Assert.AreEqual(1, field.GroupList.Count);
-
-      UnknownFieldSet group = field.GroupList[0];
-      Assert.AreEqual(1, group.FieldDictionary.Count);
-      Assert.IsTrue(group.HasField(nestedFieldDescriptor.FieldNumber));
-
-      UnknownField nestedField = group[nestedFieldDescriptor.FieldNumber];
-      Assert.AreEqual(1, nestedField.VarintList.Count);
-      Assert.AreEqual(allFields.OptionalGroup.A, (long) nestedField.VarintList[0]);
-    }
-
-    [Test]
-    public void Serialize() {
-      // Check that serializing the UnknownFieldSet produces the original data again.
-      ByteString data = emptyMessage.ToByteString();
-      Assert.AreEqual(allFieldsData, data);
-    }
-
-    [Test]
-    public void CopyFrom() {
-      TestEmptyMessage message =
-        TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Build();
-
-      Assert.AreEqual(emptyMessage.ToString(), message.ToString());
-    }
-
-    [Test]
-    public void MergeFrom() {
-      TestEmptyMessage source =
-        TestEmptyMessage.CreateBuilder()
-          .SetUnknownFields(
-            UnknownFieldSet.CreateBuilder()
-              .AddField(2,
-                UnknownField.CreateBuilder()
-                  .AddVarint(2).Build())
-              .AddField(3,
-                UnknownField.CreateBuilder()
-                  .AddVarint(4).Build())
-              .Build())
-          .Build();
-      TestEmptyMessage destination =
-        TestEmptyMessage.CreateBuilder()
-          .SetUnknownFields(
-            UnknownFieldSet.CreateBuilder()
-              .AddField(1,
-                UnknownField.CreateBuilder()
-                  .AddVarint(1).Build())
-              .AddField(3,
-                UnknownField.CreateBuilder()
-                  .AddVarint(3).Build())
-              .Build())
-          .MergeFrom(source)
-          .Build();
-
-      Assert.AreEqual(
-        "1: 1\n" +
-        "2: 2\n" +
-        "3: 3\n" +
-        "3: 4\n",
-        destination.ToString());
-    }
-
-    [Test]
-    public void Clear() {
-      UnknownFieldSet fields =
-        UnknownFieldSet.CreateBuilder().MergeFrom(unknownFields).Clear().Build();
-      Assert.AreEqual(0, fields.FieldDictionary.Count);
-    }
-
-    [Test]
-    public void ClearMessage() {
-      TestEmptyMessage message =
-        TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Clear().Build();
-      Assert.AreEqual(0, message.SerializedSize);
-    }
-
-    [Test]
-    public void ParseKnownAndUnknown() {
-      // Test mixing known and unknown fields when parsing.
-
-      UnknownFieldSet fields =
-        UnknownFieldSet.CreateBuilder(unknownFields)
-          .AddField(123456,
-            UnknownField.CreateBuilder().AddVarint(654321).Build())
-          .Build();
-
-      ByteString data = fields.ToByteString();
-      TestAllTypes destination = TestAllTypes.ParseFrom(data);
-
-      TestUtil.AssertAllFieldsSet(destination);
-      Assert.AreEqual(1, destination.UnknownFields.FieldDictionary.Count);
-
-      UnknownField field = destination.UnknownFields[123456];
-      Assert.AreEqual(1, field.VarintList.Count);
-      Assert.AreEqual(654321, (long) field.VarintList[0]);
-    }
-
-    [Test]
-    public void WrongTypeTreatedAsUnknown() {
-      // Test that fields of the wrong wire type are treated like unknown fields
-      // when parsing.
-
-      ByteString bizarroData = GetBizarroData();
-      TestAllTypes allTypesMessage = TestAllTypes.ParseFrom(bizarroData);
-      TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData);
-
-      // All fields should have been interpreted as unknown, so the debug strings
-      // should be the same.
-      Assert.AreEqual(emptyMessage.ToString(), allTypesMessage.ToString());
-    }
-
-    [Test]
-    public void UnknownExtensions() {
-      // Make sure fields are properly parsed to the UnknownFieldSet even when
-      // they are declared as extension numbers.
-
-      TestEmptyMessageWithExtensions message =
-        TestEmptyMessageWithExtensions.ParseFrom(allFieldsData);
-
-      Assert.AreEqual(unknownFields.FieldDictionary.Count, 
-                   message.UnknownFields.FieldDictionary.Count);
-      Assert.AreEqual(allFieldsData, message.ToByteString());
-    }
-
-    [Test]
-    public void WrongExtensionTypeTreatedAsUnknown() {
-      // Test that fields of the wrong wire type are treated like unknown fields
-      // when parsing extensions.
-
-      ByteString bizarroData = GetBizarroData();
-      TestAllExtensions allExtensionsMessage = TestAllExtensions.ParseFrom(bizarroData);
-      TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData);
-
-      // All fields should have been interpreted as unknown, so the debug strings
-      // should be the same.
-      Assert.AreEqual(emptyMessage.ToString(),
-                   allExtensionsMessage.ToString());
-    }
-
-    [Test]
-    public void ParseUnknownEnumValue() {
-      FieldDescriptor singularField = TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_nested_enum");
-      FieldDescriptor repeatedField = TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_nested_enum");
-      Assert.IsNotNull(singularField);
-      Assert.IsNotNull(repeatedField);
-
-      ByteString data =
-        UnknownFieldSet.CreateBuilder()
-          .AddField(singularField.FieldNumber,
-            UnknownField.CreateBuilder()
-              .AddVarint((int) TestAllTypes.Types.NestedEnum.BAR)
-              .AddVarint(5)   // not valid
-              .Build())
-          .AddField(repeatedField.FieldNumber,
-            UnknownField.CreateBuilder()
-              .AddVarint((int) TestAllTypes.Types.NestedEnum.FOO)
-              .AddVarint(4)   // not valid
-              .AddVarint((int) TestAllTypes.Types.NestedEnum.BAZ)
-              .AddVarint(6)   // not valid
-              .Build())
-          .Build()
-          .ToByteString();
-
-      {
-        TestAllTypes message = TestAllTypes.ParseFrom(data);
-        Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
-                     message.OptionalNestedEnum);
-        TestUtil.AssertEqual(new [] {TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ},
-            message.RepeatedNestedEnumList);
-        TestUtil.AssertEqual(new[] {5UL}, message.UnknownFields[singularField.FieldNumber].VarintList);
-        TestUtil.AssertEqual(new[] {4UL, 6UL}, message.UnknownFields[repeatedField.FieldNumber].VarintList);
-      }
-
-      {
-        TestAllExtensions message =
-          TestAllExtensions.ParseFrom(data, TestUtil.CreateExtensionRegistry());
-        Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
-          message.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
-        TestUtil.AssertEqual(new[] { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ },
-          message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension));
-        TestUtil.AssertEqual(new[] { 5UL }, message.UnknownFields[singularField.FieldNumber].VarintList);
-        TestUtil.AssertEqual(new[] { 4UL, 6UL }, message.UnknownFields[repeatedField.FieldNumber].VarintList);
-      }
-    }
-
-    [Test]
-    public void LargeVarint() {
-      ByteString data =
-        UnknownFieldSet.CreateBuilder()
-          .AddField(1,
-            UnknownField.CreateBuilder()
-              .AddVarint(0x7FFFFFFFFFFFFFFFL)
-              .Build())
-          .Build()
-          .ToByteString();
-      UnknownFieldSet parsed = UnknownFieldSet.ParseFrom(data);
-      UnknownField field = parsed[1];
-      Assert.AreEqual(1, field.VarintList.Count);
-      Assert.AreEqual(0x7FFFFFFFFFFFFFFFUL, field.VarintList[0]);
-    }
-
-    [Test]
-    public void EqualsAndHashCode() {
-      UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build();
-      UnknownField fixed64Field = UnknownField.CreateBuilder().AddFixed64(1).Build();
-      UnknownField varIntField = UnknownField.CreateBuilder().AddVarint(1).Build();
-      UnknownField lengthDelimitedField = UnknownField.CreateBuilder().AddLengthDelimited(ByteString.Empty).Build();
-      UnknownField groupField = UnknownField.CreateBuilder().AddGroup(unknownFields).Build();
-
-      UnknownFieldSet a = UnknownFieldSet.CreateBuilder().AddField(1, fixed32Field).Build();
-      UnknownFieldSet b = UnknownFieldSet.CreateBuilder().AddField(1, fixed64Field).Build();
-      UnknownFieldSet c = UnknownFieldSet.CreateBuilder().AddField(1, varIntField).Build();
-      UnknownFieldSet d = UnknownFieldSet.CreateBuilder().AddField(1, lengthDelimitedField).Build();
-      UnknownFieldSet e = UnknownFieldSet.CreateBuilder().AddField(1, groupField).Build();
-
-      CheckEqualsIsConsistent(a);
-      CheckEqualsIsConsistent(b);
-      CheckEqualsIsConsistent(c);
-      CheckEqualsIsConsistent(d);
-      CheckEqualsIsConsistent(e);
-
-      CheckNotEqual(a, b);
-      CheckNotEqual(a, c);
-      CheckNotEqual(a, d);
-      CheckNotEqual(a, e);
-      CheckNotEqual(b, c);
-      CheckNotEqual(b, d);
-      CheckNotEqual(b, e);
-      CheckNotEqual(c, d);
-      CheckNotEqual(c, e);
-      CheckNotEqual(d, e);
-    }
-
-    /// <summary>
-    /// Asserts that the given field sets are not equal and have different
-    /// hash codes.
-    /// </summary>
-    /// <remarks>
-    /// It's valid for non-equal objects to have the same hash code, so
-    /// this test is stricter than it needs to be. However, this should happen
-    /// relatively rarely.
-    /// </remarks>
-    /// <param name="s1"></param>
-    /// <param name="s2"></param>
-    private static void CheckNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) {
-      String equalsError = string.Format("{0} should not be equal to {1}", s1, s2);
-      Assert.IsFalse(s1.Equals(s2), equalsError);
-      Assert.IsFalse(s2.Equals(s1), equalsError);
-
-      Assert.IsFalse(s1.GetHashCode() == s2.GetHashCode(),
-          string.Format("{0} should have a different hash code from {1}", s1, s2));
-          
-    }
-
-    /**
-     * Asserts that the given field sets are equal and have identical hash codes.
-     */
-    private static void CheckEqualsIsConsistent(UnknownFieldSet set) {
-      // Object should be equal to itself.
-      Assert.AreEqual(set, set);
-
-      // Object should be equal to a copy of itself.
-      UnknownFieldSet copy = UnknownFieldSet.CreateBuilder(set).Build();
-      Assert.AreEqual(set, copy);
-      Assert.AreEqual(copy, set);
-      Assert.AreEqual(set.GetHashCode(), copy.GetHashCode());
-    }
-  }
-}
+#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.Descriptors;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class UnknownFieldSetTest
+    {
+        private MessageDescriptor descriptor;
+        private TestAllTypes allFields;
+        private ByteString allFieldsData;
+
+        /// <summary>
+        /// An empty message that has been parsed from allFieldsData.  So, it has
+        /// unknown fields of every type.
+        /// </summary>
+        private TestEmptyMessage emptyMessage;
+
+        private UnknownFieldSet unknownFields;
+
+        [SetUp]
+        public void SetUp()
+        {
+            descriptor = TestAllTypes.Descriptor;
+            allFields = TestUtil.GetAllSet();
+            allFieldsData = allFields.ToByteString();
+            emptyMessage = TestEmptyMessage.ParseFrom(allFieldsData);
+            unknownFields = emptyMessage.UnknownFields;
+        }
+
+        private UnknownField GetField(String name)
+        {
+            FieldDescriptor field = descriptor.FindDescriptor<FieldDescriptor>(name);
+            Assert.IsNotNull(field);
+            return unknownFields.FieldDictionary[field.FieldNumber];
+        }
+
+        /// <summary>
+        /// Constructs a protocol buffer which contains fields with all the same
+        /// numbers as allFieldsData except that each field is some other wire
+        /// type.
+        /// </summary>
+        private ByteString GetBizarroData()
+        {
+            UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.CreateBuilder();
+
+            UnknownField varintField = UnknownField.CreateBuilder().AddVarint(1).Build();
+            UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build();
+
+            foreach (KeyValuePair<int, UnknownField> entry in unknownFields.FieldDictionary)
+            {
+                if (entry.Value.VarintList.Count == 0)
+                {
+                    // Original field is not a varint, so use a varint.
+                    bizarroFields.AddField(entry.Key, varintField);
+                }
+                else
+                {
+                    // Original field *is* a varint, so use something else.
+                    bizarroFields.AddField(entry.Key, fixed32Field);
+                }
+            }
+
+            return bizarroFields.Build().ToByteString();
+        }
+
+        // =================================================================
+
+        [Test]
+        public void Varint()
+        {
+            UnknownField field = GetField("optional_int32");
+            Assert.AreEqual(1, field.VarintList.Count);
+            Assert.AreEqual(allFields.OptionalInt32, (long) field.VarintList[0]);
+        }
+
+        [Test]
+        public void Fixed32()
+        {
+            UnknownField field = GetField("optional_fixed32");
+            Assert.AreEqual(1, field.Fixed32List.Count);
+            Assert.AreEqual(allFields.OptionalFixed32, (int) field.Fixed32List[0]);
+        }
+
+        [Test]
+        public void Fixed64()
+        {
+            UnknownField field = GetField("optional_fixed64");
+            Assert.AreEqual(1, field.Fixed64List.Count);
+            Assert.AreEqual(allFields.OptionalFixed64, (long) field.Fixed64List[0]);
+        }
+
+        [Test]
+        public void LengthDelimited()
+        {
+            UnknownField field = GetField("optional_bytes");
+            Assert.AreEqual(1, field.LengthDelimitedList.Count);
+            Assert.AreEqual(allFields.OptionalBytes, field.LengthDelimitedList[0]);
+        }
+
+        [Test]
+        public void Group()
+        {
+            FieldDescriptor nestedFieldDescriptor =
+                TestAllTypes.Types.OptionalGroup.Descriptor.FindDescriptor<FieldDescriptor>("a");
+            Assert.IsNotNull(nestedFieldDescriptor);
+
+            UnknownField field = GetField("optionalgroup");
+            Assert.AreEqual(1, field.GroupList.Count);
+
+            UnknownFieldSet group = field.GroupList[0];
+            Assert.AreEqual(1, group.FieldDictionary.Count);
+            Assert.IsTrue(group.HasField(nestedFieldDescriptor.FieldNumber));
+
+            UnknownField nestedField = group[nestedFieldDescriptor.FieldNumber];
+            Assert.AreEqual(1, nestedField.VarintList.Count);
+            Assert.AreEqual(allFields.OptionalGroup.A, (long) nestedField.VarintList[0]);
+        }
+
+        [Test]
+        public void Serialize()
+        {
+            // Check that serializing the UnknownFieldSet produces the original data again.
+            ByteString data = emptyMessage.ToByteString();
+            Assert.AreEqual(allFieldsData, data);
+        }
+
+        [Test]
+        public void CopyFrom()
+        {
+            TestEmptyMessage message =
+                TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Build();
+
+            Assert.AreEqual(emptyMessage.ToString(), message.ToString());
+        }
+
+        [Test]
+        public void MergeFrom()
+        {
+            TestEmptyMessage source =
+                TestEmptyMessage.CreateBuilder()
+                    .SetUnknownFields(
+                        UnknownFieldSet.CreateBuilder()
+                            .AddField(2,
+                                      UnknownField.CreateBuilder()
+                                          .AddVarint(2).Build())
+                            .AddField(3,
+                                      UnknownField.CreateBuilder()
+                                          .AddVarint(4).Build())
+                            .Build())
+                    .Build();
+            TestEmptyMessage destination =
+                TestEmptyMessage.CreateBuilder()
+                    .SetUnknownFields(
+                        UnknownFieldSet.CreateBuilder()
+                            .AddField(1,
+                                      UnknownField.CreateBuilder()
+                                          .AddVarint(1).Build())
+                            .AddField(3,
+                                      UnknownField.CreateBuilder()
+                                          .AddVarint(3).Build())
+                            .Build())
+                    .MergeFrom(source)
+                    .Build();
+
+            Assert.AreEqual(
+                "1: 1\n" +
+                "2: 2\n" +
+                "3: 3\n" +
+                "3: 4\n",
+                destination.ToString());
+        }
+
+        [Test]
+        public void Clear()
+        {
+            UnknownFieldSet fields =
+                UnknownFieldSet.CreateBuilder().MergeFrom(unknownFields).Clear().Build();
+            Assert.AreEqual(0, fields.FieldDictionary.Count);
+        }
+
+        [Test]
+        public void ClearMessage()
+        {
+            TestEmptyMessage message =
+                TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Clear().Build();
+            Assert.AreEqual(0, message.SerializedSize);
+        }
+
+        [Test]
+        public void ParseKnownAndUnknown()
+        {
+            // Test mixing known and unknown fields when parsing.
+
+            UnknownFieldSet fields =
+                UnknownFieldSet.CreateBuilder(unknownFields)
+                    .AddField(123456,
+                              UnknownField.CreateBuilder().AddVarint(654321).Build())
+                    .Build();
+
+            ByteString data = fields.ToByteString();
+            TestAllTypes destination = TestAllTypes.ParseFrom(data);
+
+            TestUtil.AssertAllFieldsSet(destination);
+            Assert.AreEqual(1, destination.UnknownFields.FieldDictionary.Count);
+
+            UnknownField field = destination.UnknownFields[123456];
+            Assert.AreEqual(1, field.VarintList.Count);
+            Assert.AreEqual(654321, (long) field.VarintList[0]);
+        }
+
+        [Test]
+        public void WrongTypeTreatedAsUnknown()
+        {
+            // Test that fields of the wrong wire type are treated like unknown fields
+            // when parsing.
+
+            ByteString bizarroData = GetBizarroData();
+            TestAllTypes allTypesMessage = TestAllTypes.ParseFrom(bizarroData);
+            TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData);
+
+            // All fields should have been interpreted as unknown, so the debug strings
+            // should be the same.
+            Assert.AreEqual(emptyMessage.ToString(), allTypesMessage.ToString());
+        }
+
+        [Test]
+        public void UnknownExtensions()
+        {
+            // Make sure fields are properly parsed to the UnknownFieldSet even when
+            // they are declared as extension numbers.
+
+            TestEmptyMessageWithExtensions message =
+                TestEmptyMessageWithExtensions.ParseFrom(allFieldsData);
+
+            Assert.AreEqual(unknownFields.FieldDictionary.Count,
+                            message.UnknownFields.FieldDictionary.Count);
+            Assert.AreEqual(allFieldsData, message.ToByteString());
+        }
+
+        [Test]
+        public void WrongExtensionTypeTreatedAsUnknown()
+        {
+            // Test that fields of the wrong wire type are treated like unknown fields
+            // when parsing extensions.
+
+            ByteString bizarroData = GetBizarroData();
+            TestAllExtensions allExtensionsMessage = TestAllExtensions.ParseFrom(bizarroData);
+            TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData);
+
+            // All fields should have been interpreted as unknown, so the debug strings
+            // should be the same.
+            Assert.AreEqual(emptyMessage.ToString(),
+                            allExtensionsMessage.ToString());
+        }
+
+        [Test]
+        public void ParseUnknownEnumValue()
+        {
+            FieldDescriptor singularField =
+                TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_nested_enum");
+            FieldDescriptor repeatedField =
+                TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_nested_enum");
+            Assert.IsNotNull(singularField);
+            Assert.IsNotNull(repeatedField);
+
+            ByteString data =
+                UnknownFieldSet.CreateBuilder()
+                    .AddField(singularField.FieldNumber,
+                              UnknownField.CreateBuilder()
+                                  .AddVarint((int) TestAllTypes.Types.NestedEnum.BAR)
+                                  .AddVarint(5) // not valid
+                                  .Build())
+                    .AddField(repeatedField.FieldNumber,
+                              UnknownField.CreateBuilder()
+                                  .AddVarint((int) TestAllTypes.Types.NestedEnum.FOO)
+                                  .AddVarint(4) // not valid
+                                  .AddVarint((int) TestAllTypes.Types.NestedEnum.BAZ)
+                                  .AddVarint(6) // not valid
+                                  .Build())
+                    .Build()
+                    .ToByteString();
+
+            {
+                TestAllTypes message = TestAllTypes.ParseFrom(data);
+                Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
+                                message.OptionalNestedEnum);
+                TestUtil.AssertEqual(new[] {TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ},
+                                     message.RepeatedNestedEnumList);
+                TestUtil.AssertEqual(new[] {5UL}, message.UnknownFields[singularField.FieldNumber].VarintList);
+                TestUtil.AssertEqual(new[] {4UL, 6UL}, message.UnknownFields[repeatedField.FieldNumber].VarintList);
+            }
+
+            {
+                TestAllExtensions message =
+                    TestAllExtensions.ParseFrom(data, TestUtil.CreateExtensionRegistry());
+                Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
+                                message.GetExtension(UnitTestProtoFile.OptionalNestedEnumExtension));
+                TestUtil.AssertEqual(new[] {TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ},
+                                     message.GetExtension(UnitTestProtoFile.RepeatedNestedEnumExtension));
+                TestUtil.AssertEqual(new[] {5UL}, message.UnknownFields[singularField.FieldNumber].VarintList);
+                TestUtil.AssertEqual(new[] {4UL, 6UL}, message.UnknownFields[repeatedField.FieldNumber].VarintList);
+            }
+        }
+
+        [Test]
+        public void LargeVarint()
+        {
+            ByteString data =
+                UnknownFieldSet.CreateBuilder()
+                    .AddField(1,
+                              UnknownField.CreateBuilder()
+                                  .AddVarint(0x7FFFFFFFFFFFFFFFL)
+                                  .Build())
+                    .Build()
+                    .ToByteString();
+            UnknownFieldSet parsed = UnknownFieldSet.ParseFrom(data);
+            UnknownField field = parsed[1];
+            Assert.AreEqual(1, field.VarintList.Count);
+            Assert.AreEqual(0x7FFFFFFFFFFFFFFFUL, field.VarintList[0]);
+        }
+
+        [Test]
+        public void EqualsAndHashCode()
+        {
+            UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build();
+            UnknownField fixed64Field = UnknownField.CreateBuilder().AddFixed64(1).Build();
+            UnknownField varIntField = UnknownField.CreateBuilder().AddVarint(1).Build();
+            UnknownField lengthDelimitedField =
+                UnknownField.CreateBuilder().AddLengthDelimited(ByteString.Empty).Build();
+            UnknownField groupField = UnknownField.CreateBuilder().AddGroup(unknownFields).Build();
+
+            UnknownFieldSet a = UnknownFieldSet.CreateBuilder().AddField(1, fixed32Field).Build();
+            UnknownFieldSet b = UnknownFieldSet.CreateBuilder().AddField(1, fixed64Field).Build();
+            UnknownFieldSet c = UnknownFieldSet.CreateBuilder().AddField(1, varIntField).Build();
+            UnknownFieldSet d = UnknownFieldSet.CreateBuilder().AddField(1, lengthDelimitedField).Build();
+            UnknownFieldSet e = UnknownFieldSet.CreateBuilder().AddField(1, groupField).Build();
+
+            CheckEqualsIsConsistent(a);
+            CheckEqualsIsConsistent(b);
+            CheckEqualsIsConsistent(c);
+            CheckEqualsIsConsistent(d);
+            CheckEqualsIsConsistent(e);
+
+            CheckNotEqual(a, b);
+            CheckNotEqual(a, c);
+            CheckNotEqual(a, d);
+            CheckNotEqual(a, e);
+            CheckNotEqual(b, c);
+            CheckNotEqual(b, d);
+            CheckNotEqual(b, e);
+            CheckNotEqual(c, d);
+            CheckNotEqual(c, e);
+            CheckNotEqual(d, e);
+        }
+
+        /// <summary>
+        /// Asserts that the given field sets are not equal and have different
+        /// hash codes.
+        /// </summary>
+        /// <remarks>
+        /// It's valid for non-equal objects to have the same hash code, so
+        /// this test is stricter than it needs to be. However, this should happen
+        /// relatively rarely.
+        /// </remarks>
+        /// <param name="s1"></param>
+        /// <param name="s2"></param>
+        private static void CheckNotEqual(UnknownFieldSet s1, UnknownFieldSet s2)
+        {
+            String equalsError = string.Format("{0} should not be equal to {1}", s1, s2);
+            Assert.IsFalse(s1.Equals(s2), equalsError);
+            Assert.IsFalse(s2.Equals(s1), equalsError);
+
+            Assert.IsFalse(s1.GetHashCode() == s2.GetHashCode(),
+                           string.Format("{0} should have a different hash code from {1}", s1, s2));
+        }
+
+        /**
+     * Asserts that the given field sets are equal and have identical hash codes.
+     */
+
+        private static void CheckEqualsIsConsistent(UnknownFieldSet set)
+        {
+            // Object should be equal to itself.
+            Assert.AreEqual(set, set);
+
+            // Object should be equal to a copy of itself.
+            UnknownFieldSet copy = UnknownFieldSet.CreateBuilder(set).Build();
+            Assert.AreEqual(set, copy);
+            Assert.AreEqual(copy, set);
+            Assert.AreEqual(set.GetHashCode(), copy.GetHashCode());
+        }
+    }
+}

+ 316 - 297
src/ProtocolBuffers.Test/WireFormatTest.cs

@@ -1,297 +1,316 @@
-#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 System.Reflection;
-using Google.ProtocolBuffers.Descriptors;
-using Google.ProtocolBuffers.TestProtos;
-using NUnit.Framework;
-
-namespace Google.ProtocolBuffers {
-  [TestFixture]
-  public class WireFormatTest {
-
-    /// <summary>
-    /// Keeps the attributes on FieldType and the switch statement in WireFormat in sync.
-    /// </summary>
-    [Test]
-    public void FieldTypeToWireTypeMapping() {
-      foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public)) {
-        FieldType fieldType = (FieldType)field.GetValue(null);
-        FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0];
-        Assert.AreEqual(mapping.WireType, WireFormat.GetWireType(fieldType));
-      }
-    }
-
-    [Test]
-    public void Serialization() {
-      TestAllTypes message = TestUtil.GetAllSet();
-
-      ByteString rawBytes = message.ToByteString();
-      Assert.AreEqual(rawBytes.Length, message.SerializedSize);
-
-      TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
-
-      TestUtil.AssertAllFieldsSet(message2);
-    }
-
-    [Test]
-    public void SerializationPacked() {
-      TestPackedTypes message = TestUtil.GetPackedSet();
-      ByteString rawBytes = message.ToByteString();
-      Assert.AreEqual(rawBytes.Length, message.SerializedSize);
-      TestPackedTypes message2 = TestPackedTypes.ParseFrom(rawBytes);
-      TestUtil.AssertPackedFieldsSet(message2);
-    }
-
-    [Test]
-    public void SerializeExtensions() {
-      // TestAllTypes and TestAllExtensions should have compatible wire formats,
-      // so if we serialize a TestAllExtensions then parse it as TestAllTypes
-      // it should work.
-      TestAllExtensions message = TestUtil.GetAllExtensionsSet();
-      ByteString rawBytes = message.ToByteString();
-      Assert.AreEqual(rawBytes.Length, message.SerializedSize);
-
-      TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
-
-      TestUtil.AssertAllFieldsSet(message2);
-    }
-
-    [Test]
-    public void SerializePackedExtensions() {
-      // TestPackedTypes and TestPackedExtensions should have compatible wire
-      // formats; check that they serialize to the same string.
-      TestPackedExtensions message = TestUtil.GetPackedExtensionsSet();
-      ByteString rawBytes = message.ToByteString();
-
-      TestPackedTypes message2 = TestUtil.GetPackedSet();
-      ByteString rawBytes2 = message2.ToByteString();
-
-      Assert.AreEqual(rawBytes, rawBytes2);
-    }
-
-    [Test]
-    public void SerializeDelimited() {
-      MemoryStream stream = new MemoryStream();
-      TestUtil.GetAllSet().WriteDelimitedTo(stream);
-      stream.WriteByte(12);
-      TestUtil.GetPackedSet().WriteDelimitedTo(stream);
-      stream.WriteByte(34);
-
-      stream.Position = 0;
-
-      TestUtil.AssertAllFieldsSet(TestAllTypes.ParseDelimitedFrom(stream));
-      Assert.AreEqual(12, stream.ReadByte());
-      TestUtil.AssertPackedFieldsSet(TestPackedTypes.ParseDelimitedFrom(stream));
-      Assert.AreEqual(34, stream.ReadByte());
-      Assert.AreEqual(-1, stream.ReadByte());
-    }
-
-    [Test]
-    public void ParseExtensions() {
-      // TestAllTypes and TestAllExtensions should have compatible wire formats,
-      // so if we serealize a TestAllTypes then parse it as TestAllExtensions
-      // it should work.
-
-      TestAllTypes message = TestUtil.GetAllSet();
-      ByteString rawBytes = message.ToByteString();
-
-      ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
-      TestUtil.RegisterAllExtensions(registry);
-      registry = registry.AsReadOnly();
-
-      TestAllExtensions message2 = TestAllExtensions.ParseFrom(rawBytes, registry);
-
-      TestUtil.AssertAllExtensionsSet(message2);
-    }
-
-    [Test]
-    public void ParsePackedExtensions() {
-      // Ensure that packed extensions can be properly parsed.
-      TestPackedExtensions message = TestUtil.GetPackedExtensionsSet();
-      ByteString rawBytes = message.ToByteString();
-
-      ExtensionRegistry registry = TestUtil.CreateExtensionRegistry();
-
-      TestPackedExtensions message2 = TestPackedExtensions.ParseFrom(rawBytes, registry);
-      TestUtil.AssertPackedExtensionsSet(message2);
-    }
-
-    [Test]
-    public void ExtensionsSerializedSize() {
-      Assert.AreEqual(TestUtil.GetAllSet().SerializedSize, TestUtil.GetAllExtensionsSet().SerializedSize);
-    }
-
-    private static void AssertFieldsInOrder(ByteString data) {
-      CodedInputStream input = data.CreateCodedInput();
-      uint previousTag = 0;
-
-      while (true) {
-        uint tag = input.ReadTag();
-        if (tag == 0) {
-          break;
-        }
-
-        Assert.IsTrue(tag > previousTag);
-        previousTag = tag;
-        input.SkipField(tag);
-      }
-    }
-
-    [Test]
-    public void InterleavedFieldsAndExtensions() {
-      // Tests that fields are written in order even when extension ranges
-      // are interleaved with field numbers.
-      ByteString data =
-        TestFieldOrderings.CreateBuilder()
-          .SetMyInt(1)
-          .SetMyString("foo")
-          .SetMyFloat(1.0F)
-          .SetExtension(UnitTestProtoFile.MyExtensionInt, 23)
-          .SetExtension(UnitTestProtoFile.MyExtensionString, "bar")
-          .Build().ToByteString();
-      AssertFieldsInOrder(data);
-
-      MessageDescriptor descriptor = TestFieldOrderings.Descriptor;
-      ByteString dynamic_data =
-        DynamicMessage.CreateBuilder(TestFieldOrderings.Descriptor)
-          .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_int"), 1L)
-          .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_string"), "foo")
-          .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_float"), 1.0F)
-          .SetField(UnitTestProtoFile.MyExtensionInt.Descriptor, 23)
-          .SetField(UnitTestProtoFile.MyExtensionString.Descriptor, "bar")
-          .WeakBuild().ToByteString();
-      AssertFieldsInOrder(dynamic_data);
-    }
-
-    private const int UnknownTypeId = 1550055;
-    private static readonly int TypeId1 = TestMessageSetExtension1.Descriptor.Extensions[0].FieldNumber;
-    private static readonly int TypeId2 = TestMessageSetExtension2.Descriptor.Extensions[0].FieldNumber;
-
-    [Test]
-    public void SerializeMessageSet() {
-      // Set up a TestMessageSet with two known messages and an unknown one.
-      TestMessageSet messageSet =
-        TestMessageSet.CreateBuilder()
-          .SetExtension(
-            TestMessageSetExtension1.MessageSetExtension,
-            TestMessageSetExtension1.CreateBuilder().SetI(123).Build())
-          .SetExtension(
-            TestMessageSetExtension2.MessageSetExtension,
-            TestMessageSetExtension2.CreateBuilder().SetStr("foo").Build())
-          .SetUnknownFields(
-            UnknownFieldSet.CreateBuilder()
-              .AddField(UnknownTypeId,
-                UnknownField.CreateBuilder()
-                  .AddLengthDelimited(ByteString.CopyFromUtf8("bar"))
-                  .Build())
-              .Build())
-          .Build();
-
-      ByteString data = messageSet.ToByteString();
-
-      // Parse back using RawMessageSet and check the contents.
-      RawMessageSet raw = RawMessageSet.ParseFrom(data);
-
-      Assert.AreEqual(0, raw.UnknownFields.FieldDictionary.Count);
-
-      Assert.AreEqual(3, raw.ItemCount);
-      Assert.AreEqual(TypeId1, raw.ItemList[0].TypeId);
-      Assert.AreEqual(TypeId2, raw.ItemList[1].TypeId);
-      Assert.AreEqual(UnknownTypeId, raw.ItemList[2].TypeId);
-
-      TestMessageSetExtension1 message1 = TestMessageSetExtension1.ParseFrom(raw.GetItem(0).Message.ToByteArray());
-      Assert.AreEqual(123, message1.I);
-
-      TestMessageSetExtension2 message2 = TestMessageSetExtension2.ParseFrom(raw.GetItem(1).Message.ToByteArray());
-      Assert.AreEqual("foo", message2.Str);
-
-      Assert.AreEqual("bar", raw.GetItem(2).Message.ToStringUtf8());
-    }
-     
-    [Test]
-    public void ParseMessageSet() {
-      ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
-      extensionRegistry.Add(TestMessageSetExtension1.MessageSetExtension);
-      extensionRegistry.Add(TestMessageSetExtension2.MessageSetExtension);
-
-      // Set up a RawMessageSet with two known messages and an unknown one.
-      RawMessageSet raw =
-        RawMessageSet.CreateBuilder()
-          .AddItem(
-            RawMessageSet.Types.Item.CreateBuilder()
-              .SetTypeId(TypeId1)
-              .SetMessage(
-                TestMessageSetExtension1.CreateBuilder()
-                  .SetI(123)
-                  .Build().ToByteString())
-              .Build())
-          .AddItem(
-            RawMessageSet.Types.Item.CreateBuilder()
-              .SetTypeId(TypeId2)
-              .SetMessage(
-                TestMessageSetExtension2.CreateBuilder()
-                  .SetStr("foo")
-                  .Build().ToByteString())
-              .Build())
-          .AddItem(
-            RawMessageSet.Types.Item.CreateBuilder()
-              .SetTypeId(UnknownTypeId)
-              .SetMessage(ByteString.CopyFromUtf8("bar"))
-              .Build())
-          .Build();
-
-      ByteString data = raw.ToByteString();
-
-      // Parse as a TestMessageSet and check the contents.
-      TestMessageSet messageSet =
-        TestMessageSet.ParseFrom(data, extensionRegistry);
-
-      Assert.AreEqual(123, messageSet.GetExtension(TestMessageSetExtension1.MessageSetExtension).I);
-      Assert.AreEqual("foo", messageSet.GetExtension(TestMessageSetExtension2.MessageSetExtension).Str);
-
-      // Check for unknown field with type LENGTH_DELIMITED,
-      //   number UNKNOWN_TYPE_ID, and contents "bar".
-      UnknownFieldSet unknownFields = messageSet.UnknownFields;
-      Assert.AreEqual(1, unknownFields.FieldDictionary.Count);
-      Assert.IsTrue(unknownFields.HasField(UnknownTypeId));
-
-      UnknownField field = unknownFields[UnknownTypeId];
-      Assert.AreEqual(1, field.LengthDelimitedList.Count);
-      Assert.AreEqual("bar", field.LengthDelimitedList[0].ToStringUtf8());
-    }
-
-  }
-}
+#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 System.Reflection;
+using Google.ProtocolBuffers.Descriptors;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class WireFormatTest
+    {
+        /// <summary>
+        /// Keeps the attributes on FieldType and the switch statement in WireFormat in sync.
+        /// </summary>
+        [Test]
+        public void FieldTypeToWireTypeMapping()
+        {
+            foreach (FieldInfo field in typeof (FieldType).GetFields(BindingFlags.Static | BindingFlags.Public))
+            {
+                FieldType fieldType = (FieldType) field.GetValue(null);
+                FieldMappingAttribute mapping =
+                    (FieldMappingAttribute) field.GetCustomAttributes(typeof (FieldMappingAttribute), false)[0];
+                Assert.AreEqual(mapping.WireType, WireFormat.GetWireType(fieldType));
+            }
+        }
+
+        [Test]
+        public void Serialization()
+        {
+            TestAllTypes message = TestUtil.GetAllSet();
+
+            ByteString rawBytes = message.ToByteString();
+            Assert.AreEqual(rawBytes.Length, message.SerializedSize);
+
+            TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
+
+            TestUtil.AssertAllFieldsSet(message2);
+        }
+
+        [Test]
+        public void SerializationPacked()
+        {
+            TestPackedTypes message = TestUtil.GetPackedSet();
+            ByteString rawBytes = message.ToByteString();
+            Assert.AreEqual(rawBytes.Length, message.SerializedSize);
+            TestPackedTypes message2 = TestPackedTypes.ParseFrom(rawBytes);
+            TestUtil.AssertPackedFieldsSet(message2);
+        }
+
+        [Test]
+        public void SerializeExtensions()
+        {
+            // TestAllTypes and TestAllExtensions should have compatible wire formats,
+            // so if we serialize a TestAllExtensions then parse it as TestAllTypes
+            // it should work.
+            TestAllExtensions message = TestUtil.GetAllExtensionsSet();
+            ByteString rawBytes = message.ToByteString();
+            Assert.AreEqual(rawBytes.Length, message.SerializedSize);
+
+            TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
+
+            TestUtil.AssertAllFieldsSet(message2);
+        }
+
+        [Test]
+        public void SerializePackedExtensions()
+        {
+            // TestPackedTypes and TestPackedExtensions should have compatible wire
+            // formats; check that they serialize to the same string.
+            TestPackedExtensions message = TestUtil.GetPackedExtensionsSet();
+            ByteString rawBytes = message.ToByteString();
+
+            TestPackedTypes message2 = TestUtil.GetPackedSet();
+            ByteString rawBytes2 = message2.ToByteString();
+
+            Assert.AreEqual(rawBytes, rawBytes2);
+        }
+
+        [Test]
+        public void SerializeDelimited()
+        {
+            MemoryStream stream = new MemoryStream();
+            TestUtil.GetAllSet().WriteDelimitedTo(stream);
+            stream.WriteByte(12);
+            TestUtil.GetPackedSet().WriteDelimitedTo(stream);
+            stream.WriteByte(34);
+
+            stream.Position = 0;
+
+            TestUtil.AssertAllFieldsSet(TestAllTypes.ParseDelimitedFrom(stream));
+            Assert.AreEqual(12, stream.ReadByte());
+            TestUtil.AssertPackedFieldsSet(TestPackedTypes.ParseDelimitedFrom(stream));
+            Assert.AreEqual(34, stream.ReadByte());
+            Assert.AreEqual(-1, stream.ReadByte());
+        }
+
+        [Test]
+        public void ParseExtensions()
+        {
+            // TestAllTypes and TestAllExtensions should have compatible wire formats,
+            // so if we serealize a TestAllTypes then parse it as TestAllExtensions
+            // it should work.
+
+            TestAllTypes message = TestUtil.GetAllSet();
+            ByteString rawBytes = message.ToByteString();
+
+            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+            TestUtil.RegisterAllExtensions(registry);
+            registry = registry.AsReadOnly();
+
+            TestAllExtensions message2 = TestAllExtensions.ParseFrom(rawBytes, registry);
+
+            TestUtil.AssertAllExtensionsSet(message2);
+        }
+
+        [Test]
+        public void ParsePackedExtensions()
+        {
+            // Ensure that packed extensions can be properly parsed.
+            TestPackedExtensions message = TestUtil.GetPackedExtensionsSet();
+            ByteString rawBytes = message.ToByteString();
+
+            ExtensionRegistry registry = TestUtil.CreateExtensionRegistry();
+
+            TestPackedExtensions message2 = TestPackedExtensions.ParseFrom(rawBytes, registry);
+            TestUtil.AssertPackedExtensionsSet(message2);
+        }
+
+        [Test]
+        public void ExtensionsSerializedSize()
+        {
+            Assert.AreEqual(TestUtil.GetAllSet().SerializedSize, TestUtil.GetAllExtensionsSet().SerializedSize);
+        }
+
+        private static void AssertFieldsInOrder(ByteString data)
+        {
+            CodedInputStream input = data.CreateCodedInput();
+            uint previousTag = 0;
+
+            while (true)
+            {
+                uint tag = input.ReadTag();
+                if (tag == 0)
+                {
+                    break;
+                }
+
+                Assert.IsTrue(tag > previousTag);
+                previousTag = tag;
+                input.SkipField(tag);
+            }
+        }
+
+        [Test]
+        public void InterleavedFieldsAndExtensions()
+        {
+            // Tests that fields are written in order even when extension ranges
+            // are interleaved with field numbers.
+            ByteString data =
+                TestFieldOrderings.CreateBuilder()
+                    .SetMyInt(1)
+                    .SetMyString("foo")
+                    .SetMyFloat(1.0F)
+                    .SetExtension(UnitTestProtoFile.MyExtensionInt, 23)
+                    .SetExtension(UnitTestProtoFile.MyExtensionString, "bar")
+                    .Build().ToByteString();
+            AssertFieldsInOrder(data);
+
+            MessageDescriptor descriptor = TestFieldOrderings.Descriptor;
+            ByteString dynamic_data =
+                DynamicMessage.CreateBuilder(TestFieldOrderings.Descriptor)
+                    .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_int"), 1L)
+                    .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_string"), "foo")
+                    .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_float"), 1.0F)
+                    .SetField(UnitTestProtoFile.MyExtensionInt.Descriptor, 23)
+                    .SetField(UnitTestProtoFile.MyExtensionString.Descriptor, "bar")
+                    .WeakBuild().ToByteString();
+            AssertFieldsInOrder(dynamic_data);
+        }
+
+        private const int UnknownTypeId = 1550055;
+        private static readonly int TypeId1 = TestMessageSetExtension1.Descriptor.Extensions[0].FieldNumber;
+        private static readonly int TypeId2 = TestMessageSetExtension2.Descriptor.Extensions[0].FieldNumber;
+
+        [Test]
+        public void SerializeMessageSet()
+        {
+            // Set up a TestMessageSet with two known messages and an unknown one.
+            TestMessageSet messageSet =
+                TestMessageSet.CreateBuilder()
+                    .SetExtension(
+                        TestMessageSetExtension1.MessageSetExtension,
+                        TestMessageSetExtension1.CreateBuilder().SetI(123).Build())
+                    .SetExtension(
+                        TestMessageSetExtension2.MessageSetExtension,
+                        TestMessageSetExtension2.CreateBuilder().SetStr("foo").Build())
+                    .SetUnknownFields(
+                        UnknownFieldSet.CreateBuilder()
+                            .AddField(UnknownTypeId,
+                                      UnknownField.CreateBuilder()
+                                          .AddLengthDelimited(ByteString.CopyFromUtf8("bar"))
+                                          .Build())
+                            .Build())
+                    .Build();
+
+            ByteString data = messageSet.ToByteString();
+
+            // Parse back using RawMessageSet and check the contents.
+            RawMessageSet raw = RawMessageSet.ParseFrom(data);
+
+            Assert.AreEqual(0, raw.UnknownFields.FieldDictionary.Count);
+
+            Assert.AreEqual(3, raw.ItemCount);
+            Assert.AreEqual(TypeId1, raw.ItemList[0].TypeId);
+            Assert.AreEqual(TypeId2, raw.ItemList[1].TypeId);
+            Assert.AreEqual(UnknownTypeId, raw.ItemList[2].TypeId);
+
+            TestMessageSetExtension1 message1 = TestMessageSetExtension1.ParseFrom(raw.GetItem(0).Message.ToByteArray());
+            Assert.AreEqual(123, message1.I);
+
+            TestMessageSetExtension2 message2 = TestMessageSetExtension2.ParseFrom(raw.GetItem(1).Message.ToByteArray());
+            Assert.AreEqual("foo", message2.Str);
+
+            Assert.AreEqual("bar", raw.GetItem(2).Message.ToStringUtf8());
+        }
+
+        [Test]
+        public void ParseMessageSet()
+        {
+            ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
+            extensionRegistry.Add(TestMessageSetExtension1.MessageSetExtension);
+            extensionRegistry.Add(TestMessageSetExtension2.MessageSetExtension);
+
+            // Set up a RawMessageSet with two known messages and an unknown one.
+            RawMessageSet raw =
+                RawMessageSet.CreateBuilder()
+                    .AddItem(
+                        RawMessageSet.Types.Item.CreateBuilder()
+                            .SetTypeId(TypeId1)
+                            .SetMessage(
+                                TestMessageSetExtension1.CreateBuilder()
+                                    .SetI(123)
+                                    .Build().ToByteString())
+                            .Build())
+                    .AddItem(
+                        RawMessageSet.Types.Item.CreateBuilder()
+                            .SetTypeId(TypeId2)
+                            .SetMessage(
+                                TestMessageSetExtension2.CreateBuilder()
+                                    .SetStr("foo")
+                                    .Build().ToByteString())
+                            .Build())
+                    .AddItem(
+                        RawMessageSet.Types.Item.CreateBuilder()
+                            .SetTypeId(UnknownTypeId)
+                            .SetMessage(ByteString.CopyFromUtf8("bar"))
+                            .Build())
+                    .Build();
+
+            ByteString data = raw.ToByteString();
+
+            // Parse as a TestMessageSet and check the contents.
+            TestMessageSet messageSet =
+                TestMessageSet.ParseFrom(data, extensionRegistry);
+
+            Assert.AreEqual(123, messageSet.GetExtension(TestMessageSetExtension1.MessageSetExtension).I);
+            Assert.AreEqual("foo", messageSet.GetExtension(TestMessageSetExtension2.MessageSetExtension).Str);
+
+            // Check for unknown field with type LENGTH_DELIMITED,
+            //   number UNKNOWN_TYPE_ID, and contents "bar".
+            UnknownFieldSet unknownFields = messageSet.UnknownFields;
+            Assert.AreEqual(1, unknownFields.FieldDictionary.Count);
+            Assert.IsTrue(unknownFields.HasField(UnknownTypeId));
+
+            UnknownField field = unknownFields[UnknownTypeId];
+            Assert.AreEqual(1, field.LengthDelimitedList.Count);
+            Assert.AreEqual("bar", field.LengthDelimitedList[0].ToStringUtf8());
+        }
+    }
+}

+ 254 - 214
src/ProtocolBuffers/AbstractBuilder.cs

@@ -1,214 +1,254 @@
-#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.IO;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Implementation of the non-generic IMessage interface as far as possible.
-  /// </summary>
-  public abstract class AbstractBuilder<TMessage, TBuilder> : AbstractBuilderLite<TMessage, TBuilder>, IBuilder<TMessage, TBuilder> 
-      where TMessage : AbstractMessage<TMessage, TBuilder>
-      where TBuilder : AbstractBuilder<TMessage, TBuilder> {
-
-    #region Unimplemented members of IBuilder
-    public abstract UnknownFieldSet UnknownFields { get; set; }
-    public abstract IDictionary<FieldDescriptor, object> AllFields { get; }
-    public abstract object this[FieldDescriptor field] { get; set; }
-    public abstract MessageDescriptor DescriptorForType { get; }
-    public abstract int GetRepeatedFieldCount(FieldDescriptor field);
-    public abstract object this[FieldDescriptor field, int index] { get; set; }
-    public abstract bool HasField(FieldDescriptor field);
-    public abstract IBuilder CreateBuilderForField(FieldDescriptor field);
-    public abstract TBuilder ClearField(FieldDescriptor field);
-    public abstract TBuilder AddRepeatedField(FieldDescriptor field, object value);
-    #endregion
-
-    public TBuilder SetUnknownFields(UnknownFieldSet fields) {
-      UnknownFields = fields;
-      return ThisBuilder;
-    }
-
-    public override TBuilder Clear() {
-      foreach(FieldDescriptor field in AllFields.Keys) {
-        ClearField(field);
-      }
-      return ThisBuilder;
-    }
-
-    public sealed override TBuilder MergeFrom(IMessageLite other) {
-      if (other is IMessage) {
-        return MergeFrom((IMessage) other);
-      }
-      throw new ArgumentException("MergeFrom(Message) can only merge messages of the same type.");
-    }
-
-    /// <summary>
-    /// Merge the specified other message into the message being
-    /// built. Merging occurs as follows. For each field:
-    /// For singular primitive fields, if the field is set in <paramref name="other"/>,
-    /// then <paramref name="other"/>'s value overwrites the value in this message.
-    /// For singular message fields, if the field is set in <paramref name="other"/>,
-    /// it is merged into the corresponding sub-message of this message using the same
-    /// merging rules.
-    /// For repeated fields, the elements in <paramref name="other"/> are concatenated
-    /// with the elements in this message.
-    /// </summary>
-    /// <param name="other"></param>
-    /// <returns></returns>
-    public abstract TBuilder MergeFrom(TMessage other);
-
-    public virtual TBuilder MergeFrom(IMessage other) {
-      if (other.DescriptorForType != DescriptorForType) {
-        throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type.");
-      }
-
-      // Note:  We don't attempt to verify that other's fields have valid
-      //   types.  Doing so would be a losing battle.  We'd have to verify
-      //   all sub-messages as well, and we'd have to make copies of all of
-      //   them to insure that they don't change after verification (since
-      //   the Message interface itself cannot enforce immutability of
-      //   implementations).
-      // TODO(jonskeet):  Provide a function somewhere called MakeDeepCopy()
-      //   which allows people to make secure deep copies of messages.
-      foreach (KeyValuePair<FieldDescriptor, object> entry in other.AllFields) {
-        FieldDescriptor field = entry.Key;
-        if (field.IsRepeated) {
-          // Concatenate repeated fields
-          foreach (object element in (IEnumerable) entry.Value) {
-            AddRepeatedField(field, element);
-          }
-        } else if (field.MappedType == MappedType.Message) {
-          // Merge singular messages
-          IMessageLite existingValue = (IMessageLite)this[field];
-          if (existingValue == existingValue.WeakDefaultInstanceForType) {
-            this[field] = entry.Value;
-          } else {
-            this[field] = existingValue.WeakCreateBuilderForType()
-                                       .WeakMergeFrom(existingValue)
-                                       .WeakMergeFrom((IMessageLite)entry.Value)
-                                       .WeakBuild();
-          }
-        } else {
-          // Overwrite simple values
-          this[field] = entry.Value;
-        }
-      }
-
-      //Fix for unknown fields not merging, see java's AbstractMessage.Builder<T> line 236
-      MergeUnknownFields(other.UnknownFields);
-
-      return ThisBuilder;
-    }
-
-    public override TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
-      UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder(UnknownFields);
-      unknownFields.MergeFrom(input, extensionRegistry, this);
-      UnknownFields = unknownFields.Build();
-      return ThisBuilder;
-    }
-
-    public virtual TBuilder MergeUnknownFields(UnknownFieldSet unknownFields) {
-      UnknownFields = UnknownFieldSet.CreateBuilder(UnknownFields)
-          .MergeFrom(unknownFields)
-          .Build();
-      return ThisBuilder;
-    }
-
-    public virtual IBuilder SetField(FieldDescriptor field, object value) {
-      this[field] = value;
-      return ThisBuilder;
-    }
-
-    public virtual IBuilder SetRepeatedField(FieldDescriptor field, int index, object value) {
-      this[field, index] = value;
-      return ThisBuilder;
-	  }
-
-    #region Explicit Implementations
-
-    IMessage IBuilder.WeakBuild() {
-      return Build();
-    }
-
-    IBuilder IBuilder.WeakAddRepeatedField(FieldDescriptor field, object value) {
-      return AddRepeatedField(field, value);
-    }
-
-    IBuilder IBuilder.WeakClear() {
-      return Clear();
-    }
-
-    IBuilder IBuilder.WeakMergeFrom(IMessage message) {
-      return MergeFrom(message);
-    }
-
-    IBuilder IBuilder.WeakMergeFrom(CodedInputStream input) {
-      return MergeFrom(input);
-    }
-
-    IBuilder IBuilder.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) {
-      return MergeFrom(input, registry);
-    }
-
-    IBuilder IBuilder.WeakMergeFrom(ByteString data) {
-      return MergeFrom(data);
-    }
-
-    IBuilder IBuilder.WeakMergeFrom(ByteString data, ExtensionRegistry registry) {
-      return MergeFrom(data, registry);
-    }
-
-    IMessage IBuilder.WeakBuildPartial() {
-      return BuildPartial();
-    }
-
-    IBuilder IBuilder.WeakClone() {
-      return Clone();
-    }
-
-    IMessage IBuilder.WeakDefaultInstanceForType {
-      get { return DefaultInstanceForType; }
-    }
-
-    IBuilder IBuilder.WeakClearField(FieldDescriptor field) {
-      return ClearField(field);
-    }
-    #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;
+using System.Collections.Generic;
+using System.IO;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Implementation of the non-generic IMessage interface as far as possible.
+    /// </summary>
+    public abstract class AbstractBuilder<TMessage, TBuilder> : AbstractBuilderLite<TMessage, TBuilder>,
+                                                                IBuilder<TMessage, TBuilder>
+        where TMessage : AbstractMessage<TMessage, TBuilder>
+        where TBuilder : AbstractBuilder<TMessage, TBuilder>
+    {
+        #region Unimplemented members of IBuilder
+
+        public abstract UnknownFieldSet UnknownFields { get; set; }
+        public abstract IDictionary<FieldDescriptor, object> AllFields { get; }
+        public abstract object this[FieldDescriptor field] { get; set; }
+        public abstract MessageDescriptor DescriptorForType { get; }
+        public abstract int GetRepeatedFieldCount(FieldDescriptor field);
+        public abstract object this[FieldDescriptor field, int index] { get; set; }
+        public abstract bool HasField(FieldDescriptor field);
+        public abstract IBuilder CreateBuilderForField(FieldDescriptor field);
+        public abstract TBuilder ClearField(FieldDescriptor field);
+        public abstract TBuilder AddRepeatedField(FieldDescriptor field, object value);
+
+        #endregion
+
+        public TBuilder SetUnknownFields(UnknownFieldSet fields)
+        {
+            UnknownFields = fields;
+            return ThisBuilder;
+        }
+
+        public override TBuilder Clear()
+        {
+            foreach (FieldDescriptor field in AllFields.Keys)
+            {
+                ClearField(field);
+            }
+            return ThisBuilder;
+        }
+
+        public override sealed TBuilder MergeFrom(IMessageLite other)
+        {
+            if (other is IMessage)
+            {
+                return MergeFrom((IMessage) other);
+            }
+            throw new ArgumentException("MergeFrom(Message) can only merge messages of the same type.");
+        }
+
+        /// <summary>
+        /// Merge the specified other message into the message being
+        /// built. Merging occurs as follows. For each field:
+        /// For singular primitive fields, if the field is set in <paramref name="other"/>,
+        /// then <paramref name="other"/>'s value overwrites the value in this message.
+        /// For singular message fields, if the field is set in <paramref name="other"/>,
+        /// it is merged into the corresponding sub-message of this message using the same
+        /// merging rules.
+        /// For repeated fields, the elements in <paramref name="other"/> are concatenated
+        /// with the elements in this message.
+        /// </summary>
+        /// <param name="other"></param>
+        /// <returns></returns>
+        public abstract TBuilder MergeFrom(TMessage other);
+
+        public virtual TBuilder MergeFrom(IMessage other)
+        {
+            if (other.DescriptorForType != DescriptorForType)
+            {
+                throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type.");
+            }
+
+            // Note:  We don't attempt to verify that other's fields have valid
+            //   types.  Doing so would be a losing battle.  We'd have to verify
+            //   all sub-messages as well, and we'd have to make copies of all of
+            //   them to insure that they don't change after verification (since
+            //   the Message interface itself cannot enforce immutability of
+            //   implementations).
+            // TODO(jonskeet):  Provide a function somewhere called MakeDeepCopy()
+            //   which allows people to make secure deep copies of messages.
+            foreach (KeyValuePair<FieldDescriptor, object> entry in other.AllFields)
+            {
+                FieldDescriptor field = entry.Key;
+                if (field.IsRepeated)
+                {
+                    // Concatenate repeated fields
+                    foreach (object element in (IEnumerable) entry.Value)
+                    {
+                        AddRepeatedField(field, element);
+                    }
+                }
+                else if (field.MappedType == MappedType.Message)
+                {
+                    // Merge singular messages
+                    IMessageLite existingValue = (IMessageLite) this[field];
+                    if (existingValue == existingValue.WeakDefaultInstanceForType)
+                    {
+                        this[field] = entry.Value;
+                    }
+                    else
+                    {
+                        this[field] = existingValue.WeakCreateBuilderForType()
+                            .WeakMergeFrom(existingValue)
+                            .WeakMergeFrom((IMessageLite) entry.Value)
+                            .WeakBuild();
+                    }
+                }
+                else
+                {
+                    // Overwrite simple values
+                    this[field] = entry.Value;
+                }
+            }
+
+            //Fix for unknown fields not merging, see java's AbstractMessage.Builder<T> line 236
+            MergeUnknownFields(other.UnknownFields);
+
+            return ThisBuilder;
+        }
+
+        public override TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry)
+        {
+            UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder(UnknownFields);
+            unknownFields.MergeFrom(input, extensionRegistry, this);
+            UnknownFields = unknownFields.Build();
+            return ThisBuilder;
+        }
+
+        public virtual TBuilder MergeUnknownFields(UnknownFieldSet unknownFields)
+        {
+            UnknownFields = UnknownFieldSet.CreateBuilder(UnknownFields)
+                .MergeFrom(unknownFields)
+                .Build();
+            return ThisBuilder;
+        }
+
+        public virtual IBuilder SetField(FieldDescriptor field, object value)
+        {
+            this[field] = value;
+            return ThisBuilder;
+        }
+
+        public virtual IBuilder SetRepeatedField(FieldDescriptor field, int index, object value)
+        {
+            this[field, index] = value;
+            return ThisBuilder;
+        }
+
+        #region Explicit Implementations
+
+        IMessage IBuilder.WeakBuild()
+        {
+            return Build();
+        }
+
+        IBuilder IBuilder.WeakAddRepeatedField(FieldDescriptor field, object value)
+        {
+            return AddRepeatedField(field, value);
+        }
+
+        IBuilder IBuilder.WeakClear()
+        {
+            return Clear();
+        }
+
+        IBuilder IBuilder.WeakMergeFrom(IMessage message)
+        {
+            return MergeFrom(message);
+        }
+
+        IBuilder IBuilder.WeakMergeFrom(CodedInputStream input)
+        {
+            return MergeFrom(input);
+        }
+
+        IBuilder IBuilder.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry)
+        {
+            return MergeFrom(input, registry);
+        }
+
+        IBuilder IBuilder.WeakMergeFrom(ByteString data)
+        {
+            return MergeFrom(data);
+        }
+
+        IBuilder IBuilder.WeakMergeFrom(ByteString data, ExtensionRegistry registry)
+        {
+            return MergeFrom(data, registry);
+        }
+
+        IMessage IBuilder.WeakBuildPartial()
+        {
+            return BuildPartial();
+        }
+
+        IBuilder IBuilder.WeakClone()
+        {
+            return Clone();
+        }
+
+        IMessage IBuilder.WeakDefaultInstanceForType
+        {
+            get { return DefaultInstanceForType; }
+        }
+
+        IBuilder IBuilder.WeakClearField(FieldDescriptor field)
+        {
+            return ClearField(field);
+        }
+
+        #endregion
+    }
+}

+ 266 - 232
src/ProtocolBuffers/AbstractBuilderLite.cs

@@ -1,232 +1,266 @@
-#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.IO;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Implementation of the non-generic IMessage interface as far as possible.
-  /// </summary>
-  public abstract class AbstractBuilderLite<TMessage, TBuilder> : IBuilderLite<TMessage, TBuilder>
-    where TMessage : AbstractMessageLite<TMessage, TBuilder>
-    where TBuilder : AbstractBuilderLite<TMessage, TBuilder> {
-
-    protected abstract TBuilder ThisBuilder { get; }
-
-    public abstract bool IsInitialized { get; }
-
-    public abstract TBuilder Clear();
-
-    public abstract TBuilder Clone();
-
-    public abstract TMessage Build();
-
-    public abstract TMessage BuildPartial();
-
-    public abstract TBuilder MergeFrom(IMessageLite other);
-
-    public abstract TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry);
-
-    public abstract TMessage DefaultInstanceForType { get; }
-
-    #region IBuilderLite<TMessage,TBuilder> Members
-
-    public virtual TBuilder MergeFrom(CodedInputStream input) {
-      return MergeFrom(input, ExtensionRegistry.CreateInstance());
-    }
-
-    public TBuilder MergeDelimitedFrom(Stream input) {
-      return MergeDelimitedFrom(input, ExtensionRegistry.CreateInstance());
-    }
-
-    public TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry) {
-      int size = (int)CodedInputStream.ReadRawVarint32(input);
-      Stream limitedStream = new LimitedInputStream(input, size);
-      return MergeFrom(limitedStream, extensionRegistry);
-    }
-
-    public TBuilder MergeFrom(ByteString data) {
-      return MergeFrom(data, ExtensionRegistry.CreateInstance());
-    }
-
-    public TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry) {
-      CodedInputStream input = data.CreateCodedInput();
-      MergeFrom(input, extensionRegistry);
-      input.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public TBuilder MergeFrom(byte[] data) {
-      CodedInputStream input = CodedInputStream.CreateInstance(data);
-      MergeFrom(input);
-      input.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry) {
-      CodedInputStream input = CodedInputStream.CreateInstance(data);
-      MergeFrom(input, extensionRegistry);
-      input.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public TBuilder MergeFrom(Stream input) {
-      CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
-      MergeFrom(codedInput);
-      codedInput.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry) {
-      CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
-      MergeFrom(codedInput, extensionRegistry);
-      codedInput.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    #endregion
-    #region Explicit definitions
-
-    IBuilderLite IBuilderLite.WeakClear() {
-      return Clear();
-    }
-
-    IBuilderLite IBuilderLite.WeakMergeFrom(IMessageLite message) {
-      return MergeFrom(message);
-    }
-
-    IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data) {
-      return MergeFrom(data);
-    }
-
-    IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistry registry) {
-      return MergeFrom(data, registry);
-    }
-
-    IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input) {
-      return MergeFrom(input);
-    }
-
-    IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) {
-      return MergeFrom(input, registry);
-    }
-
-    IMessageLite IBuilderLite.WeakBuild() {
-      return Build();
-    }
-
-    IMessageLite IBuilderLite.WeakBuildPartial() {
-      return BuildPartial();
-    }
-
-    IBuilderLite IBuilderLite.WeakClone() {
-      return Clone();
-    }
-
-    IMessageLite IBuilderLite.WeakDefaultInstanceForType {
-      get { return DefaultInstanceForType; }
-    }
-
-    #endregion
-    #region LimitedInputStream
-    /// <summary>
-    /// Stream implementation which proxies another stream, only allowing a certain amount
-    /// of data to be read. Note that this is only used to read delimited streams, so it
-    /// doesn't attempt to implement everything.
-    /// </summary>
-    private class LimitedInputStream : Stream {
-
-      private readonly Stream proxied;
-      private int bytesLeft;
-
-      internal LimitedInputStream(Stream proxied, int size) {
-        this.proxied = proxied;
-        bytesLeft = size;
-      }
-
-      public override bool CanRead {
-        get { return true; }
-      }
-
-      public override bool CanSeek {
-        get { return false; }
-      }
-
-      public override bool CanWrite {
-        get { return false; }
-      }
-
-      public override void Flush() {
-      }
-
-      public override long Length {
-        get { throw new NotSupportedException(); }
-      }
-
-      public override long Position {
-        get {
-          throw new NotSupportedException();
-        }
-        set {
-          throw new NotSupportedException();
-        }
-      }
-
-      public override int Read(byte[] buffer, int offset, int count) {
-        if (bytesLeft > 0) {
-          int bytesRead = proxied.Read(buffer, offset, Math.Min(bytesLeft, count));
-          bytesLeft -= bytesRead;
-          return bytesRead;
-        }
-        return 0;
-      }
-
-      public override long Seek(long offset, SeekOrigin origin) {
-        throw new NotSupportedException();
-      }
-
-      public override void SetLength(long value) {
-        throw new NotSupportedException();
-      }
-
-      public override void Write(byte[] buffer, int offset, int count) {
-        throw new NotSupportedException();
-      }
-    }
-    #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;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Implementation of the non-generic IMessage interface as far as possible.
+    /// </summary>
+    public abstract class AbstractBuilderLite<TMessage, TBuilder> : IBuilderLite<TMessage, TBuilder>
+        where TMessage : AbstractMessageLite<TMessage, TBuilder>
+        where TBuilder : AbstractBuilderLite<TMessage, TBuilder>
+    {
+        protected abstract TBuilder ThisBuilder { get; }
+
+        public abstract bool IsInitialized { get; }
+
+        public abstract TBuilder Clear();
+
+        public abstract TBuilder Clone();
+
+        public abstract TMessage Build();
+
+        public abstract TMessage BuildPartial();
+
+        public abstract TBuilder MergeFrom(IMessageLite other);
+
+        public abstract TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry);
+
+        public abstract TMessage DefaultInstanceForType { get; }
+
+        #region IBuilderLite<TMessage,TBuilder> Members
+
+        public virtual TBuilder MergeFrom(CodedInputStream input)
+        {
+            return MergeFrom(input, ExtensionRegistry.CreateInstance());
+        }
+
+        public TBuilder MergeDelimitedFrom(Stream input)
+        {
+            return MergeDelimitedFrom(input, ExtensionRegistry.CreateInstance());
+        }
+
+        public TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry)
+        {
+            int size = (int) CodedInputStream.ReadRawVarint32(input);
+            Stream limitedStream = new LimitedInputStream(input, size);
+            return MergeFrom(limitedStream, extensionRegistry);
+        }
+
+        public TBuilder MergeFrom(ByteString data)
+        {
+            return MergeFrom(data, ExtensionRegistry.CreateInstance());
+        }
+
+        public TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry)
+        {
+            CodedInputStream input = data.CreateCodedInput();
+            MergeFrom(input, extensionRegistry);
+            input.CheckLastTagWas(0);
+            return ThisBuilder;
+        }
+
+        public TBuilder MergeFrom(byte[] data)
+        {
+            CodedInputStream input = CodedInputStream.CreateInstance(data);
+            MergeFrom(input);
+            input.CheckLastTagWas(0);
+            return ThisBuilder;
+        }
+
+        public TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry)
+        {
+            CodedInputStream input = CodedInputStream.CreateInstance(data);
+            MergeFrom(input, extensionRegistry);
+            input.CheckLastTagWas(0);
+            return ThisBuilder;
+        }
+
+        public TBuilder MergeFrom(Stream input)
+        {
+            CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
+            MergeFrom(codedInput);
+            codedInput.CheckLastTagWas(0);
+            return ThisBuilder;
+        }
+
+        public TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry)
+        {
+            CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
+            MergeFrom(codedInput, extensionRegistry);
+            codedInput.CheckLastTagWas(0);
+            return ThisBuilder;
+        }
+
+        #endregion
+
+        #region Explicit definitions
+
+        IBuilderLite IBuilderLite.WeakClear()
+        {
+            return Clear();
+        }
+
+        IBuilderLite IBuilderLite.WeakMergeFrom(IMessageLite message)
+        {
+            return MergeFrom(message);
+        }
+
+        IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data)
+        {
+            return MergeFrom(data);
+        }
+
+        IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistry registry)
+        {
+            return MergeFrom(data, registry);
+        }
+
+        IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input)
+        {
+            return MergeFrom(input);
+        }
+
+        IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry)
+        {
+            return MergeFrom(input, registry);
+        }
+
+        IMessageLite IBuilderLite.WeakBuild()
+        {
+            return Build();
+        }
+
+        IMessageLite IBuilderLite.WeakBuildPartial()
+        {
+            return BuildPartial();
+        }
+
+        IBuilderLite IBuilderLite.WeakClone()
+        {
+            return Clone();
+        }
+
+        IMessageLite IBuilderLite.WeakDefaultInstanceForType
+        {
+            get { return DefaultInstanceForType; }
+        }
+
+        #endregion
+
+        #region LimitedInputStream
+
+        /// <summary>
+        /// Stream implementation which proxies another stream, only allowing a certain amount
+        /// of data to be read. Note that this is only used to read delimited streams, so it
+        /// doesn't attempt to implement everything.
+        /// </summary>
+        private class LimitedInputStream : Stream
+        {
+            private readonly Stream proxied;
+            private int bytesLeft;
+
+            internal LimitedInputStream(Stream proxied, int size)
+            {
+                this.proxied = proxied;
+                bytesLeft = size;
+            }
+
+            public override bool CanRead
+            {
+                get { return true; }
+            }
+
+            public override bool CanSeek
+            {
+                get { return false; }
+            }
+
+            public override bool CanWrite
+            {
+                get { return false; }
+            }
+
+            public override void Flush()
+            {
+            }
+
+            public override long Length
+            {
+                get { throw new NotSupportedException(); }
+            }
+
+            public override long Position
+            {
+                get { throw new NotSupportedException(); }
+                set { throw new NotSupportedException(); }
+            }
+
+            public override int Read(byte[] buffer, int offset, int count)
+            {
+                if (bytesLeft > 0)
+                {
+                    int bytesRead = proxied.Read(buffer, offset, Math.Min(bytesLeft, count));
+                    bytesLeft -= bytesRead;
+                    return bytesRead;
+                }
+                return 0;
+            }
+
+            public override long Seek(long offset, SeekOrigin origin)
+            {
+                throw new NotSupportedException();
+            }
+
+            public override void SetLength(long value)
+            {
+                throw new NotSupportedException();
+            }
+
+            public override void Write(byte[] buffer, int offset, int count)
+            {
+                throw new NotSupportedException();
+            }
+        }
+
+        #endregion
+    }
+}

+ 303 - 245
src/ProtocolBuffers/AbstractMessage.cs

@@ -1,245 +1,303 @@
-#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.Collections;
-using System.Collections.Generic;
-using System.IO;
-using Google.ProtocolBuffers.Collections;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Implementation of the non-generic IMessage interface as far as possible.
-  /// </summary>
-  public abstract class AbstractMessage<TMessage, TBuilder> : AbstractMessageLite<TMessage, TBuilder>, IMessage<TMessage, TBuilder> 
-      where TMessage : AbstractMessage<TMessage, TBuilder> 
-      where TBuilder : AbstractBuilder<TMessage, TBuilder> {
-    /// <summary>
-    /// The serialized size if it's already been computed, or null
-    /// if we haven't computed it yet.
-    /// </summary>
-    private int? memoizedSize = null;
-
-    #region Unimplemented members of IMessage
-    public abstract MessageDescriptor DescriptorForType { get; }
-    public abstract IDictionary<FieldDescriptor, object> AllFields { get; }
-    public abstract bool HasField(FieldDescriptor field);
-    public abstract object this[FieldDescriptor field] { get; }
-    public abstract int GetRepeatedFieldCount(FieldDescriptor field);
-    public abstract object this[FieldDescriptor field, int index] { get; }
-    public abstract UnknownFieldSet UnknownFields { get; }
-    #endregion
-
-    /// <summary>
-    /// Returns true iff all required fields in the message and all embedded
-    /// messages are set.
-    /// </summary>
-    public override bool IsInitialized {
-      get {
-        // Check that all required fields are present.
-        foreach (FieldDescriptor field in DescriptorForType.Fields) {
-          if (field.IsRequired && !HasField(field)) {
-            return false;
-          }
-        }
-
-        // Check that embedded messages are initialized.
-        foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
-          FieldDescriptor field = entry.Key;
-          if (field.MappedType == MappedType.Message) {
-            if (field.IsRepeated) {
-              // We know it's an IList<T>, but not the exact type - so
-              // IEnumerable is the best we can do. (C# generics aren't covariant yet.)
-              foreach (IMessageLite element in (IEnumerable)entry.Value) {
-                if (!element.IsInitialized) {
-                  return false;
-                }
-              }
-            } else {
-              if (!((IMessageLite)entry.Value).IsInitialized) {
-                return false;
-              }
-            }
-          }
-        }
-        return true;
-      }
-    }
-
-    public sealed override string ToString() {
-      return TextFormat.PrintToString(this);
-    }
-
-    public sealed override void PrintTo(TextWriter writer) {
-      TextFormat.Print(this, writer);
-    }
-
-    /// <summary>
-    /// Serializes the message and writes it to the given output stream.
-    /// This does not flush or close the stream.
-    /// </summary>
-    /// <remarks>
-    /// Protocol Buffers are not self-delimiting. Therefore, if you write
-    /// any more data to the stream after the message, you must somehow ensure
-    /// that the parser on the receiving end does not interpret this as being
-    /// part of the protocol message. One way of doing this is by writing the size
-    /// of the message before the data, then making sure you limit the input to
-    /// that size when receiving the data. Alternatively, use WriteDelimitedTo(Stream).
-    /// </remarks>
-    public override void WriteTo(CodedOutputStream output) {
-      foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
-        FieldDescriptor field = entry.Key;
-        if (field.IsRepeated) {
-          // We know it's an IList<T>, but not the exact type - so
-          // IEnumerable is the best we can do. (C# generics aren't covariant yet.)
-          IEnumerable valueList = (IEnumerable) entry.Value;
-          if (field.IsPacked) {
-            output.WriteTag(field.FieldNumber, WireFormat.WireType.LengthDelimited);
-            int dataSize = 0;
-            foreach (object element in valueList) {
-              dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element);
-            }
-            output.WriteRawVarint32((uint)dataSize);
-            foreach (object element in valueList) {
-              output.WriteFieldNoTag(field.FieldType, element);
-            }
-          } else {
-            foreach (object element in valueList) {
-              output.WriteField(field.FieldType, field.FieldNumber, element);
-            }
-          }
-        } else {
-          output.WriteField(field.FieldType, field.FieldNumber, entry.Value);
-        }
-      }
-
-      UnknownFieldSet unknownFields = UnknownFields;
-      if (DescriptorForType.Options.MessageSetWireFormat) {
-        unknownFields.WriteAsMessageSetTo(output);
-      } else {
-        unknownFields.WriteTo(output);
-      }
-    }
-
-    /// <summary>
-    /// Returns the number of bytes required to encode this message.
-    /// The result is only computed on the first call and memoized after that.
-    /// </summary>
-    public override int SerializedSize {
-      get {
-        if (memoizedSize != null) {
-          return memoizedSize.Value;
-        }
-
-        int size = 0;
-        foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
-          FieldDescriptor field = entry.Key;
-          if (field.IsRepeated) {
-            IEnumerable valueList = (IEnumerable) entry.Value;
-            if (field.IsPacked) {
-              int dataSize = 0;
-              foreach (object element in valueList) {
-                dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element);
-              }
-              size += dataSize;
-              size += CodedOutputStream.ComputeTagSize(field.FieldNumber);
-              size += CodedOutputStream.ComputeRawVarint32Size((uint)dataSize);
-            } else {
-              foreach (object element in valueList) {
-                size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, element);
-              }
-            }
-          } else {
-            size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, entry.Value);
-          }
-        }
-
-        UnknownFieldSet unknownFields = UnknownFields;
-        if (DescriptorForType.Options.MessageSetWireFormat) {
-          size += unknownFields.SerializedSizeAsMessageSet;
-        } else {
-          size += unknownFields.SerializedSize;
-        }
-
-        memoizedSize = size;
-        return size;
-      }
-    }
-
-    /// <summary>
-    /// Compares the specified object with this message for equality.
-    /// Returns true iff the given object is a message of the same type
-    /// (as defined by DescriptorForType) and has identical values
-    /// for all its fields.
-    /// </summary>
-    public override bool Equals(object other) {
-      if (other == this) {
-        return true;
-      }
-      IMessage otherMessage = other as IMessage;
-      if (otherMessage == null || otherMessage.DescriptorForType != DescriptorForType) {
-        return false;
-      }
-      return Dictionaries.Equals(AllFields, otherMessage.AllFields) && UnknownFields.Equals(otherMessage.UnknownFields);
-    }
-
-    /// <summary>
-    /// Returns the hash code value for this message.
-    /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one!
-    /// </summary>
-    public override int GetHashCode() {
-      int hash = 41;
-      hash = (19 * hash) + DescriptorForType.GetHashCode();
-      hash = (53 * hash) + Dictionaries.GetHashCode(AllFields);
-      hash = (29 * hash) + UnknownFields.GetHashCode();
-      return hash;
-    }
-
-    #region Explicit Members
-    
-    IBuilder IMessage.WeakCreateBuilderForType() {
-      return CreateBuilderForType();
-    }
-
-    IBuilder IMessage.WeakToBuilder() {
-      return ToBuilder();
-    }
-
-    IMessage IMessage.WeakDefaultInstanceForType {
-      get { return DefaultInstanceForType; }
-    }
-
-    #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.Collections;
+using System.Collections.Generic;
+using System.IO;
+using Google.ProtocolBuffers.Collections;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Implementation of the non-generic IMessage interface as far as possible.
+    /// </summary>
+    public abstract class AbstractMessage<TMessage, TBuilder> : AbstractMessageLite<TMessage, TBuilder>,
+                                                                IMessage<TMessage, TBuilder>
+        where TMessage : AbstractMessage<TMessage, TBuilder>
+        where TBuilder : AbstractBuilder<TMessage, TBuilder>
+    {
+        /// <summary>
+        /// The serialized size if it's already been computed, or null
+        /// if we haven't computed it yet.
+        /// </summary>
+        private int? memoizedSize = null;
+
+        #region Unimplemented members of IMessage
+
+        public abstract MessageDescriptor DescriptorForType { get; }
+        public abstract IDictionary<FieldDescriptor, object> AllFields { get; }
+        public abstract bool HasField(FieldDescriptor field);
+        public abstract object this[FieldDescriptor field] { get; }
+        public abstract int GetRepeatedFieldCount(FieldDescriptor field);
+        public abstract object this[FieldDescriptor field, int index] { get; }
+        public abstract UnknownFieldSet UnknownFields { get; }
+
+        #endregion
+
+        /// <summary>
+        /// Returns true iff all required fields in the message and all embedded
+        /// messages are set.
+        /// </summary>
+        public override bool IsInitialized
+        {
+            get
+            {
+                // Check that all required fields are present.
+                foreach (FieldDescriptor field in DescriptorForType.Fields)
+                {
+                    if (field.IsRequired && !HasField(field))
+                    {
+                        return false;
+                    }
+                }
+
+                // Check that embedded messages are initialized.
+                foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields)
+                {
+                    FieldDescriptor field = entry.Key;
+                    if (field.MappedType == MappedType.Message)
+                    {
+                        if (field.IsRepeated)
+                        {
+                            // We know it's an IList<T>, but not the exact type - so
+                            // IEnumerable is the best we can do. (C# generics aren't covariant yet.)
+                            foreach (IMessageLite element in (IEnumerable) entry.Value)
+                            {
+                                if (!element.IsInitialized)
+                                {
+                                    return false;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (!((IMessageLite) entry.Value).IsInitialized)
+                            {
+                                return false;
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+        }
+
+        public override sealed string ToString()
+        {
+            return TextFormat.PrintToString(this);
+        }
+
+        public override sealed void PrintTo(TextWriter writer)
+        {
+            TextFormat.Print(this, writer);
+        }
+
+        /// <summary>
+        /// Serializes the message and writes it to the given output stream.
+        /// This does not flush or close the stream.
+        /// </summary>
+        /// <remarks>
+        /// Protocol Buffers are not self-delimiting. Therefore, if you write
+        /// any more data to the stream after the message, you must somehow ensure
+        /// that the parser on the receiving end does not interpret this as being
+        /// part of the protocol message. One way of doing this is by writing the size
+        /// of the message before the data, then making sure you limit the input to
+        /// that size when receiving the data. Alternatively, use WriteDelimitedTo(Stream).
+        /// </remarks>
+        public override void WriteTo(CodedOutputStream output)
+        {
+            foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields)
+            {
+                FieldDescriptor field = entry.Key;
+                if (field.IsRepeated)
+                {
+                    // We know it's an IList<T>, but not the exact type - so
+                    // IEnumerable is the best we can do. (C# generics aren't covariant yet.)
+                    IEnumerable valueList = (IEnumerable) entry.Value;
+                    if (field.IsPacked)
+                    {
+                        output.WriteTag(field.FieldNumber, WireFormat.WireType.LengthDelimited);
+                        int dataSize = 0;
+                        foreach (object element in valueList)
+                        {
+                            dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element);
+                        }
+                        output.WriteRawVarint32((uint) dataSize);
+                        foreach (object element in valueList)
+                        {
+                            output.WriteFieldNoTag(field.FieldType, element);
+                        }
+                    }
+                    else
+                    {
+                        foreach (object element in valueList)
+                        {
+                            output.WriteField(field.FieldType, field.FieldNumber, element);
+                        }
+                    }
+                }
+                else
+                {
+                    output.WriteField(field.FieldType, field.FieldNumber, entry.Value);
+                }
+            }
+
+            UnknownFieldSet unknownFields = UnknownFields;
+            if (DescriptorForType.Options.MessageSetWireFormat)
+            {
+                unknownFields.WriteAsMessageSetTo(output);
+            }
+            else
+            {
+                unknownFields.WriteTo(output);
+            }
+        }
+
+        /// <summary>
+        /// Returns the number of bytes required to encode this message.
+        /// The result is only computed on the first call and memoized after that.
+        /// </summary>
+        public override int SerializedSize
+        {
+            get
+            {
+                if (memoizedSize != null)
+                {
+                    return memoizedSize.Value;
+                }
+
+                int size = 0;
+                foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields)
+                {
+                    FieldDescriptor field = entry.Key;
+                    if (field.IsRepeated)
+                    {
+                        IEnumerable valueList = (IEnumerable) entry.Value;
+                        if (field.IsPacked)
+                        {
+                            int dataSize = 0;
+                            foreach (object element in valueList)
+                            {
+                                dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element);
+                            }
+                            size += dataSize;
+                            size += CodedOutputStream.ComputeTagSize(field.FieldNumber);
+                            size += CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);
+                        }
+                        else
+                        {
+                            foreach (object element in valueList)
+                            {
+                                size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, element);
+                            }
+                        }
+                    }
+                    else
+                    {
+                        size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, entry.Value);
+                    }
+                }
+
+                UnknownFieldSet unknownFields = UnknownFields;
+                if (DescriptorForType.Options.MessageSetWireFormat)
+                {
+                    size += unknownFields.SerializedSizeAsMessageSet;
+                }
+                else
+                {
+                    size += unknownFields.SerializedSize;
+                }
+
+                memoizedSize = size;
+                return size;
+            }
+        }
+
+        /// <summary>
+        /// Compares the specified object with this message for equality.
+        /// Returns true iff the given object is a message of the same type
+        /// (as defined by DescriptorForType) and has identical values
+        /// for all its fields.
+        /// </summary>
+        public override bool Equals(object other)
+        {
+            if (other == this)
+            {
+                return true;
+            }
+            IMessage otherMessage = other as IMessage;
+            if (otherMessage == null || otherMessage.DescriptorForType != DescriptorForType)
+            {
+                return false;
+            }
+            return Dictionaries.Equals(AllFields, otherMessage.AllFields) &&
+                   UnknownFields.Equals(otherMessage.UnknownFields);
+        }
+
+        /// <summary>
+        /// Returns the hash code value for this message.
+        /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one!
+        /// </summary>
+        public override int GetHashCode()
+        {
+            int hash = 41;
+            hash = (19*hash) + DescriptorForType.GetHashCode();
+            hash = (53*hash) + Dictionaries.GetHashCode(AllFields);
+            hash = (29*hash) + UnknownFields.GetHashCode();
+            return hash;
+        }
+
+        #region Explicit Members
+
+        IBuilder IMessage.WeakCreateBuilderForType()
+        {
+            return CreateBuilderForType();
+        }
+
+        IBuilder IMessage.WeakToBuilder()
+        {
+            return ToBuilder();
+        }
+
+        IMessage IMessage.WeakDefaultInstanceForType
+        {
+            get { return DefaultInstanceForType; }
+        }
+
+        #endregion
+    }
+}

+ 142 - 133
src/ProtocolBuffers/AbstractMessageLite.cs

@@ -1,133 +1,142 @@
-#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.Collections;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Implementation of the non-generic IMessage interface as far as possible.
-  /// </summary>
-  public abstract class AbstractMessageLite<TMessage, TBuilder> : IMessageLite<TMessage, TBuilder>
-    where TMessage : AbstractMessageLite<TMessage, TBuilder>
-    where TBuilder : AbstractBuilderLite<TMessage, TBuilder> {
- 
-    
-    public abstract TBuilder CreateBuilderForType();
-
-    public abstract TBuilder ToBuilder();
-
-    public abstract TMessage DefaultInstanceForType { get; }
-
-    public abstract bool IsInitialized { get; }
-
-    public abstract void WriteTo(CodedOutputStream output);
-
-    public abstract int SerializedSize { get; }
-
-    //public override bool Equals(object other) {
-    //}
-
-    //public override int GetHashCode() {
-    //}
-
-    public abstract void PrintTo(TextWriter writer);
-
-    #region IMessageLite<TMessage,TBuilder> Members
-
-    /// <summary>
-    /// Serializes the message to a ByteString. This is a trivial wrapper
-    /// around WriteTo(CodedOutputStream).
-    /// </summary>
-    public ByteString ToByteString() {
-      ByteString.CodedBuilder output = new ByteString.CodedBuilder(SerializedSize);
-      WriteTo(output.CodedOutput);
-      return output.Build();
-    }
-
-    /// <summary>
-    /// Serializes the message to a byte array. This is a trivial wrapper
-    /// around WriteTo(CodedOutputStream).
-    /// </summary>
-    public byte[] ToByteArray() {
-      byte[] result = new byte[SerializedSize];
-      CodedOutputStream output = CodedOutputStream.CreateInstance(result);
-      WriteTo(output);
-      output.CheckNoSpaceLeft();
-      return result;
-    }
-
-    /// <summary>
-    /// Serializes the message and writes it to the given stream.
-    /// This is just a wrapper around WriteTo(CodedOutputStream). This
-    /// does not flush or close the stream.
-    /// </summary>
-    /// <param name="output"></param>
-    public void WriteTo(Stream output) {
-      CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
-      WriteTo(codedOutput);
-      codedOutput.Flush();
-    }
-
-    /// <summary>
-    /// Like WriteTo(Stream) but writes the size of the message as a varint before
-    /// writing the data. This allows more data to be written to the stream after the
-    /// message without the need to delimit the message data yourself. Use 
-    /// IBuilder.MergeDelimitedFrom(Stream) or the static method
-    /// YourMessageType.ParseDelimitedFrom(Stream) to parse messages written by this method.
-    /// </summary>
-    /// <param name="output"></param>
-    public void WriteDelimitedTo(Stream output) {
-      CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
-      codedOutput.WriteRawVarint32((uint)SerializedSize);
-      WriteTo(codedOutput);
-      codedOutput.Flush();
-    }
-
-    IBuilderLite IMessageLite.WeakCreateBuilderForType() {
-      return CreateBuilderForType();
-    }
-
-    IBuilderLite IMessageLite.WeakToBuilder() {
-      return ToBuilder();
-    }
-
-    IMessageLite IMessageLite.WeakDefaultInstanceForType {
-      get { return DefaultInstanceForType; }
-    }
-
-    #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.Collections;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Implementation of the non-generic IMessage interface as far as possible.
+    /// </summary>
+    public abstract class AbstractMessageLite<TMessage, TBuilder> : IMessageLite<TMessage, TBuilder>
+        where TMessage : AbstractMessageLite<TMessage, TBuilder>
+        where TBuilder : AbstractBuilderLite<TMessage, TBuilder>
+    {
+        public abstract TBuilder CreateBuilderForType();
+
+        public abstract TBuilder ToBuilder();
+
+        public abstract TMessage DefaultInstanceForType { get; }
+
+        public abstract bool IsInitialized { get; }
+
+        public abstract void WriteTo(CodedOutputStream output);
+
+        public abstract int SerializedSize { get; }
+
+        //public override bool Equals(object other) {
+        //}
+
+        //public override int GetHashCode() {
+        //}
+
+        public abstract void PrintTo(TextWriter writer);
+
+        #region IMessageLite<TMessage,TBuilder> Members
+
+        /// <summary>
+        /// Serializes the message to a ByteString. This is a trivial wrapper
+        /// around WriteTo(CodedOutputStream).
+        /// </summary>
+        public ByteString ToByteString()
+        {
+            ByteString.CodedBuilder output = new ByteString.CodedBuilder(SerializedSize);
+            WriteTo(output.CodedOutput);
+            return output.Build();
+        }
+
+        /// <summary>
+        /// Serializes the message to a byte array. This is a trivial wrapper
+        /// around WriteTo(CodedOutputStream).
+        /// </summary>
+        public byte[] ToByteArray()
+        {
+            byte[] result = new byte[SerializedSize];
+            CodedOutputStream output = CodedOutputStream.CreateInstance(result);
+            WriteTo(output);
+            output.CheckNoSpaceLeft();
+            return result;
+        }
+
+        /// <summary>
+        /// Serializes the message and writes it to the given stream.
+        /// This is just a wrapper around WriteTo(CodedOutputStream). This
+        /// does not flush or close the stream.
+        /// </summary>
+        /// <param name="output"></param>
+        public void WriteTo(Stream output)
+        {
+            CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
+            WriteTo(codedOutput);
+            codedOutput.Flush();
+        }
+
+        /// <summary>
+        /// Like WriteTo(Stream) but writes the size of the message as a varint before
+        /// writing the data. This allows more data to be written to the stream after the
+        /// message without the need to delimit the message data yourself. Use 
+        /// IBuilder.MergeDelimitedFrom(Stream) or the static method
+        /// YourMessageType.ParseDelimitedFrom(Stream) to parse messages written by this method.
+        /// </summary>
+        /// <param name="output"></param>
+        public void WriteDelimitedTo(Stream output)
+        {
+            CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
+            codedOutput.WriteRawVarint32((uint) SerializedSize);
+            WriteTo(codedOutput);
+            codedOutput.Flush();
+        }
+
+        IBuilderLite IMessageLite.WeakCreateBuilderForType()
+        {
+            return CreateBuilderForType();
+        }
+
+        IBuilderLite IMessageLite.WeakToBuilder()
+        {
+            return ToBuilder();
+        }
+
+        IMessageLite IMessageLite.WeakDefaultInstanceForType
+        {
+            get { return DefaultInstanceForType; }
+        }
+
+        #endregion
+    }
+}

+ 241 - 213
src/ProtocolBuffers/ByteString.cs

@@ -1,213 +1,241 @@
-#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;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Immutable array of bytes.
-  /// TODO(jonskeet): Implement the common collection interfaces?
-  /// </summary>
-  public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString> {
-
-    private static readonly ByteString empty = new ByteString(new byte[0]);
-
-    private readonly byte[] bytes;
-
-    /// <summary>
-    /// Constructs a new ByteString from the given byte array. The array is
-    /// *not* copied, and must not be modified after this constructor is called.
-    /// </summary>
-    private ByteString(byte[] bytes) {
-      this.bytes = bytes;
-    }
-
-    /// <summary>
-    /// Returns an empty ByteString.
-    /// </summary>
-    public static ByteString Empty {
-      get { return empty; }
-    }
-
-    /// <summary>
-    /// Returns the length of this ByteString in bytes.
-    /// </summary>
-    public int Length {
-      get { return bytes.Length; }
-    }
-
-    public bool IsEmpty {
-      get { return Length == 0; }
-    }
-
-    public byte[] ToByteArray() {
-      return (byte[])bytes.Clone();
-    }
-
-    /// <summary>
-    /// Constructs a ByteString from the Base64 Encoded String.
-    /// </summary>
-    public static ByteString FromBase64(string bytes) {
-      return new ByteString(System.Convert.FromBase64String(bytes));
-    }
-
-    /// <summary>
-    /// Constructs a ByteString from the given array. The contents
-    /// are copied, so further modifications to the array will not
-    /// be reflected in the returned ByteString.
-    /// </summary>
-    public static ByteString CopyFrom(byte[] bytes) {
-      return new ByteString((byte[]) bytes.Clone());
-    }
-
-    /// <summary>
-    /// Constructs a ByteString from a portion of a byte array.
-    /// </summary>
-    public static ByteString CopyFrom(byte[] bytes, int offset, int count) {
-      byte[] portion = new byte[count];
-      Array.Copy(bytes, offset, portion, 0, count);
-      return new ByteString(portion);
-    }
-
-    /// <summary>
-    /// Creates a new ByteString by encoding the specified text with
-    /// the given encoding.
-    /// </summary>
-    public static ByteString CopyFrom(string text, Encoding encoding) {
-      return new ByteString(encoding.GetBytes(text));
-    }
-
-    /// <summary>
-    /// Creates a new ByteString by encoding the specified text in UTF-8.
-    /// </summary>
-    public static ByteString CopyFromUtf8(string text) {
-      return CopyFrom(text, Encoding.UTF8);
-    }
-    
-    /// <summary>
-    /// Retuns the byte at the given index.
-    /// </summary>
-    public byte this[int index] {
-      get { return bytes[index]; }
-    }
-
-    public string ToString(Encoding encoding) {
-      return encoding.GetString(bytes, 0, bytes.Length);
-    }
-
-    public string ToStringUtf8() {
-      return ToString(Encoding.UTF8);
-    }
-
-    public IEnumerator<byte> GetEnumerator() {
-      return ((IEnumerable<byte>) bytes).GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator() {
-      return GetEnumerator();
-    }
-
-    /// <summary>
-    /// Creates a CodedInputStream from this ByteString's data.
-    /// </summary>
-    public CodedInputStream CreateCodedInput() {
-      
-      // We trust CodedInputStream not to reveal the provided byte array or modify it
-      return CodedInputStream.CreateInstance(bytes);
-    }
-
-    // TODO(jonskeet): CopyTo if it turns out to be required
-
-    public override bool Equals(object obj) {
-      ByteString other = obj as ByteString;
-      if (obj == null) {
-        return false;
-      }
-      return Equals(other);
-    }
-
-    public override int GetHashCode() {
-      int ret = 23;
-      foreach (byte b in bytes) {
-        ret = (ret << 8) | b;
-      }
-      return ret;
-    }
-
-    public bool Equals(ByteString other) {
-      if (other.bytes.Length != bytes.Length) {
-        return false;
-      }
-      for (int i = 0; i < bytes.Length; i++) {
-        if (other.bytes[i] != bytes[i]) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /// <summary>
-    /// Builder for ByteStrings which allows them to be created without extra
-    /// copying being involved. This has to be a nested type in order to have access
-    /// to the private ByteString constructor.
-    /// </summary>
-    internal sealed class CodedBuilder {
-      private readonly CodedOutputStream output;
-      private readonly byte[] buffer;
-
-      internal CodedBuilder(int size) {
-        buffer = new byte[size];
-        output = CodedOutputStream.CreateInstance(buffer);
-      }
-
-      internal ByteString Build() {
-        output.CheckNoSpaceLeft();
-
-        // We can be confident that the CodedOutputStream will not modify the
-        // underlying bytes anymore because it already wrote all of them.  So,
-        // no need to make a copy.
-        return new ByteString(buffer);
-      }
-
-      internal CodedOutputStream CodedOutput {
-        get {
-          return output;
-        }
-      }
-    }
-  }
-}
+#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;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Immutable array of bytes.
+    /// TODO(jonskeet): Implement the common collection interfaces?
+    /// </summary>
+    public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString>
+    {
+        private static readonly ByteString empty = new ByteString(new byte[0]);
+
+        private readonly byte[] bytes;
+
+        /// <summary>
+        /// Constructs a new ByteString from the given byte array. The array is
+        /// *not* copied, and must not be modified after this constructor is called.
+        /// </summary>
+        private ByteString(byte[] bytes)
+        {
+            this.bytes = bytes;
+        }
+
+        /// <summary>
+        /// Returns an empty ByteString.
+        /// </summary>
+        public static ByteString Empty
+        {
+            get { return empty; }
+        }
+
+        /// <summary>
+        /// Returns the length of this ByteString in bytes.
+        /// </summary>
+        public int Length
+        {
+            get { return bytes.Length; }
+        }
+
+        public bool IsEmpty
+        {
+            get { return Length == 0; }
+        }
+
+        public byte[] ToByteArray()
+        {
+            return (byte[]) bytes.Clone();
+        }
+
+        /// <summary>
+        /// Constructs a ByteString from the Base64 Encoded String.
+        /// </summary>
+        public static ByteString FromBase64(string bytes)
+        {
+            return new ByteString(System.Convert.FromBase64String(bytes));
+        }
+
+        /// <summary>
+        /// Constructs a ByteString from the given array. The contents
+        /// are copied, so further modifications to the array will not
+        /// be reflected in the returned ByteString.
+        /// </summary>
+        public static ByteString CopyFrom(byte[] bytes)
+        {
+            return new ByteString((byte[]) bytes.Clone());
+        }
+
+        /// <summary>
+        /// Constructs a ByteString from a portion of a byte array.
+        /// </summary>
+        public static ByteString CopyFrom(byte[] bytes, int offset, int count)
+        {
+            byte[] portion = new byte[count];
+            Array.Copy(bytes, offset, portion, 0, count);
+            return new ByteString(portion);
+        }
+
+        /// <summary>
+        /// Creates a new ByteString by encoding the specified text with
+        /// the given encoding.
+        /// </summary>
+        public static ByteString CopyFrom(string text, Encoding encoding)
+        {
+            return new ByteString(encoding.GetBytes(text));
+        }
+
+        /// <summary>
+        /// Creates a new ByteString by encoding the specified text in UTF-8.
+        /// </summary>
+        public static ByteString CopyFromUtf8(string text)
+        {
+            return CopyFrom(text, Encoding.UTF8);
+        }
+
+        /// <summary>
+        /// Retuns the byte at the given index.
+        /// </summary>
+        public byte this[int index]
+        {
+            get { return bytes[index]; }
+        }
+
+        public string ToString(Encoding encoding)
+        {
+            return encoding.GetString(bytes, 0, bytes.Length);
+        }
+
+        public string ToStringUtf8()
+        {
+            return ToString(Encoding.UTF8);
+        }
+
+        public IEnumerator<byte> GetEnumerator()
+        {
+            return ((IEnumerable<byte>) bytes).GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        /// <summary>
+        /// Creates a CodedInputStream from this ByteString's data.
+        /// </summary>
+        public CodedInputStream CreateCodedInput()
+        {
+            // We trust CodedInputStream not to reveal the provided byte array or modify it
+            return CodedInputStream.CreateInstance(bytes);
+        }
+
+        // TODO(jonskeet): CopyTo if it turns out to be required
+
+        public override bool Equals(object obj)
+        {
+            ByteString other = obj as ByteString;
+            if (obj == null)
+            {
+                return false;
+            }
+            return Equals(other);
+        }
+
+        public override int GetHashCode()
+        {
+            int ret = 23;
+            foreach (byte b in bytes)
+            {
+                ret = (ret << 8) | b;
+            }
+            return ret;
+        }
+
+        public bool Equals(ByteString other)
+        {
+            if (other.bytes.Length != bytes.Length)
+            {
+                return false;
+            }
+            for (int i = 0; i < bytes.Length; i++)
+            {
+                if (other.bytes[i] != bytes[i])
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /// <summary>
+        /// Builder for ByteStrings which allows them to be created without extra
+        /// copying being involved. This has to be a nested type in order to have access
+        /// to the private ByteString constructor.
+        /// </summary>
+        internal sealed class CodedBuilder
+        {
+            private readonly CodedOutputStream output;
+            private readonly byte[] buffer;
+
+            internal CodedBuilder(int size)
+            {
+                buffer = new byte[size];
+                output = CodedOutputStream.CreateInstance(buffer);
+            }
+
+            internal ByteString Build()
+            {
+                output.CheckNoSpaceLeft();
+
+                // We can be confident that the CodedOutputStream will not modify the
+                // underlying bytes anymore because it already wrote all of them.  So,
+                // no need to make a copy.
+                return new ByteString(buffer);
+            }
+
+            internal CodedOutputStream CodedOutput
+            {
+                get { return output; }
+            }
+        }
+    }
+}

+ 1155 - 985
src/ProtocolBuffers/CodedInputStream.cs

@@ -1,985 +1,1155 @@
-#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 System.Text;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers {
-
-  /// <summary>
-  /// Readings and decodes protocol message fields.
-  /// </summary>
-  /// <remarks>
-  /// This class contains two kinds of methods:  methods that read specific
-  /// protocol message constructs and field types (e.g. ReadTag and
-  /// ReadInt32) and methods that read low-level values (e.g.
-  /// ReadRawVarint32 and ReadRawBytes).  If you are reading encoded protocol
-  /// messages, you should use the former methods, but if you are reading some
-  /// other format of your own design, use the latter. The names of the former
-  /// methods are taken from the protocol buffer type names, not .NET types.
-  /// (Hence ReadFloat instead of ReadSingle, and ReadBool instead of ReadBoolean.)
-  /// 
-  /// TODO(jonskeet): Consider whether recursion and size limits shouldn't be readonly,
-  /// set at construction time.
-  /// </remarks>
-  public sealed class CodedInputStream {
-    private readonly byte[] buffer;
-    private int bufferSize;
-    private int bufferSizeAfterLimit = 0;
-    private int bufferPos = 0;
-    private readonly Stream input;
-    private uint lastTag = 0;
-
-    internal const int DefaultRecursionLimit = 64;
-    internal const int DefaultSizeLimit = 64 << 20; // 64MB
-    public const int BufferSize = 4096;
-    
-    /// <summary>
-    /// The total number of bytes read before the current buffer. The
-    /// total bytes read up to the current position can be computed as
-    /// totalBytesRetired + bufferPos.
-    /// </summary>
-    private int totalBytesRetired = 0;
-
-    /// <summary>
-    /// The absolute position of the end of the current message.
-    /// </summary> 
-    private int currentLimit = int.MaxValue;
-
-    /// <summary>
-    /// <see cref="SetRecursionLimit"/>
-    /// </summary>
-    private int recursionDepth = 0;
-    private int recursionLimit = DefaultRecursionLimit;
-
-    /// <summary>
-    /// <see cref="SetSizeLimit"/>
-    /// </summary>
-    private int sizeLimit = DefaultSizeLimit;
-
-    #region Construction
-    /// <summary>
-    /// Creates a new CodedInputStream reading data from the given
-    /// stream.
-    /// </summary>
-    public static CodedInputStream CreateInstance(Stream input) {
-      return new CodedInputStream(input);
-    }
-
-    /// <summary>
-    /// Creates a new CodedInputStream reading data from the given
-    /// byte array.
-    /// </summary>
-    public static CodedInputStream CreateInstance(byte[] buf) {
-      return new CodedInputStream(buf, 0, buf.Length);
-    }
-
-    /// <summary>
-    /// Creates a new CodedInputStream that reads from the given
-    /// byte array slice.
-    /// </summary>
-    public static CodedInputStream CreateInstance(byte[] buf, int offset, int length) {
-      return new CodedInputStream(buf, offset, length);
-    }
-
-    private CodedInputStream(byte[] buffer, int offset, int length) {
-      this.buffer = buffer;
-      this.bufferPos = offset;
-      this.bufferSize = offset + length;
-      this.input = null;
-    }
-
-    private CodedInputStream(Stream input) {
-      this.buffer = new byte[BufferSize];
-      this.bufferSize = 0;
-      this.input = input;
-    }
-    #endregion
-
-    #region Validation
-    /// <summary>
-    /// Verifies that the last call to ReadTag() returned the given tag value.
-    /// This is used to verify that a nested group ended with the correct
-    /// end tag.
-    /// </summary>
-    /// <exception cref="InvalidProtocolBufferException">The last
-    /// tag read was not the one specified</exception>
-    [CLSCompliant(false)]
-    public void CheckLastTagWas(uint value) {
-      if (lastTag != value) {
-        throw InvalidProtocolBufferException.InvalidEndTag();
-      }
-    }
-    #endregion
-
-    #region Reading of tags etc
-    /// <summary>
-    /// Attempt to read a field tag, returning 0 if we have reached the end
-    /// of the input data. Protocol message parsers use this to read tags,
-    /// since a protocol message may legally end wherever a tag occurs, and
-    /// zero is not a valid tag number.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadTag() {
-      if (IsAtEnd) {
-        lastTag = 0;
-        return 0;
-      }
-
-      lastTag = ReadRawVarint32();
-      if (lastTag == 0) {
-        // If we actually read zero, that's not a valid tag.
-        throw InvalidProtocolBufferException.InvalidTag();
-      }
-      return lastTag;
-    }
-
-    /// <summary>
-    /// Read a double field from the stream.
-    /// </summary>
-    public double ReadDouble() {
-#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35
-      byte[] bytes = ReadRawBytes(8);
-      return BitConverter.ToDouble(bytes, 0);
-#else
-      return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());
-#endif
-    }
-
-    /// <summary>
-    /// Read a float field from the stream.
-    /// </summary>
-    public float ReadFloat() {
-      // TODO(jonskeet): Test this on different endiannesses
-      uint raw = ReadRawLittleEndian32();
-      byte[] rawBytes = BitConverter.GetBytes(raw);
-      return BitConverter.ToSingle(rawBytes, 0);
-    }
-
-    /// <summary>
-    /// Read a uint64 field from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public ulong ReadUInt64() {
-      return ReadRawVarint64();
-    }
-
-    /// <summary>
-    /// Read an int64 field from the stream.
-    /// </summary>
-    public long ReadInt64() {
-      return (long) ReadRawVarint64();
-    }
-
-    /// <summary>
-    /// Read an int32 field from the stream.
-    /// </summary>
-    public int ReadInt32() {
-      return (int) ReadRawVarint32();
-    }
-
-    /// <summary>
-    /// Read a fixed64 field from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public ulong ReadFixed64() {
-      return ReadRawLittleEndian64();
-    }
-
-    /// <summary>
-    /// Read a fixed32 field from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadFixed32() {
-      return ReadRawLittleEndian32();
-    }
-
-    /// <summary>
-    /// Read a bool field from the stream.
-    /// </summary>
-    public bool ReadBool() {
-      return ReadRawVarint32() != 0;
-    }
-
-    /// <summary>
-    /// Reads a string field from the stream.
-    /// </summary>
-    public String ReadString() {
-      int size = (int) ReadRawVarint32();
-      // No need to read any data for an empty string.
-      if (size == 0) {
-        return "";
-      }
-      if (size <= bufferSize - bufferPos) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
-        //   just copy directly from it.
-        String result = Encoding.UTF8.GetString(buffer, bufferPos, size);
-        bufferPos += size;
-        return result;
-      }
-      // Slow path: Build a byte array first then copy it.
-      return Encoding.UTF8.GetString(ReadRawBytes(size), 0, size);
-    }
-
-    /// <summary>
-    /// Reads a group field value from the stream.
-    /// </summary>    
-    public void ReadGroup(int fieldNumber, IBuilderLite builder,
-                          ExtensionRegistry extensionRegistry) {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.RecursionLimitExceeded();
-      }
-      ++recursionDepth;
-      builder.WeakMergeFrom(this, extensionRegistry);
-      CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
-      --recursionDepth;
-    }
-
-    /// <summary>
-    /// Reads a group field value from the stream and merges it into the given
-    /// UnknownFieldSet.
-    /// </summary>   
-    [Obsolete]
-    public void ReadUnknownGroup(int fieldNumber, IBuilderLite builder)
-    {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.RecursionLimitExceeded();
-      }
-      ++recursionDepth;
-      builder.WeakMergeFrom(this);
-      CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
-      --recursionDepth;
-    }
-
-    /// <summary>
-    /// Reads an embedded message field value from the stream.
-    /// </summary>   
-    public void ReadMessage(IBuilderLite builder, ExtensionRegistry extensionRegistry) {
-      int length = (int) ReadRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.RecursionLimitExceeded();
-      }
-      int oldLimit = PushLimit(length);
-      ++recursionDepth;
-      builder.WeakMergeFrom(this, extensionRegistry);
-      CheckLastTagWas(0);
-      --recursionDepth;
-      PopLimit(oldLimit);
-    }
-
-    /// <summary>
-    /// Reads a bytes field value from the stream.
-    /// </summary>   
-    public ByteString ReadBytes() {
-      int size = (int) ReadRawVarint32();
-      if (size < bufferSize - bufferPos && size > 0) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
-        //   just copy directly from it.
-        ByteString result = ByteString.CopyFrom(buffer, bufferPos, size);
-        bufferPos += size;
-        return result;
-      } else {
-        // Slow path:  Build a byte array first then copy it.
-        return ByteString.CopyFrom(ReadRawBytes(size));
-      }
-    }
-
-    /// <summary>
-    /// Reads a uint32 field value from the stream.
-    /// </summary>   
-    [CLSCompliant(false)]
-    public uint ReadUInt32() {
-      return ReadRawVarint32();
-    }
-
-    /// <summary>
-    /// Reads an enum field value from the stream. The caller is responsible
-    /// for converting the numeric value to an actual enum.
-    /// </summary>   
-    public int ReadEnum() {
-      return (int) ReadRawVarint32();
-    }
-
-    /// <summary>
-    /// Reads an sfixed32 field value from the stream.
-    /// </summary>   
-    public int ReadSFixed32() {
-      return (int) ReadRawLittleEndian32();
-    }
-
-    /// <summary>
-    /// Reads an sfixed64 field value from the stream.
-    /// </summary>   
-    public long ReadSFixed64() {
-      return (long) ReadRawLittleEndian64();
-    }
-
-    /// <summary>
-    /// Reads an sint32 field value from the stream.
-    /// </summary>   
-    public int ReadSInt32() {
-      return DecodeZigZag32(ReadRawVarint32());
-    }
-
-    /// <summary>
-    /// Reads an sint64 field value from the stream.
-    /// </summary>   
-    public long ReadSInt64() {
-      return DecodeZigZag64(ReadRawVarint64());
-    }
-
-    /// <summary>
-    /// Reads a field of any primitive type. Enums, groups and embedded
-    /// messages are not handled by this method.
-    /// </summary>
-    public object ReadPrimitiveField(FieldType fieldType) {
-      switch (fieldType) {
-        case FieldType.Double:   return ReadDouble();
-        case FieldType.Float:    return ReadFloat();
-        case FieldType.Int64:    return ReadInt64();
-        case FieldType.UInt64:   return ReadUInt64();
-        case FieldType.Int32:    return ReadInt32();
-        case FieldType.Fixed64:  return ReadFixed64();
-        case FieldType.Fixed32:  return ReadFixed32();
-        case FieldType.Bool:     return ReadBool();
-        case FieldType.String:   return ReadString();
-        case FieldType.Bytes:    return ReadBytes();
-        case FieldType.UInt32:   return ReadUInt32();
-        case FieldType.SFixed32: return ReadSFixed32();
-        case FieldType.SFixed64: return ReadSFixed64();
-        case FieldType.SInt32:   return ReadSInt32();
-        case FieldType.SInt64:   return ReadSInt64();
-        case FieldType.Group:
-            throw new ArgumentException("ReadPrimitiveField() cannot handle nested groups.");
-        case FieldType.Message:
-            throw new ArgumentException("ReadPrimitiveField() cannot handle embedded messages.");
-        // We don't handle enums because we don't know what to do if the
-        // value is not recognized.
-        case FieldType.Enum:
-            throw new ArgumentException("ReadPrimitiveField() cannot handle enums.");
-        default:
-          throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
-      }
-    }
-    #endregion
-
-    #region Underlying reading primitives
-
-    /// <summary>
-    /// Same code as ReadRawVarint32, but read each byte individually, checking for
-    /// buffer overflow.
-    /// </summary>
-    private uint SlowReadRawVarint32() {
-      int tmp = ReadRawByte();
-      if (tmp < 128) {
-        return (uint)tmp;
-      }
-      int result = tmp & 0x7f;
-      if ((tmp = ReadRawByte()) < 128) {
-        result |= tmp << 7;
-      } else {
-        result |= (tmp & 0x7f) << 7;
-        if ((tmp = ReadRawByte()) < 128) {
-          result |= tmp << 14;
-        } else {
-          result |= (tmp & 0x7f) << 14;
-          if ((tmp = ReadRawByte()) < 128) {
-            result |= tmp << 21;
-          } else {
-            result |= (tmp & 0x7f) << 21;
-            result |= (tmp = ReadRawByte()) << 28;
-            if (tmp >= 128) {
-              // Discard upper 32 bits.
-              for (int i = 0; i < 5; i++) {
-                if (ReadRawByte() < 128) return (uint)result;
-              }
-              throw InvalidProtocolBufferException.MalformedVarint();
-            }
-          }
-        }
-      }
-      return (uint)result;
-    }
-
-    /// <summary>
-    /// Read a raw Varint from the stream.  If larger than 32 bits, discard the upper bits.
-    /// This method is optimised for the case where we've got lots of data in the buffer.
-    /// That means we can check the size just once, then just read directly from the buffer
-    /// without constant rechecking of the buffer length.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadRawVarint32() {
-      if (bufferPos + 5 > bufferSize) {
-        return SlowReadRawVarint32();
-      }
-
-      int tmp = buffer[bufferPos++];
-      if (tmp < 128) {
-        return (uint)tmp;
-      }
-      int result = tmp & 0x7f;
-      if ((tmp = buffer[bufferPos++]) < 128) {
-        result |= tmp << 7;
-      } else {
-        result |= (tmp & 0x7f) << 7;
-        if ((tmp = buffer[bufferPos++]) < 128) {
-          result |= tmp << 14;
-        } else {
-          result |= (tmp & 0x7f) << 14;
-          if ((tmp = buffer[bufferPos++]) < 128) {
-            result |= tmp << 21;
-          } else {
-            result |= (tmp & 0x7f) << 21;
-            result |= (tmp = buffer[bufferPos++]) << 28;
-            if (tmp >= 128) {
-              // Discard upper 32 bits.
-              // Note that this has to use ReadRawByte() as we only ensure we've
-              // got at least 5 bytes at the start of the method. This lets us
-              // use the fast path in more cases, and we rarely hit this section of code.
-              for (int i = 0; i < 5; i++) {
-                if (ReadRawByte() < 128) return (uint)result;
-              }
-              throw InvalidProtocolBufferException.MalformedVarint();
-            }
-          }
-        }
-      }
-      return (uint)result;
-    }
-
-    /// <summary>
-    /// Reads a varint from the input one byte at a time, so that it does not
-    /// read any bytes after the end of the varint. If you simply wrapped the
-    /// stream in a CodedInputStream and used ReadRawVarint32(Stream)}
-    /// then you would probably end up reading past the end of the varint since
-    /// CodedInputStream buffers its input.
-    /// </summary>
-    /// <param name="input"></param>
-    /// <returns></returns>
-    [CLSCompliant(false)]
-    public static uint ReadRawVarint32(Stream input)
-    {
-      int result = 0;
-      int offset = 0;
-      for (; offset < 32; offset += 7) {
-        int b = input.ReadByte();
-        if (b == -1) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        }
-        result |= (b & 0x7f) << offset;
-        if ((b & 0x80) == 0) {
-          return (uint) result;
-        }
-      }
-      // Keep reading up to 64 bits.
-      for (; offset < 64; offset += 7) {
-        int b = input.ReadByte();
-        if (b == -1) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        }
-        if ((b & 0x80) == 0) {
-          return (uint) result;
-        }
-      }
-      throw InvalidProtocolBufferException.MalformedVarint();
-    }
-
-    /// <summary>
-    /// Read a raw varint from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public ulong ReadRawVarint64() {
-      int shift = 0;
-      ulong result = 0;
-      while (shift < 64) {
-        byte b = ReadRawByte();
-        result |= (ulong)(b & 0x7F) << shift;
-        if ((b & 0x80) == 0) {
-          return result;
-        }
-        shift += 7;
-      }
-      throw InvalidProtocolBufferException.MalformedVarint();
-    }
-
-    /// <summary>
-    /// Read a 32-bit little-endian integer from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadRawLittleEndian32() {
-      uint b1 = ReadRawByte();
-      uint b2 = ReadRawByte();
-      uint b3 = ReadRawByte();
-      uint b4 = ReadRawByte();
-      return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
-    }
-
-    /// <summary>
-    /// Read a 64-bit little-endian integer from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public ulong ReadRawLittleEndian64() {
-      ulong b1 = ReadRawByte();
-      ulong b2 = ReadRawByte();
-      ulong b3 = ReadRawByte();
-      ulong b4 = ReadRawByte();
-      ulong b5 = ReadRawByte();
-      ulong b6 = ReadRawByte();
-      ulong b7 = ReadRawByte();
-      ulong b8 = ReadRawByte();
-      return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
-          | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
-    }
-    #endregion
-
-    /// <summary>
-    /// Decode a 32-bit value with ZigZag encoding.
-    /// </summary>
-    /// <remarks>
-    /// ZigZag encodes signed integers into values that can be efficiently
-    /// encoded with varint.  (Otherwise, negative values must be 
-    /// sign-extended to 64 bits to be varint encoded, thus always taking
-    /// 10 bytes on the wire.)
-    /// </remarks>
-    [CLSCompliant(false)]
-    public static int DecodeZigZag32(uint n) {
-      return (int)(n >> 1) ^ -(int)(n & 1);
-    }
-
-    /// <summary>
-    /// Decode a 32-bit value with ZigZag encoding.
-    /// </summary>
-    /// <remarks>
-    /// ZigZag encodes signed integers into values that can be efficiently
-    /// encoded with varint.  (Otherwise, negative values must be 
-    /// sign-extended to 64 bits to be varint encoded, thus always taking
-    /// 10 bytes on the wire.)
-    /// </remarks>
-    [CLSCompliant(false)]
-    public static long DecodeZigZag64(ulong n) {
-      return (long)(n >> 1) ^ -(long)(n & 1);
-    }
-
-    /// <summary>
-    /// Set the maximum message recursion depth.
-    /// </summary>
-    /// <remarks>
-    /// In order to prevent malicious
-    /// messages from causing stack overflows, CodedInputStream limits
-    /// how deeply messages may be nested.  The default limit is 64.
-    /// </remarks>
-    public int SetRecursionLimit(int limit) {
-      if (limit < 0) {
-        throw new ArgumentOutOfRangeException("Recursion limit cannot be negative: " + limit);
-      }
-      int oldLimit = recursionLimit;
-      recursionLimit = limit;
-      return oldLimit;
-    }
-
-    /// <summary>
-    /// Set the maximum message size.
-    /// </summary>
-    /// <remarks>
-    /// In order to prevent malicious messages from exhausting memory or
-    /// causing integer overflows, CodedInputStream limits how large a message may be.
-    /// The default limit is 64MB.  You should set this limit as small
-    /// as you can without harming your app's functionality.  Note that
-    /// size limits only apply when reading from an InputStream, not
-    /// when constructed around a raw byte array (nor with ByteString.NewCodedInput).
-    /// If you want to read several messages from a single CodedInputStream, you
-    /// can call ResetSizeCounter() after each message to avoid hitting the
-    /// size limit.
-    /// </remarks>
-    public int SetSizeLimit(int limit) {
-      if (limit < 0) {
-        throw new ArgumentOutOfRangeException("Size limit cannot be negative: " + limit);
-      }
-      int oldLimit = sizeLimit;
-      sizeLimit = limit;
-      return oldLimit;
-    }
-
-    #region Internal reading and buffer management
-    /// <summary>
-    /// Resets the current size counter to zero (see SetSizeLimit).
-    /// </summary>
-    public void ResetSizeCounter() {
-      totalBytesRetired = 0;
-    }
-
-    /// <summary>
-    /// Sets currentLimit to (current position) + byteLimit. This is called
-    /// when descending into a length-delimited embedded message. The previous
-    /// limit is returned.
-    /// </summary>
-    /// <returns>The old limit.</returns>
-    public int PushLimit(int byteLimit) {
-      if (byteLimit < 0) {
-        throw InvalidProtocolBufferException.NegativeSize();
-      }
-      byteLimit += totalBytesRetired + bufferPos;
-      int oldLimit = currentLimit;
-      if (byteLimit > oldLimit) {
-        throw InvalidProtocolBufferException.TruncatedMessage();
-      }
-      currentLimit = byteLimit;
-
-      RecomputeBufferSizeAfterLimit();
-
-      return oldLimit;
-    }
-
-    private void RecomputeBufferSizeAfterLimit() {
-      bufferSize += bufferSizeAfterLimit;
-      int bufferEnd = totalBytesRetired + bufferSize;
-      if (bufferEnd > currentLimit) {
-        // Limit is in current buffer.
-        bufferSizeAfterLimit = bufferEnd - currentLimit;
-        bufferSize -= bufferSizeAfterLimit;
-      } else {
-        bufferSizeAfterLimit = 0;
-      }
-    }
-
-    /// <summary>
-    /// Discards the current limit, returning the previous limit.
-    /// </summary>
-    public void PopLimit(int oldLimit) {
-      currentLimit = oldLimit;
-      RecomputeBufferSizeAfterLimit();
-    }
-
-    /// <summary>
-    /// Returns whether or not all the data before the limit has been read.
-    /// </summary>
-    /// <returns></returns>
-    public bool ReachedLimit {
-      get {
-        if (currentLimit == int.MaxValue) {
-          return false;
-        }
-        int currentAbsolutePosition = totalBytesRetired + bufferPos;
-        return currentAbsolutePosition >= currentLimit;
-      }
-    }
-
-    /// <summary>
-    /// Returns true if the stream has reached the end of the input. This is the
-    /// case if either the end of the underlying input source has been reached or
-    /// the stream has reached a limit created using PushLimit.
-    /// </summary>
-    public bool IsAtEnd {
-      get {
-        return bufferPos == bufferSize && !RefillBuffer(false);
-      }
-    }
-    
-    /// <summary>
-    /// Called when buffer is empty to read more bytes from the
-    /// input.  If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that
-    /// either there will be at least one byte in the buffer when it returns
-    /// or it will throw an exception.  If <paramref name="mustSucceed"/> is false,
-    /// RefillBuffer() returns false if no more bytes were available.
-    /// </summary>
-    /// <param name="mustSucceed"></param>
-    /// <returns></returns>
-    private bool RefillBuffer(bool mustSucceed)  {
-      if (bufferPos < bufferSize) {
-        throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty.");
-      }
-
-      if (totalBytesRetired + bufferSize == currentLimit) {
-        // Oops, we hit a limit.
-        if (mustSucceed) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        } else {
-          return false;
-        }
-      }
-
-      totalBytesRetired += bufferSize;
-
-      bufferPos = 0;
-      bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length);
-      if (bufferSize < 0) {
-        throw new InvalidOperationException("Stream.Read returned a negative count");
-      }
-      if (bufferSize == 0) {
-        if (mustSucceed) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        } else {
-          return false;
-        }
-      } else {
-        RecomputeBufferSizeAfterLimit();
-        int totalBytesRead =
-          totalBytesRetired + bufferSize + bufferSizeAfterLimit;
-        if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
-          throw InvalidProtocolBufferException.SizeLimitExceeded();
-        }
-        return true;
-      }
-    }
-
-    /// <summary>
-    /// Read one byte from the input.
-    /// </summary>
-    /// <exception cref="InvalidProtocolBufferException">
-    /// the end of the stream or the current limit was reached
-    /// </exception>
-    public byte ReadRawByte() {
-      if (bufferPos == bufferSize) {
-        RefillBuffer(true);
-      }
-      return buffer[bufferPos++];
-    }
-    
-    /// <summary>
-    /// Read a fixed size of bytes from the input.
-    /// </summary>
-    /// <exception cref="InvalidProtocolBufferException">
-    /// the end of the stream or the current limit was reached
-    /// </exception>
-    public byte[] ReadRawBytes(int size) {
-      if (size < 0) {
-        throw InvalidProtocolBufferException.NegativeSize();
-      }
-
-      if (totalBytesRetired + bufferPos + size > currentLimit) {
-        // Read to the end of the stream anyway.
-        SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
-        // Then fail.
-        throw InvalidProtocolBufferException.TruncatedMessage();
-      }
-
-      if (size <= bufferSize - bufferPos) {
-        // We have all the bytes we need already.
-        byte[] bytes = new byte[size];
-        Array.Copy(buffer, bufferPos, bytes, 0, size);
-        bufferPos += size;
-        return bytes;
-      } else if (size < BufferSize) {
-        // Reading more bytes than are in the buffer, but not an excessive number
-        // of bytes.  We can safely allocate the resulting array ahead of time.
-
-        // First copy what we have.
-        byte[] bytes = new byte[size];
-        int pos = bufferSize - bufferPos;
-        Array.Copy(buffer, bufferPos, bytes, 0, pos);
-        bufferPos = bufferSize;
-
-        // We want to use RefillBuffer() and then copy from the buffer into our
-        // byte array rather than reading directly into our byte array because
-        // the input may be unbuffered.
-        RefillBuffer(true);
-
-        while (size - pos > bufferSize) {
-          Array.Copy(buffer, 0, bytes, pos, bufferSize);
-          pos += bufferSize;
-          bufferPos = bufferSize;
-          RefillBuffer(true);
-        }
-
-        Array.Copy(buffer, 0, bytes, pos, size - pos);
-        bufferPos = size - pos;
-
-        return bytes;
-      } else {
-        // The size is very large.  For security reasons, we can't allocate the
-        // entire byte array yet.  The size comes directly from the input, so a
-        // maliciously-crafted message could provide a bogus very large size in
-        // order to trick the app into allocating a lot of memory.  We avoid this
-        // by allocating and reading only a small chunk at a time, so that the
-        // malicious message must actually *be* extremely large to cause
-        // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
-
-        // Remember the buffer markers since we'll have to copy the bytes out of
-        // it later.
-        int originalBufferPos = bufferPos;
-        int originalBufferSize = bufferSize;
-
-        // Mark the current buffer consumed.
-        totalBytesRetired += bufferSize;
-        bufferPos = 0;
-        bufferSize = 0;
-
-        // Read all the rest of the bytes we need.
-        int sizeLeft = size - (originalBufferSize - originalBufferPos);
-        List<byte[]> chunks = new List<byte[]>();
-
-        while (sizeLeft > 0) {
-          byte[] chunk = new byte[Math.Min(sizeLeft, BufferSize)];
-          int pos = 0;
-          while (pos < chunk.Length) {
-            int n = (input == null) ? -1 : input.Read(chunk, pos, chunk.Length - pos);
-            if (n <= 0) {
-              throw InvalidProtocolBufferException.TruncatedMessage();
-            }
-            totalBytesRetired += n;
-            pos += n;
-          }
-          sizeLeft -= chunk.Length;
-          chunks.Add(chunk);
-        }
-
-        // OK, got everything.  Now concatenate it all into one buffer.
-        byte[] bytes = new byte[size];
-
-        // Start by copying the leftover bytes from this.buffer.
-        int newPos = originalBufferSize - originalBufferPos;
-        Array.Copy(buffer, originalBufferPos, bytes, 0, newPos);
-
-        // And now all the chunks.
-        foreach (byte[] chunk in chunks) {
-          Array.Copy(chunk, 0, bytes, newPos, chunk.Length);
-          newPos += chunk.Length;
-        }
-
-        // Done.
-        return bytes;
-      }
-    }
-
-    /// <summary>
-    /// Reads and discards a single field, given its tag value.
-    /// </summary>
-    /// <returns>false if the tag is an end-group tag, in which case
-    /// nothing is skipped. Otherwise, returns true.</returns>
-    [CLSCompliant(false)]
-    public bool SkipField(uint tag) {
-      switch (WireFormat.GetTagWireType(tag)) {
-        case WireFormat.WireType.Varint:
-          ReadInt32();
-          return true;
-        case WireFormat.WireType.Fixed64:
-          ReadRawLittleEndian64();
-          return true;
-        case WireFormat.WireType.LengthDelimited:
-          SkipRawBytes((int) ReadRawVarint32());
-          return true;
-        case WireFormat.WireType.StartGroup:
-          SkipMessage();
-          CheckLastTagWas(
-            WireFormat.MakeTag(WireFormat.GetTagFieldNumber(tag),
-                               WireFormat.WireType.EndGroup));
-          return true;
-        case WireFormat.WireType.EndGroup:
-          return false;
-        case WireFormat.WireType.Fixed32:
-          ReadRawLittleEndian32();
-          return true;
-        default:
-          throw InvalidProtocolBufferException.InvalidWireType();
-      }
-    }
-
-    /// <summary>
-    /// Reads and discards an entire message.  This will read either until EOF
-    /// or until an endgroup tag, whichever comes first.
-    /// </summary>
-    public void SkipMessage() {
-      while (true) {
-        uint tag = ReadTag();
-        if (tag == 0 || !SkipField(tag)) {
-          return;
-        }
-      }
-    }
-
-    /// <summary>
-    /// Reads and discards <paramref name="size"/> bytes.
-    /// </summary>
-    /// <exception cref="InvalidProtocolBufferException">the end of the stream
-    /// or the current limit was reached</exception>
-    public void SkipRawBytes(int size) {
-      if (size < 0) {
-        throw InvalidProtocolBufferException.NegativeSize();
-      }
-
-      if (totalBytesRetired + bufferPos + size > currentLimit) {
-        // Read to the end of the stream anyway.
-        SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
-        // Then fail.
-        throw InvalidProtocolBufferException.TruncatedMessage();
-      }
-
-      if (size <= bufferSize - bufferPos) {
-        // We have all the bytes we need already.
-        bufferPos += size;
-      } else {
-        // Skipping more bytes than are in the buffer.  First skip what we have.
-        int pos = bufferSize - bufferPos;
-        totalBytesRetired += pos;
-        bufferPos = 0;
-        bufferSize = 0;
-
-        // Then skip directly from the InputStream for the rest.
-        if (pos < size) {
-          if (input == null) {
-            throw InvalidProtocolBufferException.TruncatedMessage();
-          }
-          SkipImpl(size - pos);
-          totalBytesRetired += size - pos;
-        }
-      }
-    }
-
-    /// <summary>
-    /// Abstraction of skipping to cope with streams which can't really skip.
-    /// </summary>
-    private void SkipImpl(int amountToSkip) {
-      if (input.CanSeek) {
-        long previousPosition = input.Position;
-        input.Position += amountToSkip;
-        if (input.Position != previousPosition + amountToSkip) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        }
-      } else {
-        byte[] skipBuffer = new byte[1024];
-        while (amountToSkip > 0) {
-          int bytesRead = input.Read(skipBuffer, 0, skipBuffer.Length);
-          if (bytesRead <= 0) {
-            throw InvalidProtocolBufferException.TruncatedMessage();
-          }
-          amountToSkip -= bytesRead;
-        }
-      }
-    }
-    #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 System.Text;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Readings and decodes protocol message fields.
+    /// </summary>
+    /// <remarks>
+    /// This class contains two kinds of methods:  methods that read specific
+    /// protocol message constructs and field types (e.g. ReadTag and
+    /// ReadInt32) and methods that read low-level values (e.g.
+    /// ReadRawVarint32 and ReadRawBytes).  If you are reading encoded protocol
+    /// messages, you should use the former methods, but if you are reading some
+    /// other format of your own design, use the latter. The names of the former
+    /// methods are taken from the protocol buffer type names, not .NET types.
+    /// (Hence ReadFloat instead of ReadSingle, and ReadBool instead of ReadBoolean.)
+    /// 
+    /// TODO(jonskeet): Consider whether recursion and size limits shouldn't be readonly,
+    /// set at construction time.
+    /// </remarks>
+    public sealed class CodedInputStream
+    {
+        private readonly byte[] buffer;
+        private int bufferSize;
+        private int bufferSizeAfterLimit = 0;
+        private int bufferPos = 0;
+        private readonly Stream input;
+        private uint lastTag = 0;
+
+        internal const int DefaultRecursionLimit = 64;
+        internal const int DefaultSizeLimit = 64 << 20; // 64MB
+        public const int BufferSize = 4096;
+
+        /// <summary>
+        /// The total number of bytes read before the current buffer. The
+        /// total bytes read up to the current position can be computed as
+        /// totalBytesRetired + bufferPos.
+        /// </summary>
+        private int totalBytesRetired = 0;
+
+        /// <summary>
+        /// The absolute position of the end of the current message.
+        /// </summary> 
+        private int currentLimit = int.MaxValue;
+
+        /// <summary>
+        /// <see cref="SetRecursionLimit"/>
+        /// </summary>
+        private int recursionDepth = 0;
+
+        private int recursionLimit = DefaultRecursionLimit;
+
+        /// <summary>
+        /// <see cref="SetSizeLimit"/>
+        /// </summary>
+        private int sizeLimit = DefaultSizeLimit;
+
+        #region Construction
+
+        /// <summary>
+        /// Creates a new CodedInputStream reading data from the given
+        /// stream.
+        /// </summary>
+        public static CodedInputStream CreateInstance(Stream input)
+        {
+            return new CodedInputStream(input);
+        }
+
+        /// <summary>
+        /// Creates a new CodedInputStream reading data from the given
+        /// byte array.
+        /// </summary>
+        public static CodedInputStream CreateInstance(byte[] buf)
+        {
+            return new CodedInputStream(buf, 0, buf.Length);
+        }
+
+        /// <summary>
+        /// Creates a new CodedInputStream that reads from the given
+        /// byte array slice.
+        /// </summary>
+        public static CodedInputStream CreateInstance(byte[] buf, int offset, int length)
+        {
+            return new CodedInputStream(buf, offset, length);
+        }
+
+        private CodedInputStream(byte[] buffer, int offset, int length)
+        {
+            this.buffer = buffer;
+            this.bufferPos = offset;
+            this.bufferSize = offset + length;
+            this.input = null;
+        }
+
+        private CodedInputStream(Stream input)
+        {
+            this.buffer = new byte[BufferSize];
+            this.bufferSize = 0;
+            this.input = input;
+        }
+
+        #endregion
+
+        #region Validation
+
+        /// <summary>
+        /// Verifies that the last call to ReadTag() returned the given tag value.
+        /// This is used to verify that a nested group ended with the correct
+        /// end tag.
+        /// </summary>
+        /// <exception cref="InvalidProtocolBufferException">The last
+        /// tag read was not the one specified</exception>
+        [CLSCompliant(false)]
+        public void CheckLastTagWas(uint value)
+        {
+            if (lastTag != value)
+            {
+                throw InvalidProtocolBufferException.InvalidEndTag();
+            }
+        }
+
+        #endregion
+
+        #region Reading of tags etc
+
+        /// <summary>
+        /// Attempt to read a field tag, returning 0 if we have reached the end
+        /// of the input data. Protocol message parsers use this to read tags,
+        /// since a protocol message may legally end wherever a tag occurs, and
+        /// zero is not a valid tag number.
+        /// </summary>
+        [CLSCompliant(false)]
+        public uint ReadTag()
+        {
+            if (IsAtEnd)
+            {
+                lastTag = 0;
+                return 0;
+            }
+
+            lastTag = ReadRawVarint32();
+            if (lastTag == 0)
+            {
+                // If we actually read zero, that's not a valid tag.
+                throw InvalidProtocolBufferException.InvalidTag();
+            }
+            return lastTag;
+        }
+
+        /// <summary>
+        /// Read a double field from the stream.
+        /// </summary>
+        public double ReadDouble()
+        {
+#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35
+            byte[] bytes = ReadRawBytes(8);
+            return BitConverter.ToDouble(bytes, 0);
+#else
+      return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());
+#endif
+        }
+
+        /// <summary>
+        /// Read a float field from the stream.
+        /// </summary>
+        public float ReadFloat()
+        {
+            // TODO(jonskeet): Test this on different endiannesses
+            uint raw = ReadRawLittleEndian32();
+            byte[] rawBytes = BitConverter.GetBytes(raw);
+            return BitConverter.ToSingle(rawBytes, 0);
+        }
+
+        /// <summary>
+        /// Read a uint64 field from the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public ulong ReadUInt64()
+        {
+            return ReadRawVarint64();
+        }
+
+        /// <summary>
+        /// Read an int64 field from the stream.
+        /// </summary>
+        public long ReadInt64()
+        {
+            return (long) ReadRawVarint64();
+        }
+
+        /// <summary>
+        /// Read an int32 field from the stream.
+        /// </summary>
+        public int ReadInt32()
+        {
+            return (int) ReadRawVarint32();
+        }
+
+        /// <summary>
+        /// Read a fixed64 field from the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public ulong ReadFixed64()
+        {
+            return ReadRawLittleEndian64();
+        }
+
+        /// <summary>
+        /// Read a fixed32 field from the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public uint ReadFixed32()
+        {
+            return ReadRawLittleEndian32();
+        }
+
+        /// <summary>
+        /// Read a bool field from the stream.
+        /// </summary>
+        public bool ReadBool()
+        {
+            return ReadRawVarint32() != 0;
+        }
+
+        /// <summary>
+        /// Reads a string field from the stream.
+        /// </summary>
+        public String ReadString()
+        {
+            int size = (int) ReadRawVarint32();
+            // No need to read any data for an empty string.
+            if (size == 0)
+            {
+                return "";
+            }
+            if (size <= bufferSize - bufferPos)
+            {
+                // Fast path:  We already have the bytes in a contiguous buffer, so
+                //   just copy directly from it.
+                String result = Encoding.UTF8.GetString(buffer, bufferPos, size);
+                bufferPos += size;
+                return result;
+            }
+            // Slow path: Build a byte array first then copy it.
+            return Encoding.UTF8.GetString(ReadRawBytes(size), 0, size);
+        }
+
+        /// <summary>
+        /// Reads a group field value from the stream.
+        /// </summary>    
+        public void ReadGroup(int fieldNumber, IBuilderLite builder,
+                              ExtensionRegistry extensionRegistry)
+        {
+            if (recursionDepth >= recursionLimit)
+            {
+                throw InvalidProtocolBufferException.RecursionLimitExceeded();
+            }
+            ++recursionDepth;
+            builder.WeakMergeFrom(this, extensionRegistry);
+            CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
+            --recursionDepth;
+        }
+
+        /// <summary>
+        /// Reads a group field value from the stream and merges it into the given
+        /// UnknownFieldSet.
+        /// </summary>   
+        [Obsolete]
+        public void ReadUnknownGroup(int fieldNumber, IBuilderLite builder)
+        {
+            if (recursionDepth >= recursionLimit)
+            {
+                throw InvalidProtocolBufferException.RecursionLimitExceeded();
+            }
+            ++recursionDepth;
+            builder.WeakMergeFrom(this);
+            CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
+            --recursionDepth;
+        }
+
+        /// <summary>
+        /// Reads an embedded message field value from the stream.
+        /// </summary>   
+        public void ReadMessage(IBuilderLite builder, ExtensionRegistry extensionRegistry)
+        {
+            int length = (int) ReadRawVarint32();
+            if (recursionDepth >= recursionLimit)
+            {
+                throw InvalidProtocolBufferException.RecursionLimitExceeded();
+            }
+            int oldLimit = PushLimit(length);
+            ++recursionDepth;
+            builder.WeakMergeFrom(this, extensionRegistry);
+            CheckLastTagWas(0);
+            --recursionDepth;
+            PopLimit(oldLimit);
+        }
+
+        /// <summary>
+        /// Reads a bytes field value from the stream.
+        /// </summary>   
+        public ByteString ReadBytes()
+        {
+            int size = (int) ReadRawVarint32();
+            if (size < bufferSize - bufferPos && size > 0)
+            {
+                // Fast path:  We already have the bytes in a contiguous buffer, so
+                //   just copy directly from it.
+                ByteString result = ByteString.CopyFrom(buffer, bufferPos, size);
+                bufferPos += size;
+                return result;
+            }
+            else
+            {
+                // Slow path:  Build a byte array first then copy it.
+                return ByteString.CopyFrom(ReadRawBytes(size));
+            }
+        }
+
+        /// <summary>
+        /// Reads a uint32 field value from the stream.
+        /// </summary>   
+        [CLSCompliant(false)]
+        public uint ReadUInt32()
+        {
+            return ReadRawVarint32();
+        }
+
+        /// <summary>
+        /// Reads an enum field value from the stream. The caller is responsible
+        /// for converting the numeric value to an actual enum.
+        /// </summary>   
+        public int ReadEnum()
+        {
+            return (int) ReadRawVarint32();
+        }
+
+        /// <summary>
+        /// Reads an sfixed32 field value from the stream.
+        /// </summary>   
+        public int ReadSFixed32()
+        {
+            return (int) ReadRawLittleEndian32();
+        }
+
+        /// <summary>
+        /// Reads an sfixed64 field value from the stream.
+        /// </summary>   
+        public long ReadSFixed64()
+        {
+            return (long) ReadRawLittleEndian64();
+        }
+
+        /// <summary>
+        /// Reads an sint32 field value from the stream.
+        /// </summary>   
+        public int ReadSInt32()
+        {
+            return DecodeZigZag32(ReadRawVarint32());
+        }
+
+        /// <summary>
+        /// Reads an sint64 field value from the stream.
+        /// </summary>   
+        public long ReadSInt64()
+        {
+            return DecodeZigZag64(ReadRawVarint64());
+        }
+
+        /// <summary>
+        /// Reads a field of any primitive type. Enums, groups and embedded
+        /// messages are not handled by this method.
+        /// </summary>
+        public object ReadPrimitiveField(FieldType fieldType)
+        {
+            switch (fieldType)
+            {
+                case FieldType.Double:
+                    return ReadDouble();
+                case FieldType.Float:
+                    return ReadFloat();
+                case FieldType.Int64:
+                    return ReadInt64();
+                case FieldType.UInt64:
+                    return ReadUInt64();
+                case FieldType.Int32:
+                    return ReadInt32();
+                case FieldType.Fixed64:
+                    return ReadFixed64();
+                case FieldType.Fixed32:
+                    return ReadFixed32();
+                case FieldType.Bool:
+                    return ReadBool();
+                case FieldType.String:
+                    return ReadString();
+                case FieldType.Bytes:
+                    return ReadBytes();
+                case FieldType.UInt32:
+                    return ReadUInt32();
+                case FieldType.SFixed32:
+                    return ReadSFixed32();
+                case FieldType.SFixed64:
+                    return ReadSFixed64();
+                case FieldType.SInt32:
+                    return ReadSInt32();
+                case FieldType.SInt64:
+                    return ReadSInt64();
+                case FieldType.Group:
+                    throw new ArgumentException("ReadPrimitiveField() cannot handle nested groups.");
+                case FieldType.Message:
+                    throw new ArgumentException("ReadPrimitiveField() cannot handle embedded messages.");
+                    // We don't handle enums because we don't know what to do if the
+                    // value is not recognized.
+                case FieldType.Enum:
+                    throw new ArgumentException("ReadPrimitiveField() cannot handle enums.");
+                default:
+                    throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
+            }
+        }
+
+        #endregion
+
+        #region Underlying reading primitives
+
+        /// <summary>
+        /// Same code as ReadRawVarint32, but read each byte individually, checking for
+        /// buffer overflow.
+        /// </summary>
+        private uint SlowReadRawVarint32()
+        {
+            int tmp = ReadRawByte();
+            if (tmp < 128)
+            {
+                return (uint) tmp;
+            }
+            int result = tmp & 0x7f;
+            if ((tmp = ReadRawByte()) < 128)
+            {
+                result |= tmp << 7;
+            }
+            else
+            {
+                result |= (tmp & 0x7f) << 7;
+                if ((tmp = ReadRawByte()) < 128)
+                {
+                    result |= tmp << 14;
+                }
+                else
+                {
+                    result |= (tmp & 0x7f) << 14;
+                    if ((tmp = ReadRawByte()) < 128)
+                    {
+                        result |= tmp << 21;
+                    }
+                    else
+                    {
+                        result |= (tmp & 0x7f) << 21;
+                        result |= (tmp = ReadRawByte()) << 28;
+                        if (tmp >= 128)
+                        {
+                            // Discard upper 32 bits.
+                            for (int i = 0; i < 5; i++)
+                            {
+                                if (ReadRawByte() < 128) return (uint) result;
+                            }
+                            throw InvalidProtocolBufferException.MalformedVarint();
+                        }
+                    }
+                }
+            }
+            return (uint) result;
+        }
+
+        /// <summary>
+        /// Read a raw Varint from the stream.  If larger than 32 bits, discard the upper bits.
+        /// This method is optimised for the case where we've got lots of data in the buffer.
+        /// That means we can check the size just once, then just read directly from the buffer
+        /// without constant rechecking of the buffer length.
+        /// </summary>
+        [CLSCompliant(false)]
+        public uint ReadRawVarint32()
+        {
+            if (bufferPos + 5 > bufferSize)
+            {
+                return SlowReadRawVarint32();
+            }
+
+            int tmp = buffer[bufferPos++];
+            if (tmp < 128)
+            {
+                return (uint) tmp;
+            }
+            int result = tmp & 0x7f;
+            if ((tmp = buffer[bufferPos++]) < 128)
+            {
+                result |= tmp << 7;
+            }
+            else
+            {
+                result |= (tmp & 0x7f) << 7;
+                if ((tmp = buffer[bufferPos++]) < 128)
+                {
+                    result |= tmp << 14;
+                }
+                else
+                {
+                    result |= (tmp & 0x7f) << 14;
+                    if ((tmp = buffer[bufferPos++]) < 128)
+                    {
+                        result |= tmp << 21;
+                    }
+                    else
+                    {
+                        result |= (tmp & 0x7f) << 21;
+                        result |= (tmp = buffer[bufferPos++]) << 28;
+                        if (tmp >= 128)
+                        {
+                            // Discard upper 32 bits.
+                            // Note that this has to use ReadRawByte() as we only ensure we've
+                            // got at least 5 bytes at the start of the method. This lets us
+                            // use the fast path in more cases, and we rarely hit this section of code.
+                            for (int i = 0; i < 5; i++)
+                            {
+                                if (ReadRawByte() < 128) return (uint) result;
+                            }
+                            throw InvalidProtocolBufferException.MalformedVarint();
+                        }
+                    }
+                }
+            }
+            return (uint) result;
+        }
+
+        /// <summary>
+        /// Reads a varint from the input one byte at a time, so that it does not
+        /// read any bytes after the end of the varint. If you simply wrapped the
+        /// stream in a CodedInputStream and used ReadRawVarint32(Stream)}
+        /// then you would probably end up reading past the end of the varint since
+        /// CodedInputStream buffers its input.
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [CLSCompliant(false)]
+        public static uint ReadRawVarint32(Stream input)
+        {
+            int result = 0;
+            int offset = 0;
+            for (; offset < 32; offset += 7)
+            {
+                int b = input.ReadByte();
+                if (b == -1)
+                {
+                    throw InvalidProtocolBufferException.TruncatedMessage();
+                }
+                result |= (b & 0x7f) << offset;
+                if ((b & 0x80) == 0)
+                {
+                    return (uint) result;
+                }
+            }
+            // Keep reading up to 64 bits.
+            for (; offset < 64; offset += 7)
+            {
+                int b = input.ReadByte();
+                if (b == -1)
+                {
+                    throw InvalidProtocolBufferException.TruncatedMessage();
+                }
+                if ((b & 0x80) == 0)
+                {
+                    return (uint) result;
+                }
+            }
+            throw InvalidProtocolBufferException.MalformedVarint();
+        }
+
+        /// <summary>
+        /// Read a raw varint from the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public ulong ReadRawVarint64()
+        {
+            int shift = 0;
+            ulong result = 0;
+            while (shift < 64)
+            {
+                byte b = ReadRawByte();
+                result |= (ulong) (b & 0x7F) << shift;
+                if ((b & 0x80) == 0)
+                {
+                    return result;
+                }
+                shift += 7;
+            }
+            throw InvalidProtocolBufferException.MalformedVarint();
+        }
+
+        /// <summary>
+        /// Read a 32-bit little-endian integer from the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public uint ReadRawLittleEndian32()
+        {
+            uint b1 = ReadRawByte();
+            uint b2 = ReadRawByte();
+            uint b3 = ReadRawByte();
+            uint b4 = ReadRawByte();
+            return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
+        }
+
+        /// <summary>
+        /// Read a 64-bit little-endian integer from the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public ulong ReadRawLittleEndian64()
+        {
+            ulong b1 = ReadRawByte();
+            ulong b2 = ReadRawByte();
+            ulong b3 = ReadRawByte();
+            ulong b4 = ReadRawByte();
+            ulong b5 = ReadRawByte();
+            ulong b6 = ReadRawByte();
+            ulong b7 = ReadRawByte();
+            ulong b8 = ReadRawByte();
+            return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
+                   | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Decode a 32-bit value with ZigZag encoding.
+        /// </summary>
+        /// <remarks>
+        /// ZigZag encodes signed integers into values that can be efficiently
+        /// encoded with varint.  (Otherwise, negative values must be 
+        /// sign-extended to 64 bits to be varint encoded, thus always taking
+        /// 10 bytes on the wire.)
+        /// </remarks>
+        [CLSCompliant(false)]
+        public static int DecodeZigZag32(uint n)
+        {
+            return (int) (n >> 1) ^ -(int) (n & 1);
+        }
+
+        /// <summary>
+        /// Decode a 32-bit value with ZigZag encoding.
+        /// </summary>
+        /// <remarks>
+        /// ZigZag encodes signed integers into values that can be efficiently
+        /// encoded with varint.  (Otherwise, negative values must be 
+        /// sign-extended to 64 bits to be varint encoded, thus always taking
+        /// 10 bytes on the wire.)
+        /// </remarks>
+        [CLSCompliant(false)]
+        public static long DecodeZigZag64(ulong n)
+        {
+            return (long) (n >> 1) ^ -(long) (n & 1);
+        }
+
+        /// <summary>
+        /// Set the maximum message recursion depth.
+        /// </summary>
+        /// <remarks>
+        /// In order to prevent malicious
+        /// messages from causing stack overflows, CodedInputStream limits
+        /// how deeply messages may be nested.  The default limit is 64.
+        /// </remarks>
+        public int SetRecursionLimit(int limit)
+        {
+            if (limit < 0)
+            {
+                throw new ArgumentOutOfRangeException("Recursion limit cannot be negative: " + limit);
+            }
+            int oldLimit = recursionLimit;
+            recursionLimit = limit;
+            return oldLimit;
+        }
+
+        /// <summary>
+        /// Set the maximum message size.
+        /// </summary>
+        /// <remarks>
+        /// In order to prevent malicious messages from exhausting memory or
+        /// causing integer overflows, CodedInputStream limits how large a message may be.
+        /// The default limit is 64MB.  You should set this limit as small
+        /// as you can without harming your app's functionality.  Note that
+        /// size limits only apply when reading from an InputStream, not
+        /// when constructed around a raw byte array (nor with ByteString.NewCodedInput).
+        /// If you want to read several messages from a single CodedInputStream, you
+        /// can call ResetSizeCounter() after each message to avoid hitting the
+        /// size limit.
+        /// </remarks>
+        public int SetSizeLimit(int limit)
+        {
+            if (limit < 0)
+            {
+                throw new ArgumentOutOfRangeException("Size limit cannot be negative: " + limit);
+            }
+            int oldLimit = sizeLimit;
+            sizeLimit = limit;
+            return oldLimit;
+        }
+
+        #region Internal reading and buffer management
+
+        /// <summary>
+        /// Resets the current size counter to zero (see SetSizeLimit).
+        /// </summary>
+        public void ResetSizeCounter()
+        {
+            totalBytesRetired = 0;
+        }
+
+        /// <summary>
+        /// Sets currentLimit to (current position) + byteLimit. This is called
+        /// when descending into a length-delimited embedded message. The previous
+        /// limit is returned.
+        /// </summary>
+        /// <returns>The old limit.</returns>
+        public int PushLimit(int byteLimit)
+        {
+            if (byteLimit < 0)
+            {
+                throw InvalidProtocolBufferException.NegativeSize();
+            }
+            byteLimit += totalBytesRetired + bufferPos;
+            int oldLimit = currentLimit;
+            if (byteLimit > oldLimit)
+            {
+                throw InvalidProtocolBufferException.TruncatedMessage();
+            }
+            currentLimit = byteLimit;
+
+            RecomputeBufferSizeAfterLimit();
+
+            return oldLimit;
+        }
+
+        private void RecomputeBufferSizeAfterLimit()
+        {
+            bufferSize += bufferSizeAfterLimit;
+            int bufferEnd = totalBytesRetired + bufferSize;
+            if (bufferEnd > currentLimit)
+            {
+                // Limit is in current buffer.
+                bufferSizeAfterLimit = bufferEnd - currentLimit;
+                bufferSize -= bufferSizeAfterLimit;
+            }
+            else
+            {
+                bufferSizeAfterLimit = 0;
+            }
+        }
+
+        /// <summary>
+        /// Discards the current limit, returning the previous limit.
+        /// </summary>
+        public void PopLimit(int oldLimit)
+        {
+            currentLimit = oldLimit;
+            RecomputeBufferSizeAfterLimit();
+        }
+
+        /// <summary>
+        /// Returns whether or not all the data before the limit has been read.
+        /// </summary>
+        /// <returns></returns>
+        public bool ReachedLimit
+        {
+            get
+            {
+                if (currentLimit == int.MaxValue)
+                {
+                    return false;
+                }
+                int currentAbsolutePosition = totalBytesRetired + bufferPos;
+                return currentAbsolutePosition >= currentLimit;
+            }
+        }
+
+        /// <summary>
+        /// Returns true if the stream has reached the end of the input. This is the
+        /// case if either the end of the underlying input source has been reached or
+        /// the stream has reached a limit created using PushLimit.
+        /// </summary>
+        public bool IsAtEnd
+        {
+            get { return bufferPos == bufferSize && !RefillBuffer(false); }
+        }
+
+        /// <summary>
+        /// Called when buffer is empty to read more bytes from the
+        /// input.  If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that
+        /// either there will be at least one byte in the buffer when it returns
+        /// or it will throw an exception.  If <paramref name="mustSucceed"/> is false,
+        /// RefillBuffer() returns false if no more bytes were available.
+        /// </summary>
+        /// <param name="mustSucceed"></param>
+        /// <returns></returns>
+        private bool RefillBuffer(bool mustSucceed)
+        {
+            if (bufferPos < bufferSize)
+            {
+                throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty.");
+            }
+
+            if (totalBytesRetired + bufferSize == currentLimit)
+            {
+                // Oops, we hit a limit.
+                if (mustSucceed)
+                {
+                    throw InvalidProtocolBufferException.TruncatedMessage();
+                }
+                else
+                {
+                    return false;
+                }
+            }
+
+            totalBytesRetired += bufferSize;
+
+            bufferPos = 0;
+            bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length);
+            if (bufferSize < 0)
+            {
+                throw new InvalidOperationException("Stream.Read returned a negative count");
+            }
+            if (bufferSize == 0)
+            {
+                if (mustSucceed)
+                {
+                    throw InvalidProtocolBufferException.TruncatedMessage();
+                }
+                else
+                {
+                    return false;
+                }
+            }
+            else
+            {
+                RecomputeBufferSizeAfterLimit();
+                int totalBytesRead =
+                    totalBytesRetired + bufferSize + bufferSizeAfterLimit;
+                if (totalBytesRead > sizeLimit || totalBytesRead < 0)
+                {
+                    throw InvalidProtocolBufferException.SizeLimitExceeded();
+                }
+                return true;
+            }
+        }
+
+        /// <summary>
+        /// Read one byte from the input.
+        /// </summary>
+        /// <exception cref="InvalidProtocolBufferException">
+        /// the end of the stream or the current limit was reached
+        /// </exception>
+        public byte ReadRawByte()
+        {
+            if (bufferPos == bufferSize)
+            {
+                RefillBuffer(true);
+            }
+            return buffer[bufferPos++];
+        }
+
+        /// <summary>
+        /// Read a fixed size of bytes from the input.
+        /// </summary>
+        /// <exception cref="InvalidProtocolBufferException">
+        /// the end of the stream or the current limit was reached
+        /// </exception>
+        public byte[] ReadRawBytes(int size)
+        {
+            if (size < 0)
+            {
+                throw InvalidProtocolBufferException.NegativeSize();
+            }
+
+            if (totalBytesRetired + bufferPos + size > currentLimit)
+            {
+                // Read to the end of the stream anyway.
+                SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+                // Then fail.
+                throw InvalidProtocolBufferException.TruncatedMessage();
+            }
+
+            if (size <= bufferSize - bufferPos)
+            {
+                // We have all the bytes we need already.
+                byte[] bytes = new byte[size];
+                Array.Copy(buffer, bufferPos, bytes, 0, size);
+                bufferPos += size;
+                return bytes;
+            }
+            else if (size < BufferSize)
+            {
+                // Reading more bytes than are in the buffer, but not an excessive number
+                // of bytes.  We can safely allocate the resulting array ahead of time.
+
+                // First copy what we have.
+                byte[] bytes = new byte[size];
+                int pos = bufferSize - bufferPos;
+                Array.Copy(buffer, bufferPos, bytes, 0, pos);
+                bufferPos = bufferSize;
+
+                // We want to use RefillBuffer() and then copy from the buffer into our
+                // byte array rather than reading directly into our byte array because
+                // the input may be unbuffered.
+                RefillBuffer(true);
+
+                while (size - pos > bufferSize)
+                {
+                    Array.Copy(buffer, 0, bytes, pos, bufferSize);
+                    pos += bufferSize;
+                    bufferPos = bufferSize;
+                    RefillBuffer(true);
+                }
+
+                Array.Copy(buffer, 0, bytes, pos, size - pos);
+                bufferPos = size - pos;
+
+                return bytes;
+            }
+            else
+            {
+                // The size is very large.  For security reasons, we can't allocate the
+                // entire byte array yet.  The size comes directly from the input, so a
+                // maliciously-crafted message could provide a bogus very large size in
+                // order to trick the app into allocating a lot of memory.  We avoid this
+                // by allocating and reading only a small chunk at a time, so that the
+                // malicious message must actually *be* extremely large to cause
+                // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
+
+                // Remember the buffer markers since we'll have to copy the bytes out of
+                // it later.
+                int originalBufferPos = bufferPos;
+                int originalBufferSize = bufferSize;
+
+                // Mark the current buffer consumed.
+                totalBytesRetired += bufferSize;
+                bufferPos = 0;
+                bufferSize = 0;
+
+                // Read all the rest of the bytes we need.
+                int sizeLeft = size - (originalBufferSize - originalBufferPos);
+                List<byte[]> chunks = new List<byte[]>();
+
+                while (sizeLeft > 0)
+                {
+                    byte[] chunk = new byte[Math.Min(sizeLeft, BufferSize)];
+                    int pos = 0;
+                    while (pos < chunk.Length)
+                    {
+                        int n = (input == null) ? -1 : input.Read(chunk, pos, chunk.Length - pos);
+                        if (n <= 0)
+                        {
+                            throw InvalidProtocolBufferException.TruncatedMessage();
+                        }
+                        totalBytesRetired += n;
+                        pos += n;
+                    }
+                    sizeLeft -= chunk.Length;
+                    chunks.Add(chunk);
+                }
+
+                // OK, got everything.  Now concatenate it all into one buffer.
+                byte[] bytes = new byte[size];
+
+                // Start by copying the leftover bytes from this.buffer.
+                int newPos = originalBufferSize - originalBufferPos;
+                Array.Copy(buffer, originalBufferPos, bytes, 0, newPos);
+
+                // And now all the chunks.
+                foreach (byte[] chunk in chunks)
+                {
+                    Array.Copy(chunk, 0, bytes, newPos, chunk.Length);
+                    newPos += chunk.Length;
+                }
+
+                // Done.
+                return bytes;
+            }
+        }
+
+        /// <summary>
+        /// Reads and discards a single field, given its tag value.
+        /// </summary>
+        /// <returns>false if the tag is an end-group tag, in which case
+        /// nothing is skipped. Otherwise, returns true.</returns>
+        [CLSCompliant(false)]
+        public bool SkipField(uint tag)
+        {
+            switch (WireFormat.GetTagWireType(tag))
+            {
+                case WireFormat.WireType.Varint:
+                    ReadInt32();
+                    return true;
+                case WireFormat.WireType.Fixed64:
+                    ReadRawLittleEndian64();
+                    return true;
+                case WireFormat.WireType.LengthDelimited:
+                    SkipRawBytes((int) ReadRawVarint32());
+                    return true;
+                case WireFormat.WireType.StartGroup:
+                    SkipMessage();
+                    CheckLastTagWas(
+                        WireFormat.MakeTag(WireFormat.GetTagFieldNumber(tag),
+                                           WireFormat.WireType.EndGroup));
+                    return true;
+                case WireFormat.WireType.EndGroup:
+                    return false;
+                case WireFormat.WireType.Fixed32:
+                    ReadRawLittleEndian32();
+                    return true;
+                default:
+                    throw InvalidProtocolBufferException.InvalidWireType();
+            }
+        }
+
+        /// <summary>
+        /// Reads and discards an entire message.  This will read either until EOF
+        /// or until an endgroup tag, whichever comes first.
+        /// </summary>
+        public void SkipMessage()
+        {
+            while (true)
+            {
+                uint tag = ReadTag();
+                if (tag == 0 || !SkipField(tag))
+                {
+                    return;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Reads and discards <paramref name="size"/> bytes.
+        /// </summary>
+        /// <exception cref="InvalidProtocolBufferException">the end of the stream
+        /// or the current limit was reached</exception>
+        public void SkipRawBytes(int size)
+        {
+            if (size < 0)
+            {
+                throw InvalidProtocolBufferException.NegativeSize();
+            }
+
+            if (totalBytesRetired + bufferPos + size > currentLimit)
+            {
+                // Read to the end of the stream anyway.
+                SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+                // Then fail.
+                throw InvalidProtocolBufferException.TruncatedMessage();
+            }
+
+            if (size <= bufferSize - bufferPos)
+            {
+                // We have all the bytes we need already.
+                bufferPos += size;
+            }
+            else
+            {
+                // Skipping more bytes than are in the buffer.  First skip what we have.
+                int pos = bufferSize - bufferPos;
+                totalBytesRetired += pos;
+                bufferPos = 0;
+                bufferSize = 0;
+
+                // Then skip directly from the InputStream for the rest.
+                if (pos < size)
+                {
+                    if (input == null)
+                    {
+                        throw InvalidProtocolBufferException.TruncatedMessage();
+                    }
+                    SkipImpl(size - pos);
+                    totalBytesRetired += size - pos;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Abstraction of skipping to cope with streams which can't really skip.
+        /// </summary>
+        private void SkipImpl(int amountToSkip)
+        {
+            if (input.CanSeek)
+            {
+                long previousPosition = input.Position;
+                input.Position += amountToSkip;
+                if (input.Position != previousPosition + amountToSkip)
+                {
+                    throw InvalidProtocolBufferException.TruncatedMessage();
+                }
+            }
+            else
+            {
+                byte[] skipBuffer = new byte[1024];
+                while (amountToSkip > 0)
+                {
+                    int bytesRead = input.Read(skipBuffer, 0, skipBuffer.Length);
+                    if (bytesRead <= 0)
+                    {
+                        throw InvalidProtocolBufferException.TruncatedMessage();
+                    }
+                    amountToSkip -= bytesRead;
+                }
+            }
+        }
+
+        #endregion
+    }
+}

+ 1423 - 1146
src/ProtocolBuffers/CodedOutputStream.cs

@@ -1,1146 +1,1423 @@
-#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;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers {
-
-  /// <summary>
-  /// Encodes and writes protocol message fields.
-  /// </summary>
-  /// <remarks>
-  /// This class contains two kinds of methods:  methods that write specific
-  /// protocol message constructs and field types (e.g. WriteTag and
-  /// WriteInt32) and methods that write low-level values (e.g.
-  /// WriteRawVarint32 and WriteRawBytes).  If you are writing encoded protocol
-  /// messages, you should use the former methods, but if you are writing some
-  /// other format of your own design, use the latter. The names of the former
-  /// methods are taken from the protocol buffer type names, not .NET types.
-  /// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.)
-  /// </remarks>
-  public sealed class CodedOutputStream {
-    /// <summary>
-    /// The buffer size used by CreateInstance(Stream).
-    /// </summary>
-    public static readonly int DefaultBufferSize = 4096;
-
-    private readonly byte[] buffer;
-    private readonly int limit;
-    private int position;
-    private readonly Stream output;
-
-    #region Construction
-    private CodedOutputStream(byte[] buffer, int offset, int length) {
-      this.output = null;
-      this.buffer = buffer;
-      this.position = offset;
-      this.limit = offset + length;
-    }
-
-    private CodedOutputStream(Stream output, byte[] buffer) {
-      this.output = output;
-      this.buffer = buffer;
-      this.position = 0;
-      this.limit = buffer.Length;
-    }
-
-    /// <summary>
-    /// Creates a new CodedOutputStream which write to the given stream.
-    /// </summary>
-    public static CodedOutputStream CreateInstance(Stream output) {
-      return CreateInstance(output, DefaultBufferSize);
-    }
-
-    /// <summary>
-    /// Creates a new CodedOutputStream which write to the given stream and uses
-    /// the specified buffer size.
-    /// </summary>
-    public static CodedOutputStream CreateInstance(Stream output, int bufferSize) {
-      return new CodedOutputStream(output, new byte[bufferSize]);
-    }
-
-    /// <summary>
-    /// Creates a new CodedOutputStream that writes directly to the given
-    /// byte array. If more bytes are written than fit in the array,
-    /// OutOfSpaceException will be thrown.
-    /// </summary>
-    public static CodedOutputStream CreateInstance(byte[] flatArray) {
-      return CreateInstance(flatArray, 0, flatArray.Length);
-    }
-
-    /// <summary>
-    /// Creates a new CodedOutputStream that writes directly to the given
-    /// byte array slice. If more bytes are written than fit in the array,
-    /// OutOfSpaceException will be thrown.
-    /// </summary>
-    public static CodedOutputStream CreateInstance(byte[] flatArray, int offset, int length) {
-      return new CodedOutputStream(flatArray, offset, length);
-    }
-    #endregion
-
-    #region Writing of tags etc
-    /// <summary>
-    /// Writes a double field value, including tag, to the stream.
-    /// </summary>
-    public void WriteDouble(int fieldNumber, double value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
-      WriteDoubleNoTag(value);
-    }
-
-    /// <summary>
-    /// Writes a float field value, including tag, to the stream.
-    /// </summary>
-    public void WriteFloat(int fieldNumber, float value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
-      WriteFloatNoTag(value);
-    }
-
-    /// <summary>
-    /// Writes a uint64 field value, including tag, to the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public void WriteUInt64(int fieldNumber, ulong value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Varint);
-      WriteRawVarint64(value);
-    }
-
-    /// <summary>
-    /// Writes an int64 field value, including tag, to the stream.
-    /// </summary>
-    public void WriteInt64(int fieldNumber, long value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Varint);
-      WriteRawVarint64((ulong)value);
-    }
-
-    /// <summary>
-    /// Writes an int32 field value, including tag, to the stream.
-    /// </summary>
-    public void WriteInt32(int fieldNumber, int value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Varint);
-      if (value >= 0) {
-        WriteRawVarint32((uint)value);
-      } else {
-        // Must sign-extend.
-        WriteRawVarint64((ulong)value);
-      }
-    }
-
-    /// <summary>
-    /// Writes a fixed64 field value, including tag, to the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public void WriteFixed64(int fieldNumber, ulong value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
-      WriteRawLittleEndian64(value);
-    }
-
-    /// <summary>
-    /// Writes a fixed32 field value, including tag, to the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public void WriteFixed32(int fieldNumber, uint value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
-      WriteRawLittleEndian32(value);
-    }
-
-    /// <summary>
-    /// Writes a bool field value, including tag, to the stream.
-    /// </summary>
-    public void WriteBool(int fieldNumber, bool value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Varint);
-      WriteRawByte(value ? (byte)1 : (byte)0);
-    }
-
-    /// <summary>
-    /// Writes a string field value, including tag, to the stream.
-    /// </summary>
-    public void WriteString(int fieldNumber, string value) {
-      WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
-      // Optimise the case where we have enough space to write
-      // the string directly to the buffer, which should be common.
-      int length = Encoding.UTF8.GetByteCount(value);
-      WriteRawVarint32((uint) length);
-      if (limit - position >= length) {
-        Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, position);
-        position += length;
-      } else {
-        byte[] bytes = Encoding.UTF8.GetBytes(value);
-        WriteRawBytes(bytes);
-      }
-    }
-
-    /// <summary>
-    /// Writes a group field value, including tag, to the stream.
-    /// </summary>
-    public void WriteGroup(int fieldNumber, IMessageLite value) {
-      WriteTag(fieldNumber, WireFormat.WireType.StartGroup);
-      value.WriteTo(this);
-      WriteTag(fieldNumber, WireFormat.WireType.EndGroup);
-    }
-
-    [Obsolete]
-    public void WriteUnknownGroup(int fieldNumber, IMessageLite value) {
-      WriteTag(fieldNumber, WireFormat.WireType.StartGroup);
-      value.WriteTo(this);
-      WriteTag(fieldNumber, WireFormat.WireType.EndGroup);
-    }
-
-    public void WriteMessage(int fieldNumber, IMessageLite value) {
-      WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
-      WriteRawVarint32((uint)value.SerializedSize);
-      value.WriteTo(this);
-    }
-
-    public void WriteBytes(int fieldNumber, ByteString value) {
-      // TODO(jonskeet): Optimise this! (No need to copy the bytes twice.)
-      WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
-      byte[] bytes = value.ToByteArray();
-      WriteRawVarint32((uint)bytes.Length);
-      WriteRawBytes(bytes);
-    }
-
-    [CLSCompliant(false)]
-    public void WriteUInt32(int fieldNumber, uint value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Varint);
-      WriteRawVarint32(value);
-    }
-
-    public void WriteEnum(int fieldNumber, int value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Varint);
-      WriteRawVarint32((uint)value);
-    }
-
-    public void WriteSFixed32(int fieldNumber, int value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
-      WriteRawLittleEndian32((uint)value);
-    }
-
-    public void WriteSFixed64(int fieldNumber, long value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
-      WriteRawLittleEndian64((ulong)value);
-    }
-
-    public void WriteSInt32(int fieldNumber, int value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Varint);
-      WriteRawVarint32(EncodeZigZag32(value));
-    }
-
-    public void WriteSInt64(int fieldNumber, long value) {
-      WriteTag(fieldNumber, WireFormat.WireType.Varint);
-      WriteRawVarint64(EncodeZigZag64(value));
-    }
-
-    public void WriteMessageSetExtension(int fieldNumber, IMessageLite value) {
-      WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.StartGroup);
-      WriteUInt32(WireFormat.MessageSetField.TypeID, (uint)fieldNumber);
-      WriteMessage(WireFormat.MessageSetField.Message, value);
-      WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup);
-    }
-
-    public void WriteRawMessageSetExtension(int fieldNumber, ByteString value) {
-      WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.StartGroup);
-      WriteUInt32(WireFormat.MessageSetField.TypeID, (uint)fieldNumber);
-      WriteBytes(WireFormat.MessageSetField.Message, value);
-      WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup);
-    }
-
-    public void WriteField(FieldType fieldType, int fieldNumber, object value) {
-      switch (fieldType) {
-        case FieldType.Double: WriteDouble(fieldNumber, (double)value); break;
-        case FieldType.Float: WriteFloat(fieldNumber, (float)value); break;
-        case FieldType.Int64: WriteInt64(fieldNumber, (long)value); break;
-        case FieldType.UInt64: WriteUInt64(fieldNumber, (ulong)value); break;
-        case FieldType.Int32: WriteInt32(fieldNumber, (int)value); break;
-        case FieldType.Fixed64: WriteFixed64(fieldNumber, (ulong)value); break;
-        case FieldType.Fixed32: WriteFixed32(fieldNumber, (uint)value); break;
-        case FieldType.Bool: WriteBool(fieldNumber, (bool)value); break;
-        case FieldType.String: WriteString(fieldNumber, (string)value); break;
-        case FieldType.Group: WriteGroup(fieldNumber, (IMessageLite)value); break;
-        case FieldType.Message: WriteMessage(fieldNumber, (IMessageLite)value); break;
-        case FieldType.Bytes: WriteBytes(fieldNumber, (ByteString)value); break;
-        case FieldType.UInt32: WriteUInt32(fieldNumber, (uint)value); break;
-        case FieldType.SFixed32: WriteSFixed32(fieldNumber, (int)value); break;
-        case FieldType.SFixed64: WriteSFixed64(fieldNumber, (long)value); break;
-        case FieldType.SInt32: WriteSInt32(fieldNumber, (int)value); break;
-        case FieldType.SInt64: WriteSInt64(fieldNumber, (long)value); break;
-        case FieldType.Enum: WriteEnum(fieldNumber, ((IEnumLite)value).Number);
-          break;
-      }
-    }
-
-    public void WriteFieldNoTag(FieldType fieldType, object value) {
-      switch (fieldType) {
-        case FieldType.Double: WriteDoubleNoTag((double)value); break;
-        case FieldType.Float: WriteFloatNoTag((float)value); break;
-        case FieldType.Int64: WriteInt64NoTag((long)value); break;
-        case FieldType.UInt64: WriteUInt64NoTag((ulong)value); break;
-        case FieldType.Int32: WriteInt32NoTag((int)value); break;
-        case FieldType.Fixed64: WriteFixed64NoTag((ulong)value); break;
-        case FieldType.Fixed32: WriteFixed32NoTag((uint)value); break;
-        case FieldType.Bool: WriteBoolNoTag((bool)value); break;
-        case FieldType.String: WriteStringNoTag((string)value); break;
-        case FieldType.Group: WriteGroupNoTag((IMessageLite)value); break;
-        case FieldType.Message: WriteMessageNoTag((IMessageLite)value); break;
-        case FieldType.Bytes: WriteBytesNoTag((ByteString)value); break;
-        case FieldType.UInt32: WriteUInt32NoTag((uint)value); break;
-        case FieldType.SFixed32: WriteSFixed32NoTag((int)value); break;
-        case FieldType.SFixed64: WriteSFixed64NoTag((long)value); break;
-        case FieldType.SInt32: WriteSInt32NoTag((int)value); break;
-        case FieldType.SInt64: WriteSInt64NoTag((long)value); break;
-        case FieldType.Enum: WriteEnumNoTag(((IEnumLite)value).Number);
-          break;
-      }
-    }
-    #endregion
-
-    #region Writing of values without tags
-    /// <summary>
-    /// Writes a double field value, including tag, to the stream.
-    /// </summary>
-    public void WriteDoubleNoTag(double value) {
-      // TODO(jonskeet): Test this on different endiannesses
-#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35
-      byte[] bytes = BitConverter.GetBytes(value);
-      WriteRawBytes(bytes, 0, 8);
-#else
-      WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value));
-#endif
-    }
-
-    /// <summary>
-    /// Writes a float field value, without a tag, to the stream.
-    /// </summary>
-    public void WriteFloatNoTag(float value) {
-      // TODO(jonskeet): Test this on different endiannesses
-      byte[] rawBytes = BitConverter.GetBytes(value);
-      uint asInteger = BitConverter.ToUInt32(rawBytes, 0);
-      WriteRawLittleEndian32(asInteger);
-    }
-
-    /// <summary>
-    /// Writes a uint64 field value, without a tag, to the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public void WriteUInt64NoTag(ulong value) {
-      WriteRawVarint64(value);
-    }
-
-    /// <summary>
-    /// Writes an int64 field value, without a tag, to the stream.
-    /// </summary>
-    public void WriteInt64NoTag(long value) {
-      WriteRawVarint64((ulong)value);
-    }
-
-    /// <summary>
-    /// Writes an int32 field value, without a tag, to the stream.
-    /// </summary>
-    public void WriteInt32NoTag(int value) {
-      if (value >= 0) {
-        WriteRawVarint32((uint)value);
-      } else {
-        // Must sign-extend.
-        WriteRawVarint64((ulong)value);
-      }
-    }
-
-    /// <summary>
-    /// Writes a fixed64 field value, without a tag, to the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public void WriteFixed64NoTag(ulong value) {
-      WriteRawLittleEndian64(value);
-    }
-
-    /// <summary>
-    /// Writes a fixed32 field value, without a tag, to the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public void WriteFixed32NoTag(uint value) {
-      WriteRawLittleEndian32(value);
-    }
-
-    /// <summary>
-    /// Writes a bool field value, without a tag, to the stream.
-    /// </summary>
-    public void WriteBoolNoTag(bool value) {
-      WriteRawByte(value ? (byte)1 : (byte)0);
-    }
-
-    /// <summary>
-    /// Writes a string field value, without a tag, to the stream.
-    /// </summary>
-    public void WriteStringNoTag(string value) {
-      // Optimise the case where we have enough space to write
-      // the string directly to the buffer, which should be common.
-      int length = Encoding.UTF8.GetByteCount(value);
-      WriteRawVarint32((uint)length);
-      if (limit - position >= length) {
-        Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, position);
-        position += length;
-      } else {
-        byte[] bytes = Encoding.UTF8.GetBytes(value);
-        WriteRawBytes(bytes);
-      }
-    }
-
-    /// <summary>
-    /// Writes a group field value, without a tag, to the stream.
-    /// </summary>
-    public void WriteGroupNoTag(IMessageLite value) {
-      value.WriteTo(this);
-    }
-
-    public void WriteMessageNoTag(IMessageLite value) {
-      WriteRawVarint32((uint)value.SerializedSize);
-      value.WriteTo(this);
-    }
-
-    public void WriteBytesNoTag(ByteString value) {
-      // TODO(jonskeet): Optimise this! (No need to copy the bytes twice.)
-      byte[] bytes = value.ToByteArray();
-      WriteRawVarint32((uint)bytes.Length);
-      WriteRawBytes(bytes);
-    }
-
-    [CLSCompliant(false)]
-    public void WriteUInt32NoTag(uint value) {
-      WriteRawVarint32(value);
-    }
-
-    public void WriteEnumNoTag(int value) {
-      WriteRawVarint32((uint)value);
-    }
-
-    public void WriteSFixed32NoTag(int value) {
-      WriteRawLittleEndian32((uint)value);
-    }
-
-    public void WriteSFixed64NoTag(long value) {
-      WriteRawLittleEndian64((ulong)value);
-    }
-
-    public void WriteSInt32NoTag(int value) {
-      WriteRawVarint32(EncodeZigZag32(value));
-    }
-
-    public void WriteSInt64NoTag(long value) {
-      WriteRawVarint64(EncodeZigZag64(value));
-    }
-
-    #endregion
-
-    #region Underlying writing primitives
-    /// <summary>
-    /// Encodes and writes a tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public void WriteTag(int fieldNumber, WireFormat.WireType type) {
-      WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
-    }
-
-    private void SlowWriteRawVarint32(uint value) {
-      while (true) {
-        if ((value & ~0x7F) == 0) {
-          WriteRawByte(value);
-          return;
-        } else {
-          WriteRawByte((value & 0x7F) | 0x80);
-          value >>= 7;
-        }
-      }
-    }
-
-    /// <summary>
-    /// Writes a 32 bit value as a varint. The fast route is taken when
-    /// there's enough buffer space left to whizz through without checking
-    /// for each byte; otherwise, we resort to calling WriteRawByte each time.
-    /// </summary>
-    [CLSCompliant(false)]
-    public void WriteRawVarint32(uint value) {
-      if (position + 5 > limit) {
-        SlowWriteRawVarint32(value);
-        return;
-      }
-
-      while (true) {
-        if ((value & ~0x7F) == 0) {
-          buffer[position++] = (byte) value;
-          return;
-        } else {
-          buffer[position++] = (byte)((value & 0x7F) | 0x80);
-          value >>= 7;
-        }
-      }
-    }
-
-    [CLSCompliant(false)]
-    public void WriteRawVarint64(ulong value) {
-      while (true) {
-        if ((value & ~0x7FUL) == 0) {
-          WriteRawByte((uint)value);
-          return;
-        } else {
-          WriteRawByte(((uint)value & 0x7F) | 0x80);
-          value >>= 7;
-        }
-      }
-    }
-
-    [CLSCompliant(false)]
-    public void WriteRawLittleEndian32(uint value) {
-      WriteRawByte((byte)value);
-      WriteRawByte((byte)(value >> 8));
-      WriteRawByte((byte)(value >> 16));
-      WriteRawByte((byte)(value >> 24));
-    }
-
-    [CLSCompliant(false)]
-    public void WriteRawLittleEndian64(ulong value) {
-      WriteRawByte((byte)value);
-      WriteRawByte((byte)(value >> 8));
-      WriteRawByte((byte)(value >> 16));
-      WriteRawByte((byte)(value >> 24));
-      WriteRawByte((byte)(value >> 32));
-      WriteRawByte((byte)(value >> 40));
-      WriteRawByte((byte)(value >> 48));
-      WriteRawByte((byte)(value >> 56));
-    }
-
-    public void WriteRawByte(byte value) {
-      if (position == limit) {
-        RefreshBuffer();
-      }
-
-      buffer[position++] = value;
-    }
-
-    [CLSCompliant(false)]
-    public void WriteRawByte(uint value) {
-      WriteRawByte((byte)value);
-    }
-
-    /// <summary>
-    /// Writes out an array of bytes.
-    /// </summary>
-    public void WriteRawBytes(byte[] value) {
-      WriteRawBytes(value, 0, value.Length);
-    }
-
-    /// <summary>
-    /// Writes out part of an array of bytes.
-    /// </summary>
-    public void WriteRawBytes(byte[] value, int offset, int length) {
-      if (limit - position >= length) {
-        Array.Copy(value, offset, buffer, position, length);
-        // We have room in the current buffer.
-        position += length;
-      } else {
-        // Write extends past current buffer.  Fill the rest of this buffer and
-        // flush.
-        int bytesWritten = limit - position;
-        Array.Copy(value, offset, buffer, position, bytesWritten);
-        offset += bytesWritten;
-        length -= bytesWritten;
-        position = limit;
-        RefreshBuffer();
-
-        // Now deal with the rest.
-        // Since we have an output stream, this is our buffer
-        // and buffer offset == 0
-        if (length <= limit) {
-          // Fits in new buffer.
-          Array.Copy(value, offset, buffer, 0, length);
-          position = length;
-        } else {
-          // Write is very big.  Let's do it all at once.
-          output.Write(value, offset, length);
-        }
-      }
-    }
-    #endregion
-
-    #region Size computations
-
-    const int LittleEndian64Size = 8;
-    const int LittleEndian32Size = 4;
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// double field, including the tag.
-    /// </summary>
-    public static int ComputeDoubleSize(int fieldNumber, double value) {
-      return ComputeTagSize(fieldNumber) + LittleEndian64Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// float field, including the tag.
-    /// </summary>
-    public static int ComputeFloatSize(int fieldNumber, float value) {
-      return ComputeTagSize(fieldNumber) + LittleEndian32Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// uint64 field, including the tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeUInt64Size(int fieldNumber, ulong value) {
-      return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// int64 field, including the tag.
-    /// </summary>
-    public static int ComputeInt64Size(int fieldNumber, long value) {
-      return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size((ulong)value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// int32 field, including the tag.
-    /// </summary>
-    public static int ComputeInt32Size(int fieldNumber, int value) {
-      if (value >= 0) {
-        return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint)value);
-      } else {
-        // Must sign-extend.
-        return ComputeTagSize(fieldNumber) + 10;
-      }
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// fixed64 field, including the tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeFixed64Size(int fieldNumber, ulong value) {
-      return ComputeTagSize(fieldNumber) + LittleEndian64Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// fixed32 field, including the tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeFixed32Size(int fieldNumber, uint value) {
-      return ComputeTagSize(fieldNumber) + LittleEndian32Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// bool field, including the tag.
-    /// </summary>
-    public static int ComputeBoolSize(int fieldNumber, bool value) {
-      return ComputeTagSize(fieldNumber) + 1;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// string field, including the tag.
-    /// </summary>
-    public static int ComputeStringSize(int fieldNumber, String value) {
-      int byteArraySize = Encoding.UTF8.GetByteCount(value);
-      return ComputeTagSize(fieldNumber) +
-             ComputeRawVarint32Size((uint)byteArraySize) +
-             byteArraySize;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// group field, including the tag.
-    /// </summary>
-    public static int ComputeGroupSize(int fieldNumber, IMessageLite value) {
-      return ComputeTagSize(fieldNumber) * 2 + value.SerializedSize;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// group field represented by an UnknownFieldSet, including the tag.
-    /// </summary>
-    [Obsolete]
-    public static int ComputeUnknownGroupSize(int fieldNumber,
-                                              IMessageLite value) {
-      return ComputeTagSize(fieldNumber) * 2 + value.SerializedSize;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// embedded message field, including the tag.
-    /// </summary>
-    public static int ComputeMessageSize(int fieldNumber, IMessageLite value) {
-      int size = value.SerializedSize;
-      return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint)size) + size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// bytes field, including the tag.
-    /// </summary>
-    public static int ComputeBytesSize(int fieldNumber, ByteString value) {
-      return ComputeTagSize(fieldNumber) +
-             ComputeRawVarint32Size((uint)value.Length) +
-             value.Length;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// uint32 field, including the tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeUInt32Size(int fieldNumber, uint value) {
-      return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// enum field, including the tag. The caller is responsible for
-    /// converting the enum value to its numeric value.
-    /// </summary>
-    public static int ComputeEnumSize(int fieldNumber, int value) {
-      return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint)value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// sfixed32 field, including the tag.
-    /// </summary>
-    public static int ComputeSFixed32Size(int fieldNumber, int value) {
-      return ComputeTagSize(fieldNumber) + LittleEndian32Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// sfixed64 field, including the tag.
-    /// </summary>
-    public static int ComputeSFixed64Size(int fieldNumber, long value) {
-      return ComputeTagSize(fieldNumber) + LittleEndian64Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// sint32 field, including the tag.
-    /// </summary>
-    public static int ComputeSInt32Size(int fieldNumber, int value) {
-      return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(EncodeZigZag32(value));
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// sint64 field, including the tag.
-    /// </summary>
-    public static int ComputeSInt64Size(int fieldNumber, long value) {
-      return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(EncodeZigZag64(value));
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// double field, including the tag.
-    /// </summary>
-    public static int ComputeDoubleSizeNoTag(double value) {
-      return LittleEndian64Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// float field, including the tag.
-    /// </summary>
-    public static int ComputeFloatSizeNoTag(float value) {
-      return LittleEndian32Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// uint64 field, including the tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeUInt64SizeNoTag(ulong value) {
-      return ComputeRawVarint64Size(value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// int64 field, including the tag.
-    /// </summary>
-    public static int ComputeInt64SizeNoTag(long value) {
-      return ComputeRawVarint64Size((ulong)value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// int32 field, including the tag.
-    /// </summary>
-    public static int ComputeInt32SizeNoTag(int value) {
-      if (value >= 0) {
-        return ComputeRawVarint32Size((uint)value);
-      } else {
-        // Must sign-extend.
-        return 10;
-      }
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// fixed64 field, including the tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeFixed64SizeNoTag(ulong value) {
-      return LittleEndian64Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// fixed32 field, including the tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeFixed32SizeNoTag(uint value) {
-      return LittleEndian32Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// bool field, including the tag.
-    /// </summary>
-    public static int ComputeBoolSizeNoTag(bool value) {
-      return 1;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// string field, including the tag.
-    /// </summary>
-    public static int ComputeStringSizeNoTag(String value) {
-      int byteArraySize = Encoding.UTF8.GetByteCount(value);
-      return ComputeRawVarint32Size((uint)byteArraySize) +
-             byteArraySize;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// group field, including the tag.
-    /// </summary>
-    public static int ComputeGroupSizeNoTag(IMessageLite value) {
-      return value.SerializedSize;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// group field represented by an UnknownFieldSet, including the tag.
-    /// </summary>
-    [Obsolete]
-    public static int ComputeUnknownGroupSizeNoTag(IMessageLite value) {
-      return value.SerializedSize;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// embedded message field, including the tag.
-    /// </summary>
-    public static int ComputeMessageSizeNoTag(IMessageLite value) {
-      int size = value.SerializedSize;
-      return ComputeRawVarint32Size((uint)size) + size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// bytes field, including the tag.
-    /// </summary>
-    public static int ComputeBytesSizeNoTag(ByteString value) {
-      return ComputeRawVarint32Size((uint)value.Length) +
-             value.Length;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// uint32 field, including the tag.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeUInt32SizeNoTag(uint value) {
-      return ComputeRawVarint32Size(value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// enum field, including the tag. The caller is responsible for
-    /// converting the enum value to its numeric value.
-    /// </summary>
-    public static int ComputeEnumSizeNoTag(int value) {
-      return ComputeRawVarint32Size((uint)value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// sfixed32 field, including the tag.
-    /// </summary>
-    public static int ComputeSFixed32SizeNoTag(int value) {
-      return LittleEndian32Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// sfixed64 field, including the tag.
-    /// </summary>
-    public static int ComputeSFixed64SizeNoTag(long value) {
-      return LittleEndian64Size;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// sint32 field, including the tag.
-    /// </summary>
-    public static int ComputeSInt32SizeNoTag(int value) {
-      return ComputeRawVarint32Size(EncodeZigZag32(value));
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// sint64 field, including the tag.
-    /// </summary>
-    public static int ComputeSInt64SizeNoTag(long value) {
-      return ComputeRawVarint64Size(EncodeZigZag64(value));
-    }
-
-    /*
-     * Compute the number of bytes that would be needed to encode a
-     * MessageSet extension to the stream.  For historical reasons,
-     * the wire format differs from normal fields.
-     */
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// MessageSet extension to the stream. For historical reasons,
-    /// the wire format differs from normal fields.
-    /// </summary>
-    public static int ComputeMessageSetExtensionSize(int fieldNumber, IMessageLite value) {
-      return ComputeTagSize(WireFormat.MessageSetField.Item) * 2 +
-             ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) +
-             ComputeMessageSize(WireFormat.MessageSetField.Message, value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode an
-    /// unparsed MessageSet extension field to the stream. For
-    /// historical reasons, the wire format differs from normal fields.
-    /// </summary>
-    public static int ComputeRawMessageSetExtensionSize(int fieldNumber, ByteString value) {
-      return ComputeTagSize(WireFormat.MessageSetField.Item) * 2 +
-             ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) +
-             ComputeBytesSize(WireFormat.MessageSetField.Message, value);
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a varint.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeRawVarint32Size(uint value) {
-      if ((value & (0xffffffff << 7)) == 0) return 1;
-      if ((value & (0xffffffff << 14)) == 0) return 2;
-      if ((value & (0xffffffff << 21)) == 0) return 3;
-      if ((value & (0xffffffff << 28)) == 0) return 4;
-      return 5;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a varint.
-    /// </summary>
-    [CLSCompliant(false)]
-    public static int ComputeRawVarint64Size(ulong value) {
-      if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
-      if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
-      if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
-      if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
-      if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
-      if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
-      if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
-      if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
-      if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
-      return 10;
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// field of arbitrary type, including the tag, to the stream.
-    /// </summary>
-    public static int ComputeFieldSize(FieldType fieldType, int fieldNumber, Object value) {
-      switch (fieldType) {
-        case FieldType.Double: return ComputeDoubleSize(fieldNumber, (double)value);
-        case FieldType.Float: return ComputeFloatSize(fieldNumber, (float)value);
-        case FieldType.Int64: return ComputeInt64Size(fieldNumber, (long)value);
-        case FieldType.UInt64: return ComputeUInt64Size(fieldNumber, (ulong)value);
-        case FieldType.Int32: return ComputeInt32Size(fieldNumber, (int)value);
-        case FieldType.Fixed64: return ComputeFixed64Size(fieldNumber, (ulong)value);
-        case FieldType.Fixed32: return ComputeFixed32Size(fieldNumber, (uint)value);
-        case FieldType.Bool: return ComputeBoolSize(fieldNumber, (bool)value);
-        case FieldType.String: return ComputeStringSize(fieldNumber, (string)value);
-        case FieldType.Group: return ComputeGroupSize(fieldNumber, (IMessageLite)value);
-        case FieldType.Message: return ComputeMessageSize(fieldNumber, (IMessageLite)value);
-        case FieldType.Bytes: return ComputeBytesSize(fieldNumber, (ByteString)value);
-        case FieldType.UInt32: return ComputeUInt32Size(fieldNumber, (uint)value);
-        case FieldType.SFixed32: return ComputeSFixed32Size(fieldNumber, (int)value);
-        case FieldType.SFixed64: return ComputeSFixed64Size(fieldNumber, (long)value);
-        case FieldType.SInt32: return ComputeSInt32Size(fieldNumber, (int)value);
-        case FieldType.SInt64: return ComputeSInt64Size(fieldNumber, (long)value);
-        case FieldType.Enum: return ComputeEnumSize(fieldNumber, ((IEnumLite)value).Number);
-        default:
-          throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
-      }
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a
-    /// field of arbitrary type, excluding the tag, to the stream.
-    /// </summary>
-    public static int ComputeFieldSizeNoTag(FieldType fieldType, Object value) {
-      switch (fieldType) {
-        case FieldType.Double: return ComputeDoubleSizeNoTag((double)value);
-        case FieldType.Float: return ComputeFloatSizeNoTag((float)value);
-        case FieldType.Int64: return ComputeInt64SizeNoTag((long)value);
-        case FieldType.UInt64: return ComputeUInt64SizeNoTag((ulong)value);
-        case FieldType.Int32: return ComputeInt32SizeNoTag((int)value);
-        case FieldType.Fixed64: return ComputeFixed64SizeNoTag((ulong)value);
-        case FieldType.Fixed32: return ComputeFixed32SizeNoTag((uint)value);
-        case FieldType.Bool: return ComputeBoolSizeNoTag((bool)value);
-        case FieldType.String: return ComputeStringSizeNoTag((string)value);
-        case FieldType.Group: return ComputeGroupSizeNoTag((IMessageLite)value);
-        case FieldType.Message: return ComputeMessageSizeNoTag((IMessageLite)value);
-        case FieldType.Bytes: return ComputeBytesSizeNoTag((ByteString)value);
-        case FieldType.UInt32: return ComputeUInt32SizeNoTag((uint)value);
-        case FieldType.SFixed32: return ComputeSFixed32SizeNoTag((int)value);
-        case FieldType.SFixed64: return ComputeSFixed64SizeNoTag((long)value);
-        case FieldType.SInt32: return ComputeSInt32SizeNoTag((int)value);
-        case FieldType.SInt64: return ComputeSInt64SizeNoTag((long)value);
-        case FieldType.Enum: return ComputeEnumSizeNoTag(((IEnumLite)value).Number);
-        default:
-          throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
-      }
-    }
-
-    /// <summary>
-    /// Compute the number of bytes that would be needed to encode a tag.
-    /// </summary>
-    public static int ComputeTagSize(int fieldNumber) {
-      return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0));
-    }
-    #endregion
-
-    /// <summary>
-    /// Encode a 32-bit value with ZigZag encoding.
-    /// </summary>
-    /// <remarks>
-    /// ZigZag encodes signed integers into values that can be efficiently
-    /// encoded with varint.  (Otherwise, negative values must be 
-    /// sign-extended to 64 bits to be varint encoded, thus always taking
-    /// 10 bytes on the wire.)
-    /// </remarks>
-    [CLSCompliant(false)]
-    public static uint EncodeZigZag32(int n) {
-      // Note:  the right-shift must be arithmetic
-      return (uint)((n << 1) ^ (n >> 31));
-    }
-
-    /// <summary>
-    /// Encode a 64-bit value with ZigZag encoding.
-    /// </summary>
-    /// <remarks>
-    /// ZigZag encodes signed integers into values that can be efficiently
-    /// encoded with varint.  (Otherwise, negative values must be 
-    /// sign-extended to 64 bits to be varint encoded, thus always taking
-    /// 10 bytes on the wire.)
-    /// </remarks>
-    [CLSCompliant(false)]
-    public static ulong EncodeZigZag64(long n) {
-      return (ulong)((n << 1) ^ (n >> 63));
-    }
-
-    private void RefreshBuffer() {
-      if (output == null) {
-        // We're writing to a single buffer.
-        throw new OutOfSpaceException();
-      }
-
-      // Since we have an output stream, this is our buffer
-      // and buffer offset == 0
-      output.Write(buffer, 0, position);
-      position = 0;
-    }
-
-    /// <summary>
-    /// Indicates that a CodedOutputStream wrapping a flat byte array
-    /// ran out of space.
-    /// </summary>
-    public sealed class OutOfSpaceException : IOException {
-      internal OutOfSpaceException()
-        : base("CodedOutputStream was writing to a flat byte array and ran out of space.") {
-      }
-    }
-
-    public void Flush() {
-      if (output != null) {
-        RefreshBuffer();
-      }
-    }
-
-    /// <summary>
-    /// Verifies that SpaceLeft returns zero. It's common to create a byte array
-    /// that is exactly big enough to hold a message, then write to it with
-    /// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that
-    /// the message was actually as big as expected, which can help bugs.
-    /// </summary>
-    public void CheckNoSpaceLeft() {
-      if (SpaceLeft != 0) {
-        throw new InvalidOperationException("Did not write as much data as expected.");
-      }
-    }
-
-    /// <summary>
-    /// If writing to a flat array, returns the space left in the array. Otherwise,
-    /// throws an InvalidOperationException.
-    /// </summary>
-    public int SpaceLeft {
-      get {
-        if (output == null) {
-          return limit - position;
-        } else {
-          throw new InvalidOperationException(
-            "SpaceLeft can only be called on CodedOutputStreams that are " +
-            "writing to a flat array.");
-        }
-      }
-    }
-  }
-}
+#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;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Encodes and writes protocol message fields.
+    /// </summary>
+    /// <remarks>
+    /// This class contains two kinds of methods:  methods that write specific
+    /// protocol message constructs and field types (e.g. WriteTag and
+    /// WriteInt32) and methods that write low-level values (e.g.
+    /// WriteRawVarint32 and WriteRawBytes).  If you are writing encoded protocol
+    /// messages, you should use the former methods, but if you are writing some
+    /// other format of your own design, use the latter. The names of the former
+    /// methods are taken from the protocol buffer type names, not .NET types.
+    /// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.)
+    /// </remarks>
+    public sealed class CodedOutputStream
+    {
+        /// <summary>
+        /// The buffer size used by CreateInstance(Stream).
+        /// </summary>
+        public static readonly int DefaultBufferSize = 4096;
+
+        private readonly byte[] buffer;
+        private readonly int limit;
+        private int position;
+        private readonly Stream output;
+
+        #region Construction
+
+        private CodedOutputStream(byte[] buffer, int offset, int length)
+        {
+            this.output = null;
+            this.buffer = buffer;
+            this.position = offset;
+            this.limit = offset + length;
+        }
+
+        private CodedOutputStream(Stream output, byte[] buffer)
+        {
+            this.output = output;
+            this.buffer = buffer;
+            this.position = 0;
+            this.limit = buffer.Length;
+        }
+
+        /// <summary>
+        /// Creates a new CodedOutputStream which write to the given stream.
+        /// </summary>
+        public static CodedOutputStream CreateInstance(Stream output)
+        {
+            return CreateInstance(output, DefaultBufferSize);
+        }
+
+        /// <summary>
+        /// Creates a new CodedOutputStream which write to the given stream and uses
+        /// the specified buffer size.
+        /// </summary>
+        public static CodedOutputStream CreateInstance(Stream output, int bufferSize)
+        {
+            return new CodedOutputStream(output, new byte[bufferSize]);
+        }
+
+        /// <summary>
+        /// Creates a new CodedOutputStream that writes directly to the given
+        /// byte array. If more bytes are written than fit in the array,
+        /// OutOfSpaceException will be thrown.
+        /// </summary>
+        public static CodedOutputStream CreateInstance(byte[] flatArray)
+        {
+            return CreateInstance(flatArray, 0, flatArray.Length);
+        }
+
+        /// <summary>
+        /// Creates a new CodedOutputStream that writes directly to the given
+        /// byte array slice. If more bytes are written than fit in the array,
+        /// OutOfSpaceException will be thrown.
+        /// </summary>
+        public static CodedOutputStream CreateInstance(byte[] flatArray, int offset, int length)
+        {
+            return new CodedOutputStream(flatArray, offset, length);
+        }
+
+        #endregion
+
+        #region Writing of tags etc
+
+        /// <summary>
+        /// Writes a double field value, including tag, to the stream.
+        /// </summary>
+        public void WriteDouble(int fieldNumber, double value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
+            WriteDoubleNoTag(value);
+        }
+
+        /// <summary>
+        /// Writes a float field value, including tag, to the stream.
+        /// </summary>
+        public void WriteFloat(int fieldNumber, float value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
+            WriteFloatNoTag(value);
+        }
+
+        /// <summary>
+        /// Writes a uint64 field value, including tag, to the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public void WriteUInt64(int fieldNumber, ulong value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Varint);
+            WriteRawVarint64(value);
+        }
+
+        /// <summary>
+        /// Writes an int64 field value, including tag, to the stream.
+        /// </summary>
+        public void WriteInt64(int fieldNumber, long value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Varint);
+            WriteRawVarint64((ulong) value);
+        }
+
+        /// <summary>
+        /// Writes an int32 field value, including tag, to the stream.
+        /// </summary>
+        public void WriteInt32(int fieldNumber, int value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Varint);
+            if (value >= 0)
+            {
+                WriteRawVarint32((uint) value);
+            }
+            else
+            {
+                // Must sign-extend.
+                WriteRawVarint64((ulong) value);
+            }
+        }
+
+        /// <summary>
+        /// Writes a fixed64 field value, including tag, to the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public void WriteFixed64(int fieldNumber, ulong value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
+            WriteRawLittleEndian64(value);
+        }
+
+        /// <summary>
+        /// Writes a fixed32 field value, including tag, to the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public void WriteFixed32(int fieldNumber, uint value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
+            WriteRawLittleEndian32(value);
+        }
+
+        /// <summary>
+        /// Writes a bool field value, including tag, to the stream.
+        /// </summary>
+        public void WriteBool(int fieldNumber, bool value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Varint);
+            WriteRawByte(value ? (byte) 1 : (byte) 0);
+        }
+
+        /// <summary>
+        /// Writes a string field value, including tag, to the stream.
+        /// </summary>
+        public void WriteString(int fieldNumber, string value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            // Optimise the case where we have enough space to write
+            // the string directly to the buffer, which should be common.
+            int length = Encoding.UTF8.GetByteCount(value);
+            WriteRawVarint32((uint) length);
+            if (limit - position >= length)
+            {
+                Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, position);
+                position += length;
+            }
+            else
+            {
+                byte[] bytes = Encoding.UTF8.GetBytes(value);
+                WriteRawBytes(bytes);
+            }
+        }
+
+        /// <summary>
+        /// Writes a group field value, including tag, to the stream.
+        /// </summary>
+        public void WriteGroup(int fieldNumber, IMessageLite value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.StartGroup);
+            value.WriteTo(this);
+            WriteTag(fieldNumber, WireFormat.WireType.EndGroup);
+        }
+
+        [Obsolete]
+        public void WriteUnknownGroup(int fieldNumber, IMessageLite value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.StartGroup);
+            value.WriteTo(this);
+            WriteTag(fieldNumber, WireFormat.WireType.EndGroup);
+        }
+
+        public void WriteMessage(int fieldNumber, IMessageLite value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            WriteRawVarint32((uint) value.SerializedSize);
+            value.WriteTo(this);
+        }
+
+        public void WriteBytes(int fieldNumber, ByteString value)
+        {
+            // TODO(jonskeet): Optimise this! (No need to copy the bytes twice.)
+            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            byte[] bytes = value.ToByteArray();
+            WriteRawVarint32((uint) bytes.Length);
+            WriteRawBytes(bytes);
+        }
+
+        [CLSCompliant(false)]
+        public void WriteUInt32(int fieldNumber, uint value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Varint);
+            WriteRawVarint32(value);
+        }
+
+        public void WriteEnum(int fieldNumber, int value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Varint);
+            WriteRawVarint32((uint) value);
+        }
+
+        public void WriteSFixed32(int fieldNumber, int value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
+            WriteRawLittleEndian32((uint) value);
+        }
+
+        public void WriteSFixed64(int fieldNumber, long value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
+            WriteRawLittleEndian64((ulong) value);
+        }
+
+        public void WriteSInt32(int fieldNumber, int value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Varint);
+            WriteRawVarint32(EncodeZigZag32(value));
+        }
+
+        public void WriteSInt64(int fieldNumber, long value)
+        {
+            WriteTag(fieldNumber, WireFormat.WireType.Varint);
+            WriteRawVarint64(EncodeZigZag64(value));
+        }
+
+        public void WriteMessageSetExtension(int fieldNumber, IMessageLite value)
+        {
+            WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.StartGroup);
+            WriteUInt32(WireFormat.MessageSetField.TypeID, (uint) fieldNumber);
+            WriteMessage(WireFormat.MessageSetField.Message, value);
+            WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup);
+        }
+
+        public void WriteRawMessageSetExtension(int fieldNumber, ByteString value)
+        {
+            WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.StartGroup);
+            WriteUInt32(WireFormat.MessageSetField.TypeID, (uint) fieldNumber);
+            WriteBytes(WireFormat.MessageSetField.Message, value);
+            WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup);
+        }
+
+        public void WriteField(FieldType fieldType, int fieldNumber, object value)
+        {
+            switch (fieldType)
+            {
+                case FieldType.Double:
+                    WriteDouble(fieldNumber, (double) value);
+                    break;
+                case FieldType.Float:
+                    WriteFloat(fieldNumber, (float) value);
+                    break;
+                case FieldType.Int64:
+                    WriteInt64(fieldNumber, (long) value);
+                    break;
+                case FieldType.UInt64:
+                    WriteUInt64(fieldNumber, (ulong) value);
+                    break;
+                case FieldType.Int32:
+                    WriteInt32(fieldNumber, (int) value);
+                    break;
+                case FieldType.Fixed64:
+                    WriteFixed64(fieldNumber, (ulong) value);
+                    break;
+                case FieldType.Fixed32:
+                    WriteFixed32(fieldNumber, (uint) value);
+                    break;
+                case FieldType.Bool:
+                    WriteBool(fieldNumber, (bool) value);
+                    break;
+                case FieldType.String:
+                    WriteString(fieldNumber, (string) value);
+                    break;
+                case FieldType.Group:
+                    WriteGroup(fieldNumber, (IMessageLite) value);
+                    break;
+                case FieldType.Message:
+                    WriteMessage(fieldNumber, (IMessageLite) value);
+                    break;
+                case FieldType.Bytes:
+                    WriteBytes(fieldNumber, (ByteString) value);
+                    break;
+                case FieldType.UInt32:
+                    WriteUInt32(fieldNumber, (uint) value);
+                    break;
+                case FieldType.SFixed32:
+                    WriteSFixed32(fieldNumber, (int) value);
+                    break;
+                case FieldType.SFixed64:
+                    WriteSFixed64(fieldNumber, (long) value);
+                    break;
+                case FieldType.SInt32:
+                    WriteSInt32(fieldNumber, (int) value);
+                    break;
+                case FieldType.SInt64:
+                    WriteSInt64(fieldNumber, (long) value);
+                    break;
+                case FieldType.Enum:
+                    WriteEnum(fieldNumber, ((IEnumLite) value).Number);
+                    break;
+            }
+        }
+
+        public void WriteFieldNoTag(FieldType fieldType, object value)
+        {
+            switch (fieldType)
+            {
+                case FieldType.Double:
+                    WriteDoubleNoTag((double) value);
+                    break;
+                case FieldType.Float:
+                    WriteFloatNoTag((float) value);
+                    break;
+                case FieldType.Int64:
+                    WriteInt64NoTag((long) value);
+                    break;
+                case FieldType.UInt64:
+                    WriteUInt64NoTag((ulong) value);
+                    break;
+                case FieldType.Int32:
+                    WriteInt32NoTag((int) value);
+                    break;
+                case FieldType.Fixed64:
+                    WriteFixed64NoTag((ulong) value);
+                    break;
+                case FieldType.Fixed32:
+                    WriteFixed32NoTag((uint) value);
+                    break;
+                case FieldType.Bool:
+                    WriteBoolNoTag((bool) value);
+                    break;
+                case FieldType.String:
+                    WriteStringNoTag((string) value);
+                    break;
+                case FieldType.Group:
+                    WriteGroupNoTag((IMessageLite) value);
+                    break;
+                case FieldType.Message:
+                    WriteMessageNoTag((IMessageLite) value);
+                    break;
+                case FieldType.Bytes:
+                    WriteBytesNoTag((ByteString) value);
+                    break;
+                case FieldType.UInt32:
+                    WriteUInt32NoTag((uint) value);
+                    break;
+                case FieldType.SFixed32:
+                    WriteSFixed32NoTag((int) value);
+                    break;
+                case FieldType.SFixed64:
+                    WriteSFixed64NoTag((long) value);
+                    break;
+                case FieldType.SInt32:
+                    WriteSInt32NoTag((int) value);
+                    break;
+                case FieldType.SInt64:
+                    WriteSInt64NoTag((long) value);
+                    break;
+                case FieldType.Enum:
+                    WriteEnumNoTag(((IEnumLite) value).Number);
+                    break;
+            }
+        }
+
+        #endregion
+
+        #region Writing of values without tags
+
+        /// <summary>
+        /// Writes a double field value, including tag, to the stream.
+        /// </summary>
+        public void WriteDoubleNoTag(double value)
+        {
+            // TODO(jonskeet): Test this on different endiannesses
+#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35
+            byte[] bytes = BitConverter.GetBytes(value);
+            WriteRawBytes(bytes, 0, 8);
+#else
+      WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value));
+#endif
+        }
+
+        /// <summary>
+        /// Writes a float field value, without a tag, to the stream.
+        /// </summary>
+        public void WriteFloatNoTag(float value)
+        {
+            // TODO(jonskeet): Test this on different endiannesses
+            byte[] rawBytes = BitConverter.GetBytes(value);
+            uint asInteger = BitConverter.ToUInt32(rawBytes, 0);
+            WriteRawLittleEndian32(asInteger);
+        }
+
+        /// <summary>
+        /// Writes a uint64 field value, without a tag, to the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public void WriteUInt64NoTag(ulong value)
+        {
+            WriteRawVarint64(value);
+        }
+
+        /// <summary>
+        /// Writes an int64 field value, without a tag, to the stream.
+        /// </summary>
+        public void WriteInt64NoTag(long value)
+        {
+            WriteRawVarint64((ulong) value);
+        }
+
+        /// <summary>
+        /// Writes an int32 field value, without a tag, to the stream.
+        /// </summary>
+        public void WriteInt32NoTag(int value)
+        {
+            if (value >= 0)
+            {
+                WriteRawVarint32((uint) value);
+            }
+            else
+            {
+                // Must sign-extend.
+                WriteRawVarint64((ulong) value);
+            }
+        }
+
+        /// <summary>
+        /// Writes a fixed64 field value, without a tag, to the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public void WriteFixed64NoTag(ulong value)
+        {
+            WriteRawLittleEndian64(value);
+        }
+
+        /// <summary>
+        /// Writes a fixed32 field value, without a tag, to the stream.
+        /// </summary>
+        [CLSCompliant(false)]
+        public void WriteFixed32NoTag(uint value)
+        {
+            WriteRawLittleEndian32(value);
+        }
+
+        /// <summary>
+        /// Writes a bool field value, without a tag, to the stream.
+        /// </summary>
+        public void WriteBoolNoTag(bool value)
+        {
+            WriteRawByte(value ? (byte) 1 : (byte) 0);
+        }
+
+        /// <summary>
+        /// Writes a string field value, without a tag, to the stream.
+        /// </summary>
+        public void WriteStringNoTag(string value)
+        {
+            // Optimise the case where we have enough space to write
+            // the string directly to the buffer, which should be common.
+            int length = Encoding.UTF8.GetByteCount(value);
+            WriteRawVarint32((uint) length);
+            if (limit - position >= length)
+            {
+                Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, position);
+                position += length;
+            }
+            else
+            {
+                byte[] bytes = Encoding.UTF8.GetBytes(value);
+                WriteRawBytes(bytes);
+            }
+        }
+
+        /// <summary>
+        /// Writes a group field value, without a tag, to the stream.
+        /// </summary>
+        public void WriteGroupNoTag(IMessageLite value)
+        {
+            value.WriteTo(this);
+        }
+
+        public void WriteMessageNoTag(IMessageLite value)
+        {
+            WriteRawVarint32((uint) value.SerializedSize);
+            value.WriteTo(this);
+        }
+
+        public void WriteBytesNoTag(ByteString value)
+        {
+            // TODO(jonskeet): Optimise this! (No need to copy the bytes twice.)
+            byte[] bytes = value.ToByteArray();
+            WriteRawVarint32((uint) bytes.Length);
+            WriteRawBytes(bytes);
+        }
+
+        [CLSCompliant(false)]
+        public void WriteUInt32NoTag(uint value)
+        {
+            WriteRawVarint32(value);
+        }
+
+        public void WriteEnumNoTag(int value)
+        {
+            WriteRawVarint32((uint) value);
+        }
+
+        public void WriteSFixed32NoTag(int value)
+        {
+            WriteRawLittleEndian32((uint) value);
+        }
+
+        public void WriteSFixed64NoTag(long value)
+        {
+            WriteRawLittleEndian64((ulong) value);
+        }
+
+        public void WriteSInt32NoTag(int value)
+        {
+            WriteRawVarint32(EncodeZigZag32(value));
+        }
+
+        public void WriteSInt64NoTag(long value)
+        {
+            WriteRawVarint64(EncodeZigZag64(value));
+        }
+
+        #endregion
+
+        #region Underlying writing primitives
+
+        /// <summary>
+        /// Encodes and writes a tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public void WriteTag(int fieldNumber, WireFormat.WireType type)
+        {
+            WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
+        }
+
+        private void SlowWriteRawVarint32(uint value)
+        {
+            while (true)
+            {
+                if ((value & ~0x7F) == 0)
+                {
+                    WriteRawByte(value);
+                    return;
+                }
+                else
+                {
+                    WriteRawByte((value & 0x7F) | 0x80);
+                    value >>= 7;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Writes a 32 bit value as a varint. The fast route is taken when
+        /// there's enough buffer space left to whizz through without checking
+        /// for each byte; otherwise, we resort to calling WriteRawByte each time.
+        /// </summary>
+        [CLSCompliant(false)]
+        public void WriteRawVarint32(uint value)
+        {
+            if (position + 5 > limit)
+            {
+                SlowWriteRawVarint32(value);
+                return;
+            }
+
+            while (true)
+            {
+                if ((value & ~0x7F) == 0)
+                {
+                    buffer[position++] = (byte) value;
+                    return;
+                }
+                else
+                {
+                    buffer[position++] = (byte) ((value & 0x7F) | 0x80);
+                    value >>= 7;
+                }
+            }
+        }
+
+        [CLSCompliant(false)]
+        public void WriteRawVarint64(ulong value)
+        {
+            while (true)
+            {
+                if ((value & ~0x7FUL) == 0)
+                {
+                    WriteRawByte((uint) value);
+                    return;
+                }
+                else
+                {
+                    WriteRawByte(((uint) value & 0x7F) | 0x80);
+                    value >>= 7;
+                }
+            }
+        }
+
+        [CLSCompliant(false)]
+        public void WriteRawLittleEndian32(uint value)
+        {
+            WriteRawByte((byte) value);
+            WriteRawByte((byte) (value >> 8));
+            WriteRawByte((byte) (value >> 16));
+            WriteRawByte((byte) (value >> 24));
+        }
+
+        [CLSCompliant(false)]
+        public void WriteRawLittleEndian64(ulong value)
+        {
+            WriteRawByte((byte) value);
+            WriteRawByte((byte) (value >> 8));
+            WriteRawByte((byte) (value >> 16));
+            WriteRawByte((byte) (value >> 24));
+            WriteRawByte((byte) (value >> 32));
+            WriteRawByte((byte) (value >> 40));
+            WriteRawByte((byte) (value >> 48));
+            WriteRawByte((byte) (value >> 56));
+        }
+
+        public void WriteRawByte(byte value)
+        {
+            if (position == limit)
+            {
+                RefreshBuffer();
+            }
+
+            buffer[position++] = value;
+        }
+
+        [CLSCompliant(false)]
+        public void WriteRawByte(uint value)
+        {
+            WriteRawByte((byte) value);
+        }
+
+        /// <summary>
+        /// Writes out an array of bytes.
+        /// </summary>
+        public void WriteRawBytes(byte[] value)
+        {
+            WriteRawBytes(value, 0, value.Length);
+        }
+
+        /// <summary>
+        /// Writes out part of an array of bytes.
+        /// </summary>
+        public void WriteRawBytes(byte[] value, int offset, int length)
+        {
+            if (limit - position >= length)
+            {
+                Array.Copy(value, offset, buffer, position, length);
+                // We have room in the current buffer.
+                position += length;
+            }
+            else
+            {
+                // Write extends past current buffer.  Fill the rest of this buffer and
+                // flush.
+                int bytesWritten = limit - position;
+                Array.Copy(value, offset, buffer, position, bytesWritten);
+                offset += bytesWritten;
+                length -= bytesWritten;
+                position = limit;
+                RefreshBuffer();
+
+                // Now deal with the rest.
+                // Since we have an output stream, this is our buffer
+                // and buffer offset == 0
+                if (length <= limit)
+                {
+                    // Fits in new buffer.
+                    Array.Copy(value, offset, buffer, 0, length);
+                    position = length;
+                }
+                else
+                {
+                    // Write is very big.  Let's do it all at once.
+                    output.Write(value, offset, length);
+                }
+            }
+        }
+
+        #endregion
+
+        #region Size computations
+
+        private const int LittleEndian64Size = 8;
+        private const int LittleEndian32Size = 4;
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// double field, including the tag.
+        /// </summary>
+        public static int ComputeDoubleSize(int fieldNumber, double value)
+        {
+            return ComputeTagSize(fieldNumber) + LittleEndian64Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// float field, including the tag.
+        /// </summary>
+        public static int ComputeFloatSize(int fieldNumber, float value)
+        {
+            return ComputeTagSize(fieldNumber) + LittleEndian32Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// uint64 field, including the tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeUInt64Size(int fieldNumber, ulong value)
+        {
+            return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// int64 field, including the tag.
+        /// </summary>
+        public static int ComputeInt64Size(int fieldNumber, long value)
+        {
+            return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size((ulong) value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// int32 field, including the tag.
+        /// </summary>
+        public static int ComputeInt32Size(int fieldNumber, int value)
+        {
+            if (value >= 0)
+            {
+                return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint) value);
+            }
+            else
+            {
+                // Must sign-extend.
+                return ComputeTagSize(fieldNumber) + 10;
+            }
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// fixed64 field, including the tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeFixed64Size(int fieldNumber, ulong value)
+        {
+            return ComputeTagSize(fieldNumber) + LittleEndian64Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// fixed32 field, including the tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeFixed32Size(int fieldNumber, uint value)
+        {
+            return ComputeTagSize(fieldNumber) + LittleEndian32Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// bool field, including the tag.
+        /// </summary>
+        public static int ComputeBoolSize(int fieldNumber, bool value)
+        {
+            return ComputeTagSize(fieldNumber) + 1;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// string field, including the tag.
+        /// </summary>
+        public static int ComputeStringSize(int fieldNumber, String value)
+        {
+            int byteArraySize = Encoding.UTF8.GetByteCount(value);
+            return ComputeTagSize(fieldNumber) +
+                   ComputeRawVarint32Size((uint) byteArraySize) +
+                   byteArraySize;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// group field, including the tag.
+        /// </summary>
+        public static int ComputeGroupSize(int fieldNumber, IMessageLite value)
+        {
+            return ComputeTagSize(fieldNumber)*2 + value.SerializedSize;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// group field represented by an UnknownFieldSet, including the tag.
+        /// </summary>
+        [Obsolete]
+        public static int ComputeUnknownGroupSize(int fieldNumber,
+                                                  IMessageLite value)
+        {
+            return ComputeTagSize(fieldNumber)*2 + value.SerializedSize;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// embedded message field, including the tag.
+        /// </summary>
+        public static int ComputeMessageSize(int fieldNumber, IMessageLite value)
+        {
+            int size = value.SerializedSize;
+            return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint) size) + size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// bytes field, including the tag.
+        /// </summary>
+        public static int ComputeBytesSize(int fieldNumber, ByteString value)
+        {
+            return ComputeTagSize(fieldNumber) +
+                   ComputeRawVarint32Size((uint) value.Length) +
+                   value.Length;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// uint32 field, including the tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeUInt32Size(int fieldNumber, uint value)
+        {
+            return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// enum field, including the tag. The caller is responsible for
+        /// converting the enum value to its numeric value.
+        /// </summary>
+        public static int ComputeEnumSize(int fieldNumber, int value)
+        {
+            return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint) value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// sfixed32 field, including the tag.
+        /// </summary>
+        public static int ComputeSFixed32Size(int fieldNumber, int value)
+        {
+            return ComputeTagSize(fieldNumber) + LittleEndian32Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// sfixed64 field, including the tag.
+        /// </summary>
+        public static int ComputeSFixed64Size(int fieldNumber, long value)
+        {
+            return ComputeTagSize(fieldNumber) + LittleEndian64Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// sint32 field, including the tag.
+        /// </summary>
+        public static int ComputeSInt32Size(int fieldNumber, int value)
+        {
+            return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(EncodeZigZag32(value));
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// sint64 field, including the tag.
+        /// </summary>
+        public static int ComputeSInt64Size(int fieldNumber, long value)
+        {
+            return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(EncodeZigZag64(value));
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// double field, including the tag.
+        /// </summary>
+        public static int ComputeDoubleSizeNoTag(double value)
+        {
+            return LittleEndian64Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// float field, including the tag.
+        /// </summary>
+        public static int ComputeFloatSizeNoTag(float value)
+        {
+            return LittleEndian32Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// uint64 field, including the tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeUInt64SizeNoTag(ulong value)
+        {
+            return ComputeRawVarint64Size(value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// int64 field, including the tag.
+        /// </summary>
+        public static int ComputeInt64SizeNoTag(long value)
+        {
+            return ComputeRawVarint64Size((ulong) value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// int32 field, including the tag.
+        /// </summary>
+        public static int ComputeInt32SizeNoTag(int value)
+        {
+            if (value >= 0)
+            {
+                return ComputeRawVarint32Size((uint) value);
+            }
+            else
+            {
+                // Must sign-extend.
+                return 10;
+            }
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// fixed64 field, including the tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeFixed64SizeNoTag(ulong value)
+        {
+            return LittleEndian64Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// fixed32 field, including the tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeFixed32SizeNoTag(uint value)
+        {
+            return LittleEndian32Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// bool field, including the tag.
+        /// </summary>
+        public static int ComputeBoolSizeNoTag(bool value)
+        {
+            return 1;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// string field, including the tag.
+        /// </summary>
+        public static int ComputeStringSizeNoTag(String value)
+        {
+            int byteArraySize = Encoding.UTF8.GetByteCount(value);
+            return ComputeRawVarint32Size((uint) byteArraySize) +
+                   byteArraySize;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// group field, including the tag.
+        /// </summary>
+        public static int ComputeGroupSizeNoTag(IMessageLite value)
+        {
+            return value.SerializedSize;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// group field represented by an UnknownFieldSet, including the tag.
+        /// </summary>
+        [Obsolete]
+        public static int ComputeUnknownGroupSizeNoTag(IMessageLite value)
+        {
+            return value.SerializedSize;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// embedded message field, including the tag.
+        /// </summary>
+        public static int ComputeMessageSizeNoTag(IMessageLite value)
+        {
+            int size = value.SerializedSize;
+            return ComputeRawVarint32Size((uint) size) + size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// bytes field, including the tag.
+        /// </summary>
+        public static int ComputeBytesSizeNoTag(ByteString value)
+        {
+            return ComputeRawVarint32Size((uint) value.Length) +
+                   value.Length;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// uint32 field, including the tag.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeUInt32SizeNoTag(uint value)
+        {
+            return ComputeRawVarint32Size(value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// enum field, including the tag. The caller is responsible for
+        /// converting the enum value to its numeric value.
+        /// </summary>
+        public static int ComputeEnumSizeNoTag(int value)
+        {
+            return ComputeRawVarint32Size((uint) value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// sfixed32 field, including the tag.
+        /// </summary>
+        public static int ComputeSFixed32SizeNoTag(int value)
+        {
+            return LittleEndian32Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// sfixed64 field, including the tag.
+        /// </summary>
+        public static int ComputeSFixed64SizeNoTag(long value)
+        {
+            return LittleEndian64Size;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// sint32 field, including the tag.
+        /// </summary>
+        public static int ComputeSInt32SizeNoTag(int value)
+        {
+            return ComputeRawVarint32Size(EncodeZigZag32(value));
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// sint64 field, including the tag.
+        /// </summary>
+        public static int ComputeSInt64SizeNoTag(long value)
+        {
+            return ComputeRawVarint64Size(EncodeZigZag64(value));
+        }
+
+        /*
+     * Compute the number of bytes that would be needed to encode a
+     * MessageSet extension to the stream.  For historical reasons,
+     * the wire format differs from normal fields.
+     */
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// MessageSet extension to the stream. For historical reasons,
+        /// the wire format differs from normal fields.
+        /// </summary>
+        public static int ComputeMessageSetExtensionSize(int fieldNumber, IMessageLite value)
+        {
+            return ComputeTagSize(WireFormat.MessageSetField.Item)*2 +
+                   ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) +
+                   ComputeMessageSize(WireFormat.MessageSetField.Message, value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode an
+        /// unparsed MessageSet extension field to the stream. For
+        /// historical reasons, the wire format differs from normal fields.
+        /// </summary>
+        public static int ComputeRawMessageSetExtensionSize(int fieldNumber, ByteString value)
+        {
+            return ComputeTagSize(WireFormat.MessageSetField.Item)*2 +
+                   ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) +
+                   ComputeBytesSize(WireFormat.MessageSetField.Message, value);
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a varint.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeRawVarint32Size(uint value)
+        {
+            if ((value & (0xffffffff << 7)) == 0) return 1;
+            if ((value & (0xffffffff << 14)) == 0) return 2;
+            if ((value & (0xffffffff << 21)) == 0) return 3;
+            if ((value & (0xffffffff << 28)) == 0) return 4;
+            return 5;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a varint.
+        /// </summary>
+        [CLSCompliant(false)]
+        public static int ComputeRawVarint64Size(ulong value)
+        {
+            if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
+            if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
+            if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
+            if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
+            if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
+            if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
+            if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
+            if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
+            if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
+            return 10;
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// field of arbitrary type, including the tag, to the stream.
+        /// </summary>
+        public static int ComputeFieldSize(FieldType fieldType, int fieldNumber, Object value)
+        {
+            switch (fieldType)
+            {
+                case FieldType.Double:
+                    return ComputeDoubleSize(fieldNumber, (double) value);
+                case FieldType.Float:
+                    return ComputeFloatSize(fieldNumber, (float) value);
+                case FieldType.Int64:
+                    return ComputeInt64Size(fieldNumber, (long) value);
+                case FieldType.UInt64:
+                    return ComputeUInt64Size(fieldNumber, (ulong) value);
+                case FieldType.Int32:
+                    return ComputeInt32Size(fieldNumber, (int) value);
+                case FieldType.Fixed64:
+                    return ComputeFixed64Size(fieldNumber, (ulong) value);
+                case FieldType.Fixed32:
+                    return ComputeFixed32Size(fieldNumber, (uint) value);
+                case FieldType.Bool:
+                    return ComputeBoolSize(fieldNumber, (bool) value);
+                case FieldType.String:
+                    return ComputeStringSize(fieldNumber, (string) value);
+                case FieldType.Group:
+                    return ComputeGroupSize(fieldNumber, (IMessageLite) value);
+                case FieldType.Message:
+                    return ComputeMessageSize(fieldNumber, (IMessageLite) value);
+                case FieldType.Bytes:
+                    return ComputeBytesSize(fieldNumber, (ByteString) value);
+                case FieldType.UInt32:
+                    return ComputeUInt32Size(fieldNumber, (uint) value);
+                case FieldType.SFixed32:
+                    return ComputeSFixed32Size(fieldNumber, (int) value);
+                case FieldType.SFixed64:
+                    return ComputeSFixed64Size(fieldNumber, (long) value);
+                case FieldType.SInt32:
+                    return ComputeSInt32Size(fieldNumber, (int) value);
+                case FieldType.SInt64:
+                    return ComputeSInt64Size(fieldNumber, (long) value);
+                case FieldType.Enum:
+                    return ComputeEnumSize(fieldNumber, ((IEnumLite) value).Number);
+                default:
+                    throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
+            }
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a
+        /// field of arbitrary type, excluding the tag, to the stream.
+        /// </summary>
+        public static int ComputeFieldSizeNoTag(FieldType fieldType, Object value)
+        {
+            switch (fieldType)
+            {
+                case FieldType.Double:
+                    return ComputeDoubleSizeNoTag((double) value);
+                case FieldType.Float:
+                    return ComputeFloatSizeNoTag((float) value);
+                case FieldType.Int64:
+                    return ComputeInt64SizeNoTag((long) value);
+                case FieldType.UInt64:
+                    return ComputeUInt64SizeNoTag((ulong) value);
+                case FieldType.Int32:
+                    return ComputeInt32SizeNoTag((int) value);
+                case FieldType.Fixed64:
+                    return ComputeFixed64SizeNoTag((ulong) value);
+                case FieldType.Fixed32:
+                    return ComputeFixed32SizeNoTag((uint) value);
+                case FieldType.Bool:
+                    return ComputeBoolSizeNoTag((bool) value);
+                case FieldType.String:
+                    return ComputeStringSizeNoTag((string) value);
+                case FieldType.Group:
+                    return ComputeGroupSizeNoTag((IMessageLite) value);
+                case FieldType.Message:
+                    return ComputeMessageSizeNoTag((IMessageLite) value);
+                case FieldType.Bytes:
+                    return ComputeBytesSizeNoTag((ByteString) value);
+                case FieldType.UInt32:
+                    return ComputeUInt32SizeNoTag((uint) value);
+                case FieldType.SFixed32:
+                    return ComputeSFixed32SizeNoTag((int) value);
+                case FieldType.SFixed64:
+                    return ComputeSFixed64SizeNoTag((long) value);
+                case FieldType.SInt32:
+                    return ComputeSInt32SizeNoTag((int) value);
+                case FieldType.SInt64:
+                    return ComputeSInt64SizeNoTag((long) value);
+                case FieldType.Enum:
+                    return ComputeEnumSizeNoTag(((IEnumLite) value).Number);
+                default:
+                    throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
+            }
+        }
+
+        /// <summary>
+        /// Compute the number of bytes that would be needed to encode a tag.
+        /// </summary>
+        public static int ComputeTagSize(int fieldNumber)
+        {
+            return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0));
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Encode a 32-bit value with ZigZag encoding.
+        /// </summary>
+        /// <remarks>
+        /// ZigZag encodes signed integers into values that can be efficiently
+        /// encoded with varint.  (Otherwise, negative values must be 
+        /// sign-extended to 64 bits to be varint encoded, thus always taking
+        /// 10 bytes on the wire.)
+        /// </remarks>
+        [CLSCompliant(false)]
+        public static uint EncodeZigZag32(int n)
+        {
+            // Note:  the right-shift must be arithmetic
+            return (uint) ((n << 1) ^ (n >> 31));
+        }
+
+        /// <summary>
+        /// Encode a 64-bit value with ZigZag encoding.
+        /// </summary>
+        /// <remarks>
+        /// ZigZag encodes signed integers into values that can be efficiently
+        /// encoded with varint.  (Otherwise, negative values must be 
+        /// sign-extended to 64 bits to be varint encoded, thus always taking
+        /// 10 bytes on the wire.)
+        /// </remarks>
+        [CLSCompliant(false)]
+        public static ulong EncodeZigZag64(long n)
+        {
+            return (ulong) ((n << 1) ^ (n >> 63));
+        }
+
+        private void RefreshBuffer()
+        {
+            if (output == null)
+            {
+                // We're writing to a single buffer.
+                throw new OutOfSpaceException();
+            }
+
+            // Since we have an output stream, this is our buffer
+            // and buffer offset == 0
+            output.Write(buffer, 0, position);
+            position = 0;
+        }
+
+        /// <summary>
+        /// Indicates that a CodedOutputStream wrapping a flat byte array
+        /// ran out of space.
+        /// </summary>
+        public sealed class OutOfSpaceException : IOException
+        {
+            internal OutOfSpaceException()
+                : base("CodedOutputStream was writing to a flat byte array and ran out of space.")
+            {
+            }
+        }
+
+        public void Flush()
+        {
+            if (output != null)
+            {
+                RefreshBuffer();
+            }
+        }
+
+        /// <summary>
+        /// Verifies that SpaceLeft returns zero. It's common to create a byte array
+        /// that is exactly big enough to hold a message, then write to it with
+        /// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that
+        /// the message was actually as big as expected, which can help bugs.
+        /// </summary>
+        public void CheckNoSpaceLeft()
+        {
+            if (SpaceLeft != 0)
+            {
+                throw new InvalidOperationException("Did not write as much data as expected.");
+            }
+        }
+
+        /// <summary>
+        /// If writing to a flat array, returns the space left in the array. Otherwise,
+        /// throws an InvalidOperationException.
+        /// </summary>
+        public int SpaceLeft
+        {
+            get
+            {
+                if (output == null)
+                {
+                    return limit - position;
+                }
+                else
+                {
+                    throw new InvalidOperationException(
+                        "SpaceLeft can only be called on CodedOutputStreams that are " +
+                        "writing to a flat array.");
+                }
+            }
+        }
+    }
+}

+ 122 - 108
src/ProtocolBuffers/Collections/Dictionaries.cs

@@ -1,108 +1,122 @@
-// 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.
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace Google.ProtocolBuffers.Collections {
-
-  /// <summary>
-  /// Utility class for dictionaries.
-  /// </summary>
-  public static class Dictionaries {
-
-    /// <summary>
-    /// Compares two dictionaries for equality. Each value is compared with equality using Equals
-    /// for non-IEnumerable implementations, and using EnumerableEquals otherwise.
-    /// TODO(jonskeet): This is clearly pretty slow, and involves lots of boxing/unboxing...
-    /// </summary>
-    public static bool Equals<TKey, TValue>(IDictionary<TKey, TValue> left, IDictionary<TKey, TValue> right) {
-      if (left.Count != right.Count) {
-        return false;
-      }
-      foreach (KeyValuePair<TKey,TValue> leftEntry in left)
-      {
-        TValue rightValue;
-        if (!right.TryGetValue(leftEntry.Key, out rightValue)) {
-          return false;
-        }
-
-        IEnumerable leftEnumerable = leftEntry.Value as IEnumerable;
-        IEnumerable rightEnumerable = rightValue as IEnumerable;
-        if (leftEnumerable == null || rightEnumerable == null) {
-          if (!Equals(leftEntry.Value, rightValue)) {
-            return false;
-          }
-        } else {
-          if (!Enumerables.Equals(leftEnumerable, rightEnumerable)) {
-            return false;
-          }
-        }
-      }
-      return true;
-    }
-
-    public static IDictionary<TKey, TValue> AsReadOnly<TKey, TValue> (IDictionary<TKey, TValue> dictionary) {
-      return dictionary.IsReadOnly ? dictionary : new ReadOnlyDictionary<TKey, TValue>(dictionary);
-    }
-
-    /// <summary>
-    /// Creates a hashcode for a dictionary by XORing the hashcodes of all the fields
-    /// and values. (By XORing, we avoid ordering issues.)
-    /// TODO(jonskeet): Currently XORs other stuff too, and assumes non-null values.
-    /// </summary>
-    public static int GetHashCode<TKey, TValue>(IDictionary<TKey, TValue> dictionary) {
-      int ret = 31;
-      foreach (KeyValuePair<TKey, TValue> entry in dictionary) {
-        int hash = entry.Key.GetHashCode() ^ GetDeepHashCode(entry.Value);
-        ret ^= hash;
-      }
-      return ret;
-    }
-
-    /// <summary>
-    /// Determines the hash of a value by either taking it directly or hashing all the elements
-    /// for IEnumerable implementations.
-    /// </summary>
-    private static int GetDeepHashCode(object value) {
-      IEnumerable iterable = value as IEnumerable;
-      if (iterable == null) {
-        return value.GetHashCode();
-      }
-      int hash = 29;
-      foreach (object element in iterable) {
-        hash = hash * 37 + element.GetHashCode();
-      }
-      return hash;
-    }
-  }
-}
+// 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.
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Google.ProtocolBuffers.Collections
+{
+    /// <summary>
+    /// Utility class for dictionaries.
+    /// </summary>
+    public static class Dictionaries
+    {
+        /// <summary>
+        /// Compares two dictionaries for equality. Each value is compared with equality using Equals
+        /// for non-IEnumerable implementations, and using EnumerableEquals otherwise.
+        /// TODO(jonskeet): This is clearly pretty slow, and involves lots of boxing/unboxing...
+        /// </summary>
+        public static bool Equals<TKey, TValue>(IDictionary<TKey, TValue> left, IDictionary<TKey, TValue> right)
+        {
+            if (left.Count != right.Count)
+            {
+                return false;
+            }
+            foreach (KeyValuePair<TKey, TValue> leftEntry in left)
+            {
+                TValue rightValue;
+                if (!right.TryGetValue(leftEntry.Key, out rightValue))
+                {
+                    return false;
+                }
+
+                IEnumerable leftEnumerable = leftEntry.Value as IEnumerable;
+                IEnumerable rightEnumerable = rightValue as IEnumerable;
+                if (leftEnumerable == null || rightEnumerable == null)
+                {
+                    if (!Equals(leftEntry.Value, rightValue))
+                    {
+                        return false;
+                    }
+                }
+                else
+                {
+                    if (!Enumerables.Equals(leftEnumerable, rightEnumerable))
+                    {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
+        public static IDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(IDictionary<TKey, TValue> dictionary)
+        {
+            return dictionary.IsReadOnly ? dictionary : new ReadOnlyDictionary<TKey, TValue>(dictionary);
+        }
+
+        /// <summary>
+        /// Creates a hashcode for a dictionary by XORing the hashcodes of all the fields
+        /// and values. (By XORing, we avoid ordering issues.)
+        /// TODO(jonskeet): Currently XORs other stuff too, and assumes non-null values.
+        /// </summary>
+        public static int GetHashCode<TKey, TValue>(IDictionary<TKey, TValue> dictionary)
+        {
+            int ret = 31;
+            foreach (KeyValuePair<TKey, TValue> entry in dictionary)
+            {
+                int hash = entry.Key.GetHashCode() ^ GetDeepHashCode(entry.Value);
+                ret ^= hash;
+            }
+            return ret;
+        }
+
+        /// <summary>
+        /// Determines the hash of a value by either taking it directly or hashing all the elements
+        /// for IEnumerable implementations.
+        /// </summary>
+        private static int GetDeepHashCode(object value)
+        {
+            IEnumerable iterable = value as IEnumerable;
+            if (iterable == null)
+            {
+                return value.GetHashCode();
+            }
+            int hash = 29;
+            foreach (object element in iterable)
+            {
+                hash = hash*37 + element.GetHashCode();
+            }
+            return hash;
+        }
+    }
+}

+ 74 - 63
src/ProtocolBuffers/Collections/Enumerables.cs

@@ -1,63 +1,74 @@
-// 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.
-using System;
-using System.Collections;
-
-namespace Google.ProtocolBuffers.Collections {
-  /// <summary>
-  /// Utility class for IEnumerable (and potentially the generic version in the future).
-  /// </summary>
-  public static class Enumerables {
-    public static bool Equals(IEnumerable left, IEnumerable right) {
-      IEnumerator leftEnumerator = left.GetEnumerator();
-      try {
-        foreach (object rightObject in right) {
-          if (!leftEnumerator.MoveNext()) {
-            return false;
-          }
-          if (!Equals(leftEnumerator.Current, rightObject)) {
-            return false;
-          }
-        }
-        if (leftEnumerator.MoveNext()) {
-          return false;
-        }
-      } finally {
-        IDisposable leftEnumeratorDisposable = leftEnumerator as IDisposable;
-        if (leftEnumeratorDisposable != null) {
-          leftEnumeratorDisposable.Dispose();
-        }
-      }
-      return true;
-    }
-  }
-}
+// 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.
+using System;
+using System.Collections;
+
+namespace Google.ProtocolBuffers.Collections
+{
+    /// <summary>
+    /// Utility class for IEnumerable (and potentially the generic version in the future).
+    /// </summary>
+    public static class Enumerables
+    {
+        public static bool Equals(IEnumerable left, IEnumerable right)
+        {
+            IEnumerator leftEnumerator = left.GetEnumerator();
+            try
+            {
+                foreach (object rightObject in right)
+                {
+                    if (!leftEnumerator.MoveNext())
+                    {
+                        return false;
+                    }
+                    if (!Equals(leftEnumerator.Current, rightObject))
+                    {
+                        return false;
+                    }
+                }
+                if (leftEnumerator.MoveNext())
+                {
+                    return false;
+                }
+            }
+            finally
+            {
+                IDisposable leftEnumeratorDisposable = leftEnumerator as IDisposable;
+                if (leftEnumeratorDisposable != null)
+                {
+                    leftEnumeratorDisposable.Dispose();
+                }
+            }
+            return true;
+        }
+    }
+}

+ 50 - 48
src/ProtocolBuffers/Collections/IPopsicleList.cs

@@ -1,48 +1,50 @@
-// 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.
-using System.Collections.Generic;
-
-namespace Google.ProtocolBuffers.Collections {
-  /// <summary>
-  /// A list which has an Add method which accepts an IEnumerable[T].
-  /// This allows whole collections to be added easily using collection initializers.
-  /// It causes a potential overload confusion if T : IEnumerable[T], but in
-  /// practice that won't happen in protocol buffers.
-  /// </summary>
-  /// <remarks>This is only currently implemented by PopsicleList, and it's likely
-  /// to stay that way - hence the name. More genuinely descriptive names are
-  /// horribly ugly. (At least, the ones the author could think of...)</remarks>
-  /// <typeparam name="T">The element type of the list</typeparam>
-  public interface IPopsicleList<T> : IList<T> {
-    void Add(IEnumerable<T> collection);
-  }
-}
+// 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.
+using System.Collections.Generic;
+
+namespace Google.ProtocolBuffers.Collections
+{
+    /// <summary>
+    /// A list which has an Add method which accepts an IEnumerable[T].
+    /// This allows whole collections to be added easily using collection initializers.
+    /// It causes a potential overload confusion if T : IEnumerable[T], but in
+    /// practice that won't happen in protocol buffers.
+    /// </summary>
+    /// <remarks>This is only currently implemented by PopsicleList, and it's likely
+    /// to stay that way - hence the name. More genuinely descriptive names are
+    /// horribly ugly. (At least, the ones the author could think of...)</remarks>
+    /// <typeparam name="T">The element type of the list</typeparam>
+    public interface IPopsicleList<T> : IList<T>
+    {
+        void Add(IEnumerable<T> collection);
+    }
+}

+ 110 - 99
src/ProtocolBuffers/Collections/Lists.cs

@@ -1,99 +1,110 @@
-// 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.
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-
-namespace Google.ProtocolBuffers.Collections {
-
-  /// <summary>
-  /// Utility non-generic class for calling into Lists{T} using type inference.
-  /// </summary>
-  public static class Lists {
-
-    /// <summary>
-    /// Returns a read-only view of the specified list.
-    /// </summary>
-    public static IList<T> AsReadOnly<T>(IList<T> list) {
-      return Lists<T>.AsReadOnly(list);
-    }
-
-    public static bool Equals<T>(IList<T> left, IList<T> right) {
-      if (left == right) {
-        return true;
-      }
-      if (left == null || right == null) {
-        return false;
-      }
-      if (left.Count != right.Count) {
-        return false;
-      }
-      IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
-      for (int i = 0; i < left.Count; i++) {
-        if (!comparer.Equals(left[i], right[i])) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    public static int GetHashCode<T>(IList<T> list) {
-      int hash = 31;
-      foreach (T element in list) {
-        hash = hash * 29 + element.GetHashCode();
-      }
-      return hash;
-    }
-  }
-
-  /// <summary>
-  /// Utility class for dealing with lists.
-  /// </summary>
-  public static class Lists<T> {
-
-    static readonly ReadOnlyCollection<T> empty = new ReadOnlyCollection<T>(new T[0]);
-
-    /// <summary>
-    /// Returns an immutable empty list.
-    /// </summary>
-    public static ReadOnlyCollection<T> Empty {
-      get { return empty; }
-    }
-
-    /// <summary>
-    /// Returns either the original reference if it's already read-only,
-    /// or a new ReadOnlyCollection wrapping the original list.
-    /// </summary>
-    public static IList<T> AsReadOnly(IList<T> list) {
-      return list.IsReadOnly ? list : new ReadOnlyCollection<T>(list);
-    }
-  }
-}
+// 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.
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Google.ProtocolBuffers.Collections
+{
+    /// <summary>
+    /// Utility non-generic class for calling into Lists{T} using type inference.
+    /// </summary>
+    public static class Lists
+    {
+        /// <summary>
+        /// Returns a read-only view of the specified list.
+        /// </summary>
+        public static IList<T> AsReadOnly<T>(IList<T> list)
+        {
+            return Lists<T>.AsReadOnly(list);
+        }
+
+        public static bool Equals<T>(IList<T> left, IList<T> right)
+        {
+            if (left == right)
+            {
+                return true;
+            }
+            if (left == null || right == null)
+            {
+                return false;
+            }
+            if (left.Count != right.Count)
+            {
+                return false;
+            }
+            IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
+            for (int i = 0; i < left.Count; i++)
+            {
+                if (!comparer.Equals(left[i], right[i]))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public static int GetHashCode<T>(IList<T> list)
+        {
+            int hash = 31;
+            foreach (T element in list)
+            {
+                hash = hash*29 + element.GetHashCode();
+            }
+            return hash;
+        }
+    }
+
+    /// <summary>
+    /// Utility class for dealing with lists.
+    /// </summary>
+    public static class Lists<T>
+    {
+        private static readonly ReadOnlyCollection<T> empty = new ReadOnlyCollection<T>(new T[0]);
+
+        /// <summary>
+        /// Returns an immutable empty list.
+        /// </summary>
+        public static ReadOnlyCollection<T> Empty
+        {
+            get { return empty; }
+        }
+
+        /// <summary>
+        /// Returns either the original reference if it's already read-only,
+        /// or a new ReadOnlyCollection wrapping the original list.
+        /// </summary>
+        public static IList<T> AsReadOnly(IList<T> list)
+        {
+            return list.IsReadOnly ? list : new ReadOnlyCollection<T>(list);
+        }
+    }
+}

+ 150 - 132
src/ProtocolBuffers/Collections/PopsicleList.cs

@@ -1,132 +1,150 @@
-// 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.
-using System;
-using System.Collections.Generic;
-using System.Collections;
-
-namespace Google.ProtocolBuffers.Collections {
-  /// <summary>
-  /// Proxies calls to a <see cref="List{T}" />, but allows the list
-  /// to be made read-only (with the <see cref="MakeReadOnly" /> method), 
-  /// after which any modifying methods throw <see cref="NotSupportedException" />.
-  /// </summary>
-  public sealed class PopsicleList<T> : IPopsicleList<T> {
-
-    private readonly List<T> items = new List<T>();
-    private bool readOnly = false;
-
-    /// <summary>
-    /// Makes this list read-only ("freezes the popsicle"). From this
-    /// point on, mutating methods (Clear, Add etc) will throw a
-    /// NotSupportedException. There is no way of "defrosting" the list afterwards.
-    /// </summary>
-    public void MakeReadOnly() {
-      readOnly = true;
-    }
-
-    public int IndexOf(T item) {
-      return items.IndexOf(item);
-    }
-
-    public void Insert(int index, T item) {
-      ValidateModification();
-      items.Insert(index, item);
-    }
-
-    public void RemoveAt(int index) {
-      ValidateModification();
-      items.RemoveAt(index);
-    }
-
-    public T this[int index] {
-      get {
-        return items[index];
-      }
-      set {
-        ValidateModification();
-        items[index] = value;
-      }
-    }
-
-    public void Add(T item) {
-      ValidateModification();
-      items.Add(item);
-    }
-
-    public void Clear() {
-      ValidateModification();
-      items.Clear();
-    }
-
-    public bool Contains(T item) {
-      return items.Contains(item);
-    }
-
-    public void CopyTo(T[] array, int arrayIndex) {
-      items.CopyTo(array, arrayIndex);
-    }
-
-    public int Count {
-      get { return items.Count; }
-    }
-
-    public bool IsReadOnly {
-      get { return readOnly; }
-    }
-
-    public bool Remove(T item) {
-      ValidateModification();
-      return items.Remove(item);
-    }
-
-    public void Add(IEnumerable<T> collection) {
-      if (readOnly) {
-        throw new NotSupportedException("List is read-only");
-      }
-      items.AddRange(collection);
-    }
-
-    public IEnumerator<T> GetEnumerator() {
-      return items.GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator() {
-      return GetEnumerator();
-    }
-
-    private void ValidateModification() {
-      if (readOnly) {
-        throw new NotSupportedException("List is read-only");
-      }
-    }
-  }
-}
+// 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.
+using System;
+using System.Collections.Generic;
+using System.Collections;
+
+namespace Google.ProtocolBuffers.Collections
+{
+    /// <summary>
+    /// Proxies calls to a <see cref="List{T}" />, but allows the list
+    /// to be made read-only (with the <see cref="MakeReadOnly" /> method), 
+    /// after which any modifying methods throw <see cref="NotSupportedException" />.
+    /// </summary>
+    public sealed class PopsicleList<T> : IPopsicleList<T>
+    {
+        private readonly List<T> items = new List<T>();
+        private bool readOnly = false;
+
+        /// <summary>
+        /// Makes this list read-only ("freezes the popsicle"). From this
+        /// point on, mutating methods (Clear, Add etc) will throw a
+        /// NotSupportedException. There is no way of "defrosting" the list afterwards.
+        /// </summary>
+        public void MakeReadOnly()
+        {
+            readOnly = true;
+        }
+
+        public int IndexOf(T item)
+        {
+            return items.IndexOf(item);
+        }
+
+        public void Insert(int index, T item)
+        {
+            ValidateModification();
+            items.Insert(index, item);
+        }
+
+        public void RemoveAt(int index)
+        {
+            ValidateModification();
+            items.RemoveAt(index);
+        }
+
+        public T this[int index]
+        {
+            get { return items[index]; }
+            set
+            {
+                ValidateModification();
+                items[index] = value;
+            }
+        }
+
+        public void Add(T item)
+        {
+            ValidateModification();
+            items.Add(item);
+        }
+
+        public void Clear()
+        {
+            ValidateModification();
+            items.Clear();
+        }
+
+        public bool Contains(T item)
+        {
+            return items.Contains(item);
+        }
+
+        public void CopyTo(T[] array, int arrayIndex)
+        {
+            items.CopyTo(array, arrayIndex);
+        }
+
+        public int Count
+        {
+            get { return items.Count; }
+        }
+
+        public bool IsReadOnly
+        {
+            get { return readOnly; }
+        }
+
+        public bool Remove(T item)
+        {
+            ValidateModification();
+            return items.Remove(item);
+        }
+
+        public void Add(IEnumerable<T> collection)
+        {
+            if (readOnly)
+            {
+                throw new NotSupportedException("List is read-only");
+            }
+            items.AddRange(collection);
+        }
+
+        public IEnumerator<T> GetEnumerator()
+        {
+            return items.GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        private void ValidateModification()
+        {
+            if (readOnly)
+            {
+                throw new NotSupportedException("List is read-only");
+            }
+        }
+    }
+}

+ 146 - 128
src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs

@@ -1,128 +1,146 @@
-// 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.
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace Google.ProtocolBuffers.Collections {
-  /// <summary>
-  /// Read-only wrapper around another dictionary.
-  /// </summary>
-  public sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue> {
-    readonly IDictionary<TKey, TValue> wrapped;
-
-    public ReadOnlyDictionary(IDictionary<TKey, TValue> wrapped) {
-      this.wrapped = wrapped;
-    }
-
-    public void Add(TKey key, TValue value) {
-      throw new InvalidOperationException();
-    }
-
-    public bool ContainsKey(TKey key) {
-      return wrapped.ContainsKey(key);
-    }
-
-    public ICollection<TKey> Keys {
-      get { return wrapped.Keys; }
-    }
-
-    public bool Remove(TKey key) {
-      throw new InvalidOperationException();
-    }
-
-    public bool TryGetValue(TKey key, out TValue value) {
-      return wrapped.TryGetValue(key, out value);
-    }
-
-    public ICollection<TValue> Values {
-      get { return wrapped.Values; }
-    }
-
-    public TValue this[TKey key] {
-      get {
-        return wrapped[key];
-      }
-      set {
-        throw new InvalidOperationException();
-      }
-    }
-
-    public void Add(KeyValuePair<TKey, TValue> item) {
-      throw new InvalidOperationException();
-    }
-
-    public void Clear() {
-      throw new InvalidOperationException();
-    }
-
-    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 true; }
-    }
-
-    public bool Remove(KeyValuePair<TKey, TValue> item) {
-      throw new InvalidOperationException();
-    }
-
-    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
-      return wrapped.GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator() {
-      return ((IEnumerable) wrapped).GetEnumerator();
-    }
-
-    public override bool Equals(object obj) {
-      return wrapped.Equals(obj);
-    }
-
-    public override int GetHashCode() {
-      return wrapped.GetHashCode();
-    }
-
-    public override string ToString() {
-      return wrapped.ToString();
-    }
-  }
-}
+// 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.
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Google.ProtocolBuffers.Collections
+{
+    /// <summary>
+    /// Read-only wrapper around another dictionary.
+    /// </summary>
+    public sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
+    {
+        private readonly IDictionary<TKey, TValue> wrapped;
+
+        public ReadOnlyDictionary(IDictionary<TKey, TValue> wrapped)
+        {
+            this.wrapped = wrapped;
+        }
+
+        public void Add(TKey key, TValue value)
+        {
+            throw new InvalidOperationException();
+        }
+
+        public bool ContainsKey(TKey key)
+        {
+            return wrapped.ContainsKey(key);
+        }
+
+        public ICollection<TKey> Keys
+        {
+            get { return wrapped.Keys; }
+        }
+
+        public bool Remove(TKey key)
+        {
+            throw new InvalidOperationException();
+        }
+
+        public bool TryGetValue(TKey key, out TValue value)
+        {
+            return wrapped.TryGetValue(key, out value);
+        }
+
+        public ICollection<TValue> Values
+        {
+            get { return wrapped.Values; }
+        }
+
+        public TValue this[TKey key]
+        {
+            get { return wrapped[key]; }
+            set { throw new InvalidOperationException(); }
+        }
+
+        public void Add(KeyValuePair<TKey, TValue> item)
+        {
+            throw new InvalidOperationException();
+        }
+
+        public void Clear()
+        {
+            throw new InvalidOperationException();
+        }
+
+        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 true; }
+        }
+
+        public bool Remove(KeyValuePair<TKey, TValue> item)
+        {
+            throw new InvalidOperationException();
+        }
+
+        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+        {
+            return wrapped.GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return ((IEnumerable) wrapped).GetEnumerator();
+        }
+
+        public override bool Equals(object obj)
+        {
+            return wrapped.Equals(obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return wrapped.GetHashCode();
+        }
+
+        public override string ToString()
+        {
+            return wrapped.ToString();
+        }
+    }
+}

+ 60 - 51
src/ProtocolBuffers/Delegates.cs

@@ -1,51 +1,60 @@
-#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;
-
-namespace Google.ProtocolBuffers {
-  /// <summary>
-  /// Delegate to return a stream when asked, used by MessageStreamIterator.
-  /// </summary>
-  public delegate Stream StreamProvider();
-
-  // These delegate declarations mirror the ones in .NET 3.5 for the sake of familiarity.
-  internal delegate TResult Func<TResult>();
-  internal delegate TResult Func<T, TResult>(T arg);
-  internal delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
-  internal delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
-  internal delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-  internal delegate void Action();
-  internal delegate void Action<T1, T2>(T1 arg1, T2 arg2);
-}
+#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;
+
+namespace Google.ProtocolBuffers
+{
+    /// <summary>
+    /// Delegate to return a stream when asked, used by MessageStreamIterator.
+    /// </summary>
+    public delegate Stream StreamProvider();
+
+    // These delegate declarations mirror the ones in .NET 3.5 for the sake of familiarity.
+    internal delegate TResult Func<TResult>();
+
+    internal delegate TResult Func<T, TResult>(T arg);
+
+    internal delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
+
+    internal delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
+
+    internal delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+
+    internal delegate void Action();
+
+    internal delegate void Action<T1, T2>(T1 arg1, T2 arg2);
+}

+ 2209 - 1451
src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs

@@ -4,1483 +4,2241 @@ 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.DescriptorProtos {
-  
-  public static partial class CSharpOptions {
-  
-    #region Extension registration
-    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
-      registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFileOptions);
-      registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFieldOptions);
-      registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CsharpServiceOptions);
-      registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CsharpMethodOptions);
-    }
-    #endregion
-    #region Extensions
-    public const int CSharpFileOptionsFieldNumber = 1000;
-    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions> CSharpFileOptions;
-    public const int CSharpFieldOptionsFieldNumber = 1000;
-    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions> CSharpFieldOptions;
-    public const int CsharpServiceOptionsFieldNumber = 1000;
-    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions> CsharpServiceOptions;
-    public const int CsharpMethodOptionsFieldNumber = 1000;
-    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions> CsharpMethodOptions;
-    #endregion
-    
-    #region Static variables
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFileOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Builder> internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFieldOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Builder> internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpServiceOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.Builder> internal__static_google_protobuf_CSharpServiceOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpMethodOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.Builder> internal__static_google_protobuf_CSharpMethodOptions__FieldAccessorTable;
-    #endregion
-    #region Descriptor
-    public static pbd::FileDescriptor Descriptor {
-      get { return descriptor; }
+
+namespace Google.ProtocolBuffers.DescriptorProtos
+{
+    public static partial class CSharpOptions
+    {
+        #region Extension registration
+
+        public static void RegisterAllExtensions(pb::ExtensionRegistry registry)
+        {
+            registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFileOptions);
+            registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFieldOptions);
+            registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CsharpServiceOptions);
+            registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CsharpMethodOptions);
+        }
+
+        #endregion
+
+        #region Extensions
+
+        public const int CSharpFileOptionsFieldNumber = 1000;
+
+        public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions>
+            CSharpFileOptions;
+
+        public const int CSharpFieldOptionsFieldNumber = 1000;
+
+        public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions>
+            CSharpFieldOptions;
+
+        public const int CsharpServiceOptionsFieldNumber = 1000;
+
+        public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions>
+            CsharpServiceOptions;
+
+        public const int CsharpMethodOptionsFieldNumber = 1000;
+
+        public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions>
+            CsharpMethodOptions;
+
+        #endregion
+
+        #region Static variables
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFileOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Builder>
+            internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFieldOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Builder>
+            internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpServiceOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.Builder>
+            internal__static_google_protobuf_CSharpServiceOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpMethodOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.Builder>
+            internal__static_google_protobuf_CSharpMethodOptions__FieldAccessorTable;
+
+        #endregion
+
+        #region Descriptor
+
+        public static pbd::FileDescriptor Descriptor
+        {
+            get { return descriptor; }
+        }
+
+        private static pbd::FileDescriptor descriptor;
+
+        static CSharpOptions()
+        {
+            byte[] descriptorData = global::System.Convert.FromBase64String(
+                "CiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8SD2dvb2ds" +
+                "ZS5wcm90b2J1ZhogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8i" +
+                "tgMKEUNTaGFycEZpbGVPcHRpb25zEhEKCW5hbWVzcGFjZRgBIAEoCRIaChJ1" +
+                "bWJyZWxsYV9jbGFzc25hbWUYAiABKAkSHAoOcHVibGljX2NsYXNzZXMYAyAB" +
+                "KAg6BHRydWUSFgoObXVsdGlwbGVfZmlsZXMYBCABKAgSFAoMbmVzdF9jbGFz" +
+                "c2VzGAUgASgIEhYKDmNvZGVfY29udHJhY3RzGAYgASgIEiQKHGV4cGFuZF9u" +
+                "YW1lc3BhY2VfZGlyZWN0b3JpZXMYByABKAgSHAoOY2xzX2NvbXBsaWFuY2UY" +
+                "CCABKAg6BHRydWUSHAoOZmlsZV9leHRlbnNpb24Y3QEgASgJOgMuY3MSGwoS" +
+                "dW1icmVsbGFfbmFtZXNwYWNlGN4BIAEoCRIcChBvdXRwdXRfZGlyZWN0b3J5" +
+                "GN8BIAEoCToBLhImChZpZ25vcmVfZ29vZ2xlX3Byb3RvYnVmGOABIAEoCDoF" +
+                "ZmFsc2USSQoWc2VydmljZV9nZW5lcmF0b3JfdHlwZRjhASABKA4yIi5nb29n" +
+                "bGUucHJvdG9idWYuQ1NoYXJwU2VydmljZVR5cGU6BE5PTkUiKwoSQ1NoYXJw" +
+                "RmllbGRPcHRpb25zEhUKDXByb3BlcnR5X25hbWUYASABKAkiLAoUQ1NoYXJw" +
+                "U2VydmljZU9wdGlvbnMSFAoMaW50ZXJmYWNlX2lkGAEgASgJIioKE0NTaGFy" +
+                "cE1ldGhvZE9wdGlvbnMSEwoLZGlzcGF0Y2hfaWQYASABKAUqSwoRQ1NoYXJw" +
+                "U2VydmljZVR5cGUSCAoETk9ORRAAEgsKB0dFTkVSSUMQARINCglJTlRFUkZB" +
+                "Q0UQAhIQCgxJUlBDRElTUEFUQ0gQAzpeChNjc2hhcnBfZmlsZV9vcHRpb25z" +
+                "EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGOgHIAEoCzIiLmdvb2ds" +
+                "ZS5wcm90b2J1Zi5DU2hhcnBGaWxlT3B0aW9uczphChRjc2hhcnBfZmllbGRf" +
+                "b3B0aW9ucxIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY6AcgASgL" +
+                "MiMuZ29vZ2xlLnByb3RvYnVmLkNTaGFycEZpZWxkT3B0aW9uczpnChZjc2hh" +
+                "cnBfc2VydmljZV9vcHRpb25zEh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VP" +
+                "cHRpb25zGOgHIAEoCzIlLmdvb2dsZS5wcm90b2J1Zi5DU2hhcnBTZXJ2aWNl" +
+                "T3B0aW9uczpkChVjc2hhcnBfbWV0aG9kX29wdGlvbnMSHi5nb29nbGUucHJv" +
+                "dG9idWYuTWV0aG9kT3B0aW9ucxjoByABKAsyJC5nb29nbGUucHJvdG9idWYu" +
+                "Q1NoYXJwTWV0aG9kT3B0aW9ucw==");
+            pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root)
+                                                                          {
+                                                                              descriptor = root;
+                                                                              internal__static_google_protobuf_CSharpFileOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[0];
+                                                                              internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpFileOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpFileOptions.Builder>
+                                                                                      (internal__static_google_protobuf_CSharpFileOptions__Descriptor,
+                                                                                       new string[]
+                                                                                           {
+                                                                                               "Namespace",
+                                                                                               "UmbrellaClassname",
+                                                                                               "PublicClasses",
+                                                                                               "MultipleFiles",
+                                                                                               "NestClasses",
+                                                                                               "CodeContracts",
+                                                                                               "ExpandNamespaceDirectories"
+                                                                                               , "ClsCompliance",
+                                                                                               "FileExtension",
+                                                                                               "UmbrellaNamespace",
+                                                                                               "OutputDirectory",
+                                                                                               "IgnoreGoogleProtobuf",
+                                                                                               "ServiceGeneratorType",
+                                                                                           });
+                                                                              internal__static_google_protobuf_CSharpFieldOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[1];
+                                                                              internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpFieldOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpFieldOptions.Builder
+                                                                                          >(
+                                                                                      internal__static_google_protobuf_CSharpFieldOptions__Descriptor,
+                                                                                      new string[] {"PropertyName",});
+                                                                              internal__static_google_protobuf_CSharpServiceOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[2];
+                                                                              internal__static_google_protobuf_CSharpServiceOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpServiceOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpServiceOptions.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_CSharpServiceOptions__Descriptor,
+                                                                                      new string[] {"InterfaceId",});
+                                                                              internal__static_google_protobuf_CSharpMethodOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[3];
+                                                                              internal__static_google_protobuf_CSharpMethodOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpMethodOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpMethodOptions.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_CSharpMethodOptions__Descriptor,
+                                                                                      new string[] {"DispatchId",});
+                                                                              global::Google.ProtocolBuffers.
+                                                                                  DescriptorProtos.CSharpOptions.
+                                                                                  CSharpFileOptions =
+                                                                                  pb::GeneratedSingleExtension
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpFileOptions>.
+                                                                                      CreateInstance(
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpOptions.Descriptor.
+                                                                                              Extensions[0]);
+                                                                              global::Google.ProtocolBuffers.
+                                                                                  DescriptorProtos.CSharpOptions.
+                                                                                  CSharpFieldOptions =
+                                                                                  pb::GeneratedSingleExtension
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpFieldOptions>.
+                                                                                      CreateInstance(
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpOptions.Descriptor.
+                                                                                              Extensions[1]);
+                                                                              global::Google.ProtocolBuffers.
+                                                                                  DescriptorProtos.CSharpOptions.
+                                                                                  CsharpServiceOptions =
+                                                                                  pb::GeneratedSingleExtension
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpServiceOptions>.
+                                                                                      CreateInstance(
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpOptions.Descriptor.
+                                                                                              Extensions[2]);
+                                                                              global::Google.ProtocolBuffers.
+                                                                                  DescriptorProtos.CSharpOptions.
+                                                                                  CsharpMethodOptions =
+                                                                                  pb::GeneratedSingleExtension
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpMethodOptions>.
+                                                                                      CreateInstance(
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              CSharpOptions.Descriptor.
+                                                                                              Extensions[3]);
+                                                                              return null;
+                                                                          };
+            pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+                                                               new pbd::FileDescriptor[]
+                                                                   {
+                                                                       global::Google.ProtocolBuffers.DescriptorProtos.
+                                                                           DescriptorProtoFile.Descriptor,
+                                                                   }, assigner);
+        }
+
+        #endregion
     }
-    private static pbd::FileDescriptor descriptor;
-    
-    static CSharpOptions() {
-      byte[] descriptorData = global::System.Convert.FromBase64String(
-          "CiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8SD2dvb2ds" + 
-          "ZS5wcm90b2J1ZhogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8i" + 
-          "tgMKEUNTaGFycEZpbGVPcHRpb25zEhEKCW5hbWVzcGFjZRgBIAEoCRIaChJ1" + 
-          "bWJyZWxsYV9jbGFzc25hbWUYAiABKAkSHAoOcHVibGljX2NsYXNzZXMYAyAB" + 
-          "KAg6BHRydWUSFgoObXVsdGlwbGVfZmlsZXMYBCABKAgSFAoMbmVzdF9jbGFz" + 
-          "c2VzGAUgASgIEhYKDmNvZGVfY29udHJhY3RzGAYgASgIEiQKHGV4cGFuZF9u" + 
-          "YW1lc3BhY2VfZGlyZWN0b3JpZXMYByABKAgSHAoOY2xzX2NvbXBsaWFuY2UY" + 
-          "CCABKAg6BHRydWUSHAoOZmlsZV9leHRlbnNpb24Y3QEgASgJOgMuY3MSGwoS" + 
-          "dW1icmVsbGFfbmFtZXNwYWNlGN4BIAEoCRIcChBvdXRwdXRfZGlyZWN0b3J5" + 
-          "GN8BIAEoCToBLhImChZpZ25vcmVfZ29vZ2xlX3Byb3RvYnVmGOABIAEoCDoF" + 
-          "ZmFsc2USSQoWc2VydmljZV9nZW5lcmF0b3JfdHlwZRjhASABKA4yIi5nb29n" + 
-          "bGUucHJvdG9idWYuQ1NoYXJwU2VydmljZVR5cGU6BE5PTkUiKwoSQ1NoYXJw" + 
-          "RmllbGRPcHRpb25zEhUKDXByb3BlcnR5X25hbWUYASABKAkiLAoUQ1NoYXJw" + 
-          "U2VydmljZU9wdGlvbnMSFAoMaW50ZXJmYWNlX2lkGAEgASgJIioKE0NTaGFy" + 
-          "cE1ldGhvZE9wdGlvbnMSEwoLZGlzcGF0Y2hfaWQYASABKAUqSwoRQ1NoYXJw" + 
-          "U2VydmljZVR5cGUSCAoETk9ORRAAEgsKB0dFTkVSSUMQARINCglJTlRFUkZB" + 
-          "Q0UQAhIQCgxJUlBDRElTUEFUQ0gQAzpeChNjc2hhcnBfZmlsZV9vcHRpb25z" + 
-          "EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGOgHIAEoCzIiLmdvb2ds" + 
-          "ZS5wcm90b2J1Zi5DU2hhcnBGaWxlT3B0aW9uczphChRjc2hhcnBfZmllbGRf" + 
-          "b3B0aW9ucxIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY6AcgASgL" + 
-          "MiMuZ29vZ2xlLnByb3RvYnVmLkNTaGFycEZpZWxkT3B0aW9uczpnChZjc2hh" + 
-          "cnBfc2VydmljZV9vcHRpb25zEh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VP" + 
-          "cHRpb25zGOgHIAEoCzIlLmdvb2dsZS5wcm90b2J1Zi5DU2hhcnBTZXJ2aWNl" + 
-          "T3B0aW9uczpkChVjc2hhcnBfbWV0aG9kX29wdGlvbnMSHi5nb29nbGUucHJv" + 
-          "dG9idWYuTWV0aG9kT3B0aW9ucxjoByABKAsyJC5nb29nbGUucHJvdG9idWYu" + 
-          "Q1NoYXJwTWV0aG9kT3B0aW9ucw==");
-      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
-        descriptor = root;
-        internal__static_google_protobuf_CSharpFileOptions__Descriptor = Descriptor.MessageTypes[0];
-        internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Builder>(internal__static_google_protobuf_CSharpFileOptions__Descriptor,
-                new string[] { "Namespace", "UmbrellaClassname", "PublicClasses", "MultipleFiles", "NestClasses", "CodeContracts", "ExpandNamespaceDirectories", "ClsCompliance", "FileExtension", "UmbrellaNamespace", "OutputDirectory", "IgnoreGoogleProtobuf", "ServiceGeneratorType", });
-        internal__static_google_protobuf_CSharpFieldOptions__Descriptor = Descriptor.MessageTypes[1];
-        internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Builder>(internal__static_google_protobuf_CSharpFieldOptions__Descriptor,
-                new string[] { "PropertyName", });
-        internal__static_google_protobuf_CSharpServiceOptions__Descriptor = Descriptor.MessageTypes[2];
-        internal__static_google_protobuf_CSharpServiceOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.Builder>(internal__static_google_protobuf_CSharpServiceOptions__Descriptor,
-                new string[] { "InterfaceId", });
-        internal__static_google_protobuf_CSharpMethodOptions__Descriptor = Descriptor.MessageTypes[3];
-        internal__static_google_protobuf_CSharpMethodOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.Builder>(internal__static_google_protobuf_CSharpMethodOptions__Descriptor,
-                new string[] { "DispatchId", });
-        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFileOptions = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions>.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[0]);
-        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFieldOptions = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions>.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[1]);
-        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CsharpServiceOptions = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions>.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[2]);
-        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CsharpMethodOptions = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions>.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[3]);
-        return null;
-      };
-      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
-          new pbd::FileDescriptor[] {
-          global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, 
-          }, assigner);
+
+    #region Enums
+
+    public enum CSharpServiceType
+    {
+        NONE = 0,
+        GENERIC = 1,
+        INTERFACE = 2,
+        IRPCDISPATCH = 3,
     }
+
     #endregion
-    
-  }
-  #region Enums
-  public enum CSharpServiceType {
-    NONE = 0,
-    GENERIC = 1,
-    INTERFACE = 2,
-    IRPCDISPATCH = 3,
-  }
-  
-  #endregion
-  
-  #region Messages
-  public sealed partial class CSharpFileOptions : pb::GeneratedMessage<CSharpFileOptions, CSharpFileOptions.Builder> {
-    private static readonly CSharpFileOptions defaultInstance = new Builder().BuildPartial();
-    public static CSharpFileOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override CSharpFileOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override CSharpFileOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpFileOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<CSharpFileOptions, CSharpFileOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable; }
-    }
-    
-    public const int NamespaceFieldNumber = 1;
-    private bool hasNamespace;
-    private string namespace_ = "";
-    public bool HasNamespace {
-      get { return hasNamespace; }
-    }
-    public string Namespace {
-      get { return namespace_; }
-    }
-    
-    public const int UmbrellaClassnameFieldNumber = 2;
-    private bool hasUmbrellaClassname;
-    private string umbrellaClassname_ = "";
-    public bool HasUmbrellaClassname {
-      get { return hasUmbrellaClassname; }
-    }
-    public string UmbrellaClassname {
-      get { return umbrellaClassname_; }
-    }
-    
-    public const int PublicClassesFieldNumber = 3;
-    private bool hasPublicClasses;
-    private bool publicClasses_ = true;
-    public bool HasPublicClasses {
-      get { return hasPublicClasses; }
-    }
-    public bool PublicClasses {
-      get { return publicClasses_; }
-    }
-    
-    public const int MultipleFilesFieldNumber = 4;
-    private bool hasMultipleFiles;
-    private bool multipleFiles_ = false;
-    public bool HasMultipleFiles {
-      get { return hasMultipleFiles; }
-    }
-    public bool MultipleFiles {
-      get { return multipleFiles_; }
-    }
-    
-    public const int NestClassesFieldNumber = 5;
-    private bool hasNestClasses;
-    private bool nestClasses_ = false;
-    public bool HasNestClasses {
-      get { return hasNestClasses; }
-    }
-    public bool NestClasses {
-      get { return nestClasses_; }
-    }
-    
-    public const int CodeContractsFieldNumber = 6;
-    private bool hasCodeContracts;
-    private bool codeContracts_ = false;
-    public bool HasCodeContracts {
-      get { return hasCodeContracts; }
-    }
-    public bool CodeContracts {
-      get { return codeContracts_; }
-    }
-    
-    public const int ExpandNamespaceDirectoriesFieldNumber = 7;
-    private bool hasExpandNamespaceDirectories;
-    private bool expandNamespaceDirectories_ = false;
-    public bool HasExpandNamespaceDirectories {
-      get { return hasExpandNamespaceDirectories; }
-    }
-    public bool ExpandNamespaceDirectories {
-      get { return expandNamespaceDirectories_; }
-    }
-    
-    public const int ClsComplianceFieldNumber = 8;
-    private bool hasClsCompliance;
-    private bool clsCompliance_ = true;
-    public bool HasClsCompliance {
-      get { return hasClsCompliance; }
-    }
-    public bool ClsCompliance {
-      get { return clsCompliance_; }
-    }
-    
-    public const int FileExtensionFieldNumber = 221;
-    private bool hasFileExtension;
-    private string fileExtension_ = ".cs";
-    public bool HasFileExtension {
-      get { return hasFileExtension; }
-    }
-    public string FileExtension {
-      get { return fileExtension_; }
-    }
-    
-    public const int UmbrellaNamespaceFieldNumber = 222;
-    private bool hasUmbrellaNamespace;
-    private string umbrellaNamespace_ = "";
-    public bool HasUmbrellaNamespace {
-      get { return hasUmbrellaNamespace; }
-    }
-    public string UmbrellaNamespace {
-      get { return umbrellaNamespace_; }
-    }
-    
-    public const int OutputDirectoryFieldNumber = 223;
-    private bool hasOutputDirectory;
-    private string outputDirectory_ = ".";
-    public bool HasOutputDirectory {
-      get { return hasOutputDirectory; }
-    }
-    public string OutputDirectory {
-      get { return outputDirectory_; }
-    }
-    
-    public const int IgnoreGoogleProtobufFieldNumber = 224;
-    private bool hasIgnoreGoogleProtobuf;
-    private bool ignoreGoogleProtobuf_ = false;
-    public bool HasIgnoreGoogleProtobuf {
-      get { return hasIgnoreGoogleProtobuf; }
-    }
-    public bool IgnoreGoogleProtobuf {
-      get { return ignoreGoogleProtobuf_; }
-    }
-    
-    public const int ServiceGeneratorTypeFieldNumber = 225;
-    private bool hasServiceGeneratorType;
-    private global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType serviceGeneratorType_ = global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType.NONE;
-    public bool HasServiceGeneratorType {
-      get { return hasServiceGeneratorType; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType ServiceGeneratorType {
-      get { return serviceGeneratorType_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        return true;
-      }
+
+    #region Messages
+
+    public sealed partial class CSharpFileOptions : pb::GeneratedMessage<CSharpFileOptions, CSharpFileOptions.Builder>
+    {
+        private static readonly CSharpFileOptions defaultInstance = new Builder().BuildPartial();
+
+        public static CSharpFileOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override CSharpFileOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override CSharpFileOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.
+                        internal__static_google_protobuf_CSharpFileOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<CSharpFileOptions, CSharpFileOptions.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.
+                        internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable;
+            }
+        }
+
+        public const int NamespaceFieldNumber = 1;
+        private bool hasNamespace;
+        private string namespace_ = "";
+
+        public bool HasNamespace
+        {
+            get { return hasNamespace; }
+        }
+
+        public string Namespace
+        {
+            get { return namespace_; }
+        }
+
+        public const int UmbrellaClassnameFieldNumber = 2;
+        private bool hasUmbrellaClassname;
+        private string umbrellaClassname_ = "";
+
+        public bool HasUmbrellaClassname
+        {
+            get { return hasUmbrellaClassname; }
+        }
+
+        public string UmbrellaClassname
+        {
+            get { return umbrellaClassname_; }
+        }
+
+        public const int PublicClassesFieldNumber = 3;
+        private bool hasPublicClasses;
+        private bool publicClasses_ = true;
+
+        public bool HasPublicClasses
+        {
+            get { return hasPublicClasses; }
+        }
+
+        public bool PublicClasses
+        {
+            get { return publicClasses_; }
+        }
+
+        public const int MultipleFilesFieldNumber = 4;
+        private bool hasMultipleFiles;
+        private bool multipleFiles_ = false;
+
+        public bool HasMultipleFiles
+        {
+            get { return hasMultipleFiles; }
+        }
+
+        public bool MultipleFiles
+        {
+            get { return multipleFiles_; }
+        }
+
+        public const int NestClassesFieldNumber = 5;
+        private bool hasNestClasses;
+        private bool nestClasses_ = false;
+
+        public bool HasNestClasses
+        {
+            get { return hasNestClasses; }
+        }
+
+        public bool NestClasses
+        {
+            get { return nestClasses_; }
+        }
+
+        public const int CodeContractsFieldNumber = 6;
+        private bool hasCodeContracts;
+        private bool codeContracts_ = false;
+
+        public bool HasCodeContracts
+        {
+            get { return hasCodeContracts; }
+        }
+
+        public bool CodeContracts
+        {
+            get { return codeContracts_; }
+        }
+
+        public const int ExpandNamespaceDirectoriesFieldNumber = 7;
+        private bool hasExpandNamespaceDirectories;
+        private bool expandNamespaceDirectories_ = false;
+
+        public bool HasExpandNamespaceDirectories
+        {
+            get { return hasExpandNamespaceDirectories; }
+        }
+
+        public bool ExpandNamespaceDirectories
+        {
+            get { return expandNamespaceDirectories_; }
+        }
+
+        public const int ClsComplianceFieldNumber = 8;
+        private bool hasClsCompliance;
+        private bool clsCompliance_ = true;
+
+        public bool HasClsCompliance
+        {
+            get { return hasClsCompliance; }
+        }
+
+        public bool ClsCompliance
+        {
+            get { return clsCompliance_; }
+        }
+
+        public const int FileExtensionFieldNumber = 221;
+        private bool hasFileExtension;
+        private string fileExtension_ = ".cs";
+
+        public bool HasFileExtension
+        {
+            get { return hasFileExtension; }
+        }
+
+        public string FileExtension
+        {
+            get { return fileExtension_; }
+        }
+
+        public const int UmbrellaNamespaceFieldNumber = 222;
+        private bool hasUmbrellaNamespace;
+        private string umbrellaNamespace_ = "";
+
+        public bool HasUmbrellaNamespace
+        {
+            get { return hasUmbrellaNamespace; }
+        }
+
+        public string UmbrellaNamespace
+        {
+            get { return umbrellaNamespace_; }
+        }
+
+        public const int OutputDirectoryFieldNumber = 223;
+        private bool hasOutputDirectory;
+        private string outputDirectory_ = ".";
+
+        public bool HasOutputDirectory
+        {
+            get { return hasOutputDirectory; }
+        }
+
+        public string OutputDirectory
+        {
+            get { return outputDirectory_; }
+        }
+
+        public const int IgnoreGoogleProtobufFieldNumber = 224;
+        private bool hasIgnoreGoogleProtobuf;
+        private bool ignoreGoogleProtobuf_ = false;
+
+        public bool HasIgnoreGoogleProtobuf
+        {
+            get { return hasIgnoreGoogleProtobuf; }
+        }
+
+        public bool IgnoreGoogleProtobuf
+        {
+            get { return ignoreGoogleProtobuf_; }
+        }
+
+        public const int ServiceGeneratorTypeFieldNumber = 225;
+        private bool hasServiceGeneratorType;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType serviceGeneratorType_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType.NONE;
+
+        public bool HasServiceGeneratorType
+        {
+            get { return hasServiceGeneratorType; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType ServiceGeneratorType
+        {
+            get { return serviceGeneratorType_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get { return true; }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasNamespace)
+            {
+                output.WriteString(1, Namespace);
+            }
+            if (HasUmbrellaClassname)
+            {
+                output.WriteString(2, UmbrellaClassname);
+            }
+            if (HasPublicClasses)
+            {
+                output.WriteBool(3, PublicClasses);
+            }
+            if (HasMultipleFiles)
+            {
+                output.WriteBool(4, MultipleFiles);
+            }
+            if (HasNestClasses)
+            {
+                output.WriteBool(5, NestClasses);
+            }
+            if (HasCodeContracts)
+            {
+                output.WriteBool(6, CodeContracts);
+            }
+            if (HasExpandNamespaceDirectories)
+            {
+                output.WriteBool(7, ExpandNamespaceDirectories);
+            }
+            if (HasClsCompliance)
+            {
+                output.WriteBool(8, ClsCompliance);
+            }
+            if (HasFileExtension)
+            {
+                output.WriteString(221, FileExtension);
+            }
+            if (HasUmbrellaNamespace)
+            {
+                output.WriteString(222, UmbrellaNamespace);
+            }
+            if (HasOutputDirectory)
+            {
+                output.WriteString(223, OutputDirectory);
+            }
+            if (HasIgnoreGoogleProtobuf)
+            {
+                output.WriteBool(224, IgnoreGoogleProtobuf);
+            }
+            if (HasServiceGeneratorType)
+            {
+                output.WriteEnum(225, (int) ServiceGeneratorType);
+            }
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                if (HasNamespace)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(1, Namespace);
+                }
+                if (HasUmbrellaClassname)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(2, UmbrellaClassname);
+                }
+                if (HasPublicClasses)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(3, PublicClasses);
+                }
+                if (HasMultipleFiles)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(4, MultipleFiles);
+                }
+                if (HasNestClasses)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(5, NestClasses);
+                }
+                if (HasCodeContracts)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(6, CodeContracts);
+                }
+                if (HasExpandNamespaceDirectories)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(7, ExpandNamespaceDirectories);
+                }
+                if (HasClsCompliance)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(8, ClsCompliance);
+                }
+                if (HasFileExtension)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(221, FileExtension);
+                }
+                if (HasUmbrellaNamespace)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(222, UmbrellaNamespace);
+                }
+                if (HasOutputDirectory)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(223, OutputDirectory);
+                }
+                if (HasIgnoreGoogleProtobuf)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(224, IgnoreGoogleProtobuf);
+                }
+                if (HasServiceGeneratorType)
+                {
+                    size += pb::CodedOutputStream.ComputeEnumSize(225, (int) ServiceGeneratorType);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static CSharpFileOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static CSharpFileOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpFileOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static CSharpFileOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpFileOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static CSharpFileOptions ParseFrom(global::System.IO.Stream input,
+                                                  pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpFileOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static CSharpFileOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                           pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static CSharpFileOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static CSharpFileOptions 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(CSharpFileOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<CSharpFileOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private CSharpFileOptions result = new CSharpFileOptions();
+
+            protected override CSharpFileOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new CSharpFileOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Descriptor; }
+            }
+
+            public override CSharpFileOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.DefaultInstance; }
+            }
+
+            public override CSharpFileOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                CSharpFileOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is CSharpFileOptions)
+                {
+                    return MergeFrom((CSharpFileOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(CSharpFileOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.DefaultInstance)
+                    return this;
+                if (other.HasNamespace)
+                {
+                    Namespace = other.Namespace;
+                }
+                if (other.HasUmbrellaClassname)
+                {
+                    UmbrellaClassname = other.UmbrellaClassname;
+                }
+                if (other.HasPublicClasses)
+                {
+                    PublicClasses = other.PublicClasses;
+                }
+                if (other.HasMultipleFiles)
+                {
+                    MultipleFiles = other.MultipleFiles;
+                }
+                if (other.HasNestClasses)
+                {
+                    NestClasses = other.NestClasses;
+                }
+                if (other.HasCodeContracts)
+                {
+                    CodeContracts = other.CodeContracts;
+                }
+                if (other.HasExpandNamespaceDirectories)
+                {
+                    ExpandNamespaceDirectories = other.ExpandNamespaceDirectories;
+                }
+                if (other.HasClsCompliance)
+                {
+                    ClsCompliance = other.ClsCompliance;
+                }
+                if (other.HasFileExtension)
+                {
+                    FileExtension = other.FileExtension;
+                }
+                if (other.HasUmbrellaNamespace)
+                {
+                    UmbrellaNamespace = other.UmbrellaNamespace;
+                }
+                if (other.HasOutputDirectory)
+                {
+                    OutputDirectory = other.OutputDirectory;
+                }
+                if (other.HasIgnoreGoogleProtobuf)
+                {
+                    IgnoreGoogleProtobuf = other.IgnoreGoogleProtobuf;
+                }
+                if (other.HasServiceGeneratorType)
+                {
+                    ServiceGeneratorType = other.ServiceGeneratorType;
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                Namespace = input.ReadString();
+                                break;
+                            }
+                        case 18:
+                            {
+                                UmbrellaClassname = input.ReadString();
+                                break;
+                            }
+                        case 24:
+                            {
+                                PublicClasses = input.ReadBool();
+                                break;
+                            }
+                        case 32:
+                            {
+                                MultipleFiles = input.ReadBool();
+                                break;
+                            }
+                        case 40:
+                            {
+                                NestClasses = input.ReadBool();
+                                break;
+                            }
+                        case 48:
+                            {
+                                CodeContracts = input.ReadBool();
+                                break;
+                            }
+                        case 56:
+                            {
+                                ExpandNamespaceDirectories = input.ReadBool();
+                                break;
+                            }
+                        case 64:
+                            {
+                                ClsCompliance = input.ReadBool();
+                                break;
+                            }
+                        case 1770:
+                            {
+                                FileExtension = input.ReadString();
+                                break;
+                            }
+                        case 1778:
+                            {
+                                UmbrellaNamespace = input.ReadString();
+                                break;
+                            }
+                        case 1786:
+                            {
+                                OutputDirectory = input.ReadString();
+                                break;
+                            }
+                        case 1792:
+                            {
+                                IgnoreGoogleProtobuf = input.ReadBool();
+                                break;
+                            }
+                        case 1800:
+                            {
+                                int rawValue = input.ReadEnum();
+                                if (
+                                    !global::System.Enum.IsDefined(
+                                        typeof (global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType),
+                                        rawValue))
+                                {
+                                    if (unknownFields == null)
+                                    {
+                                        unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                    }
+                                    unknownFields.MergeVarintField(225, (ulong) rawValue);
+                                }
+                                else
+                                {
+                                    ServiceGeneratorType =
+                                        (global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType) rawValue;
+                                }
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public bool HasNamespace
+            {
+                get { return result.HasNamespace; }
+            }
+
+            public string Namespace
+            {
+                get { return result.Namespace; }
+                set { SetNamespace(value); }
+            }
+
+            public Builder SetNamespace(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasNamespace = true;
+                result.namespace_ = value;
+                return this;
+            }
+
+            public Builder ClearNamespace()
+            {
+                result.hasNamespace = false;
+                result.namespace_ = "";
+                return this;
+            }
+
+            public bool HasUmbrellaClassname
+            {
+                get { return result.HasUmbrellaClassname; }
+            }
+
+            public string UmbrellaClassname
+            {
+                get { return result.UmbrellaClassname; }
+                set { SetUmbrellaClassname(value); }
+            }
+
+            public Builder SetUmbrellaClassname(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasUmbrellaClassname = true;
+                result.umbrellaClassname_ = value;
+                return this;
+            }
+
+            public Builder ClearUmbrellaClassname()
+            {
+                result.hasUmbrellaClassname = false;
+                result.umbrellaClassname_ = "";
+                return this;
+            }
+
+            public bool HasPublicClasses
+            {
+                get { return result.HasPublicClasses; }
+            }
+
+            public bool PublicClasses
+            {
+                get { return result.PublicClasses; }
+                set { SetPublicClasses(value); }
+            }
+
+            public Builder SetPublicClasses(bool value)
+            {
+                result.hasPublicClasses = true;
+                result.publicClasses_ = value;
+                return this;
+            }
+
+            public Builder ClearPublicClasses()
+            {
+                result.hasPublicClasses = false;
+                result.publicClasses_ = true;
+                return this;
+            }
+
+            public bool HasMultipleFiles
+            {
+                get { return result.HasMultipleFiles; }
+            }
+
+            public bool MultipleFiles
+            {
+                get { return result.MultipleFiles; }
+                set { SetMultipleFiles(value); }
+            }
+
+            public Builder SetMultipleFiles(bool value)
+            {
+                result.hasMultipleFiles = true;
+                result.multipleFiles_ = value;
+                return this;
+            }
+
+            public Builder ClearMultipleFiles()
+            {
+                result.hasMultipleFiles = false;
+                result.multipleFiles_ = false;
+                return this;
+            }
+
+            public bool HasNestClasses
+            {
+                get { return result.HasNestClasses; }
+            }
+
+            public bool NestClasses
+            {
+                get { return result.NestClasses; }
+                set { SetNestClasses(value); }
+            }
+
+            public Builder SetNestClasses(bool value)
+            {
+                result.hasNestClasses = true;
+                result.nestClasses_ = value;
+                return this;
+            }
+
+            public Builder ClearNestClasses()
+            {
+                result.hasNestClasses = false;
+                result.nestClasses_ = false;
+                return this;
+            }
+
+            public bool HasCodeContracts
+            {
+                get { return result.HasCodeContracts; }
+            }
+
+            public bool CodeContracts
+            {
+                get { return result.CodeContracts; }
+                set { SetCodeContracts(value); }
+            }
+
+            public Builder SetCodeContracts(bool value)
+            {
+                result.hasCodeContracts = true;
+                result.codeContracts_ = value;
+                return this;
+            }
+
+            public Builder ClearCodeContracts()
+            {
+                result.hasCodeContracts = false;
+                result.codeContracts_ = false;
+                return this;
+            }
+
+            public bool HasExpandNamespaceDirectories
+            {
+                get { return result.HasExpandNamespaceDirectories; }
+            }
+
+            public bool ExpandNamespaceDirectories
+            {
+                get { return result.ExpandNamespaceDirectories; }
+                set { SetExpandNamespaceDirectories(value); }
+            }
+
+            public Builder SetExpandNamespaceDirectories(bool value)
+            {
+                result.hasExpandNamespaceDirectories = true;
+                result.expandNamespaceDirectories_ = value;
+                return this;
+            }
+
+            public Builder ClearExpandNamespaceDirectories()
+            {
+                result.hasExpandNamespaceDirectories = false;
+                result.expandNamespaceDirectories_ = false;
+                return this;
+            }
+
+            public bool HasClsCompliance
+            {
+                get { return result.HasClsCompliance; }
+            }
+
+            public bool ClsCompliance
+            {
+                get { return result.ClsCompliance; }
+                set { SetClsCompliance(value); }
+            }
+
+            public Builder SetClsCompliance(bool value)
+            {
+                result.hasClsCompliance = true;
+                result.clsCompliance_ = value;
+                return this;
+            }
+
+            public Builder ClearClsCompliance()
+            {
+                result.hasClsCompliance = false;
+                result.clsCompliance_ = true;
+                return this;
+            }
+
+            public bool HasFileExtension
+            {
+                get { return result.HasFileExtension; }
+            }
+
+            public string FileExtension
+            {
+                get { return result.FileExtension; }
+                set { SetFileExtension(value); }
+            }
+
+            public Builder SetFileExtension(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasFileExtension = true;
+                result.fileExtension_ = value;
+                return this;
+            }
+
+            public Builder ClearFileExtension()
+            {
+                result.hasFileExtension = false;
+                result.fileExtension_ = ".cs";
+                return this;
+            }
+
+            public bool HasUmbrellaNamespace
+            {
+                get { return result.HasUmbrellaNamespace; }
+            }
+
+            public string UmbrellaNamespace
+            {
+                get { return result.UmbrellaNamespace; }
+                set { SetUmbrellaNamespace(value); }
+            }
+
+            public Builder SetUmbrellaNamespace(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasUmbrellaNamespace = true;
+                result.umbrellaNamespace_ = value;
+                return this;
+            }
+
+            public Builder ClearUmbrellaNamespace()
+            {
+                result.hasUmbrellaNamespace = false;
+                result.umbrellaNamespace_ = "";
+                return this;
+            }
+
+            public bool HasOutputDirectory
+            {
+                get { return result.HasOutputDirectory; }
+            }
+
+            public string OutputDirectory
+            {
+                get { return result.OutputDirectory; }
+                set { SetOutputDirectory(value); }
+            }
+
+            public Builder SetOutputDirectory(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOutputDirectory = true;
+                result.outputDirectory_ = value;
+                return this;
+            }
+
+            public Builder ClearOutputDirectory()
+            {
+                result.hasOutputDirectory = false;
+                result.outputDirectory_ = ".";
+                return this;
+            }
+
+            public bool HasIgnoreGoogleProtobuf
+            {
+                get { return result.HasIgnoreGoogleProtobuf; }
+            }
+
+            public bool IgnoreGoogleProtobuf
+            {
+                get { return result.IgnoreGoogleProtobuf; }
+                set { SetIgnoreGoogleProtobuf(value); }
+            }
+
+            public Builder SetIgnoreGoogleProtobuf(bool value)
+            {
+                result.hasIgnoreGoogleProtobuf = true;
+                result.ignoreGoogleProtobuf_ = value;
+                return this;
+            }
+
+            public Builder ClearIgnoreGoogleProtobuf()
+            {
+                result.hasIgnoreGoogleProtobuf = false;
+                result.ignoreGoogleProtobuf_ = false;
+                return this;
+            }
+
+            public bool HasServiceGeneratorType
+            {
+                get { return result.HasServiceGeneratorType; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType ServiceGeneratorType
+            {
+                get { return result.ServiceGeneratorType; }
+                set { SetServiceGeneratorType(value); }
+            }
+
+            public Builder SetServiceGeneratorType(
+                global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType value)
+            {
+                result.hasServiceGeneratorType = true;
+                result.serviceGeneratorType_ = value;
+                return this;
+            }
+
+            public Builder ClearServiceGeneratorType()
+            {
+                result.hasServiceGeneratorType = false;
+                result.serviceGeneratorType_ = global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType.NONE;
+                return this;
+            }
+        }
+
+        static CSharpFileOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, null);
+        }
     }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasNamespace) {
-        output.WriteString(1, Namespace);
-      }
-      if (HasUmbrellaClassname) {
-        output.WriteString(2, UmbrellaClassname);
-      }
-      if (HasPublicClasses) {
-        output.WriteBool(3, PublicClasses);
-      }
-      if (HasMultipleFiles) {
-        output.WriteBool(4, MultipleFiles);
-      }
-      if (HasNestClasses) {
-        output.WriteBool(5, NestClasses);
-      }
-      if (HasCodeContracts) {
-        output.WriteBool(6, CodeContracts);
-      }
-      if (HasExpandNamespaceDirectories) {
-        output.WriteBool(7, ExpandNamespaceDirectories);
-      }
-      if (HasClsCompliance) {
-        output.WriteBool(8, ClsCompliance);
-      }
-      if (HasFileExtension) {
-        output.WriteString(221, FileExtension);
-      }
-      if (HasUmbrellaNamespace) {
-        output.WriteString(222, UmbrellaNamespace);
-      }
-      if (HasOutputDirectory) {
-        output.WriteString(223, OutputDirectory);
-      }
-      if (HasIgnoreGoogleProtobuf) {
-        output.WriteBool(224, IgnoreGoogleProtobuf);
-      }
-      if (HasServiceGeneratorType) {
-        output.WriteEnum(225, (int) ServiceGeneratorType);
-      }
-      UnknownFields.WriteTo(output);
+
+    public sealed partial class CSharpFieldOptions :
+        pb::GeneratedMessage<CSharpFieldOptions, CSharpFieldOptions.Builder>
+    {
+        private static readonly CSharpFieldOptions defaultInstance = new Builder().BuildPartial();
+
+        public static CSharpFieldOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override CSharpFieldOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override CSharpFieldOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.
+                        internal__static_google_protobuf_CSharpFieldOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<CSharpFieldOptions, CSharpFieldOptions.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.
+                        internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable;
+            }
+        }
+
+        public const int PropertyNameFieldNumber = 1;
+        private bool hasPropertyName;
+        private string propertyName_ = "";
+
+        public bool HasPropertyName
+        {
+            get { return hasPropertyName; }
+        }
+
+        public string PropertyName
+        {
+            get { return propertyName_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get { return true; }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasPropertyName)
+            {
+                output.WriteString(1, PropertyName);
+            }
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                if (HasPropertyName)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(1, PropertyName);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static CSharpFieldOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static CSharpFieldOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpFieldOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static CSharpFieldOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpFieldOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static CSharpFieldOptions ParseFrom(global::System.IO.Stream input,
+                                                   pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpFieldOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static CSharpFieldOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                            pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static CSharpFieldOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static CSharpFieldOptions 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(CSharpFieldOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<CSharpFieldOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private CSharpFieldOptions result = new CSharpFieldOptions();
+
+            protected override CSharpFieldOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new CSharpFieldOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Descriptor; }
+            }
+
+            public override CSharpFieldOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.DefaultInstance; }
+            }
+
+            public override CSharpFieldOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                CSharpFieldOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is CSharpFieldOptions)
+                {
+                    return MergeFrom((CSharpFieldOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(CSharpFieldOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.DefaultInstance)
+                    return this;
+                if (other.HasPropertyName)
+                {
+                    PropertyName = other.PropertyName;
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                PropertyName = input.ReadString();
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public bool HasPropertyName
+            {
+                get { return result.HasPropertyName; }
+            }
+
+            public string PropertyName
+            {
+                get { return result.PropertyName; }
+                set { SetPropertyName(value); }
+            }
+
+            public Builder SetPropertyName(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasPropertyName = true;
+                result.propertyName_ = value;
+                return this;
+            }
+
+            public Builder ClearPropertyName()
+            {
+                result.hasPropertyName = false;
+                result.propertyName_ = "";
+                return this;
+            }
+        }
+
+        static CSharpFieldOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, null);
+        }
     }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasNamespace) {
-          size += pb::CodedOutputStream.ComputeStringSize(1, Namespace);
+
+    public sealed partial class CSharpServiceOptions :
+        pb::GeneratedMessage<CSharpServiceOptions, CSharpServiceOptions.Builder>
+    {
+        private static readonly CSharpServiceOptions defaultInstance = new Builder().BuildPartial();
+
+        public static CSharpServiceOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override CSharpServiceOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override CSharpServiceOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.
+                        internal__static_google_protobuf_CSharpServiceOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<CSharpServiceOptions, CSharpServiceOptions.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.
+                        internal__static_google_protobuf_CSharpServiceOptions__FieldAccessorTable;
+            }
         }
-        if (HasUmbrellaClassname) {
-          size += pb::CodedOutputStream.ComputeStringSize(2, UmbrellaClassname);
+
+        public const int InterfaceIdFieldNumber = 1;
+        private bool hasInterfaceId;
+        private string interfaceId_ = "";
+
+        public bool HasInterfaceId
+        {
+            get { return hasInterfaceId; }
         }
-        if (HasPublicClasses) {
-          size += pb::CodedOutputStream.ComputeBoolSize(3, PublicClasses);
+
+        public string InterfaceId
+        {
+            get { return interfaceId_; }
         }
-        if (HasMultipleFiles) {
-          size += pb::CodedOutputStream.ComputeBoolSize(4, MultipleFiles);
+
+        public override bool IsInitialized
+        {
+            get { return true; }
         }
-        if (HasNestClasses) {
-          size += pb::CodedOutputStream.ComputeBoolSize(5, NestClasses);
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasInterfaceId)
+            {
+                output.WriteString(1, InterfaceId);
+            }
+            UnknownFields.WriteTo(output);
         }
-        if (HasCodeContracts) {
-          size += pb::CodedOutputStream.ComputeBoolSize(6, CodeContracts);
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                if (HasInterfaceId)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(1, InterfaceId);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
         }
-        if (HasExpandNamespaceDirectories) {
-          size += pb::CodedOutputStream.ComputeBoolSize(7, ExpandNamespaceDirectories);
+
+        public static CSharpServiceOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
         }
-        if (HasClsCompliance) {
-          size += pb::CodedOutputStream.ComputeBoolSize(8, ClsCompliance);
+
+        public static CSharpServiceOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
         }
-        if (HasFileExtension) {
-          size += pb::CodedOutputStream.ComputeStringSize(221, FileExtension);
+
+        public static CSharpServiceOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
         }
-        if (HasUmbrellaNamespace) {
-          size += pb::CodedOutputStream.ComputeStringSize(222, UmbrellaNamespace);
+
+        public static CSharpServiceOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
         }
-        if (HasOutputDirectory) {
-          size += pb::CodedOutputStream.ComputeStringSize(223, OutputDirectory);
+
+        public static CSharpServiceOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
         }
-        if (HasIgnoreGoogleProtobuf) {
-          size += pb::CodedOutputStream.ComputeBoolSize(224, IgnoreGoogleProtobuf);
+
+        public static CSharpServiceOptions ParseFrom(global::System.IO.Stream input,
+                                                     pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
-        if (HasServiceGeneratorType) {
-          size += pb::CodedOutputStream.ComputeEnumSize(225, (int) ServiceGeneratorType);
+
+        public static CSharpServiceOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
         }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static CSharpFileOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static CSharpFileOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpFileOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static CSharpFileOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpFileOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static CSharpFileOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpFileOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static CSharpFileOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static CSharpFileOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static CSharpFileOptions 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(CSharpFileOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<CSharpFileOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      CSharpFileOptions result = new CSharpFileOptions();
-      
-      protected override CSharpFileOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new CSharpFileOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Descriptor; }
-      }
-      
-      public override CSharpFileOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.DefaultInstance; }
-      }
-      
-      public override CSharpFileOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        CSharpFileOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is CSharpFileOptions) {
-          return MergeFrom((CSharpFileOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(CSharpFileOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.DefaultInstance) return this;
-        if (other.HasNamespace) {
-          Namespace = other.Namespace;
-        }
-        if (other.HasUmbrellaClassname) {
-          UmbrellaClassname = other.UmbrellaClassname;
-        }
-        if (other.HasPublicClasses) {
-          PublicClasses = other.PublicClasses;
-        }
-        if (other.HasMultipleFiles) {
-          MultipleFiles = other.MultipleFiles;
-        }
-        if (other.HasNestClasses) {
-          NestClasses = other.NestClasses;
-        }
-        if (other.HasCodeContracts) {
-          CodeContracts = other.CodeContracts;
-        }
-        if (other.HasExpandNamespaceDirectories) {
-          ExpandNamespaceDirectories = other.ExpandNamespaceDirectories;
-        }
-        if (other.HasClsCompliance) {
-          ClsCompliance = other.ClsCompliance;
-        }
-        if (other.HasFileExtension) {
-          FileExtension = other.FileExtension;
-        }
-        if (other.HasUmbrellaNamespace) {
-          UmbrellaNamespace = other.UmbrellaNamespace;
-        }
-        if (other.HasOutputDirectory) {
-          OutputDirectory = other.OutputDirectory;
-        }
-        if (other.HasIgnoreGoogleProtobuf) {
-          IgnoreGoogleProtobuf = other.IgnoreGoogleProtobuf;
-        }
-        if (other.HasServiceGeneratorType) {
-          ServiceGeneratorType = other.ServiceGeneratorType;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
+
+        public static CSharpServiceOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                              pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static CSharpServiceOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static CSharpServiceOptions 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(CSharpServiceOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<CSharpServiceOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private CSharpServiceOptions result = new CSharpServiceOptions();
+
+            protected override CSharpServiceOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new CSharpServiceOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.Descriptor; }
+            }
+
+            public override CSharpServiceOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.DefaultInstance; }
+            }
+
+            public override CSharpServiceOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                CSharpServiceOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is CSharpServiceOptions)
+                {
+                    return MergeFrom((CSharpServiceOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(CSharpServiceOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.DefaultInstance)
+                    return this;
+                if (other.HasInterfaceId)
+                {
+                    InterfaceId = other.InterfaceId;
                 }
+                this.MergeUnknownFields(other.UnknownFields);
                 return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Namespace = input.ReadString();
-              break;
-            }
-            case 18: {
-              UmbrellaClassname = input.ReadString();
-              break;
-            }
-            case 24: {
-              PublicClasses = input.ReadBool();
-              break;
-            }
-            case 32: {
-              MultipleFiles = input.ReadBool();
-              break;
-            }
-            case 40: {
-              NestClasses = input.ReadBool();
-              break;
-            }
-            case 48: {
-              CodeContracts = input.ReadBool();
-              break;
-            }
-            case 56: {
-              ExpandNamespaceDirectories = input.ReadBool();
-              break;
-            }
-            case 64: {
-              ClsCompliance = input.ReadBool();
-              break;
-            }
-            case 1770: {
-              FileExtension = input.ReadString();
-              break;
-            }
-            case 1778: {
-              UmbrellaNamespace = input.ReadString();
-              break;
-            }
-            case 1786: {
-              OutputDirectory = input.ReadString();
-              break;
-            }
-            case 1792: {
-              IgnoreGoogleProtobuf = input.ReadBool();
-              break;
-            }
-            case 1800: {
-              int rawValue = input.ReadEnum();
-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType), rawValue)) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            }
+
+            public override Builder MergeFrom(pb::CodedInputStream input)
+            {
+                return MergeFrom(input, pb::ExtensionRegistry.Empty);
+            }
+
+            public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                InterfaceId = input.ReadString();
+                                break;
+                            }
+                    }
                 }
-                unknownFields.MergeVarintField(225, (ulong) rawValue);
-              } else {
-                ServiceGeneratorType = (global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType) rawValue;
-              }
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasNamespace {
-        get { return result.HasNamespace; }
-      }
-      public string Namespace {
-        get { return result.Namespace; }
-        set { SetNamespace(value); }
-      }
-      public Builder SetNamespace(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasNamespace = true;
-        result.namespace_ = value;
-        return this;
-      }
-      public Builder ClearNamespace() {
-        result.hasNamespace = false;
-        result.namespace_ = "";
-        return this;
-      }
-      
-      public bool HasUmbrellaClassname {
-        get { return result.HasUmbrellaClassname; }
-      }
-      public string UmbrellaClassname {
-        get { return result.UmbrellaClassname; }
-        set { SetUmbrellaClassname(value); }
-      }
-      public Builder SetUmbrellaClassname(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasUmbrellaClassname = true;
-        result.umbrellaClassname_ = value;
-        return this;
-      }
-      public Builder ClearUmbrellaClassname() {
-        result.hasUmbrellaClassname = false;
-        result.umbrellaClassname_ = "";
-        return this;
-      }
-      
-      public bool HasPublicClasses {
-        get { return result.HasPublicClasses; }
-      }
-      public bool PublicClasses {
-        get { return result.PublicClasses; }
-        set { SetPublicClasses(value); }
-      }
-      public Builder SetPublicClasses(bool value) {
-        result.hasPublicClasses = true;
-        result.publicClasses_ = value;
-        return this;
-      }
-      public Builder ClearPublicClasses() {
-        result.hasPublicClasses = false;
-        result.publicClasses_ = true;
-        return this;
-      }
-      
-      public bool HasMultipleFiles {
-        get { return result.HasMultipleFiles; }
-      }
-      public bool MultipleFiles {
-        get { return result.MultipleFiles; }
-        set { SetMultipleFiles(value); }
-      }
-      public Builder SetMultipleFiles(bool value) {
-        result.hasMultipleFiles = true;
-        result.multipleFiles_ = value;
-        return this;
-      }
-      public Builder ClearMultipleFiles() {
-        result.hasMultipleFiles = false;
-        result.multipleFiles_ = false;
-        return this;
-      }
-      
-      public bool HasNestClasses {
-        get { return result.HasNestClasses; }
-      }
-      public bool NestClasses {
-        get { return result.NestClasses; }
-        set { SetNestClasses(value); }
-      }
-      public Builder SetNestClasses(bool value) {
-        result.hasNestClasses = true;
-        result.nestClasses_ = value;
-        return this;
-      }
-      public Builder ClearNestClasses() {
-        result.hasNestClasses = false;
-        result.nestClasses_ = false;
-        return this;
-      }
-      
-      public bool HasCodeContracts {
-        get { return result.HasCodeContracts; }
-      }
-      public bool CodeContracts {
-        get { return result.CodeContracts; }
-        set { SetCodeContracts(value); }
-      }
-      public Builder SetCodeContracts(bool value) {
-        result.hasCodeContracts = true;
-        result.codeContracts_ = value;
-        return this;
-      }
-      public Builder ClearCodeContracts() {
-        result.hasCodeContracts = false;
-        result.codeContracts_ = false;
-        return this;
-      }
-      
-      public bool HasExpandNamespaceDirectories {
-        get { return result.HasExpandNamespaceDirectories; }
-      }
-      public bool ExpandNamespaceDirectories {
-        get { return result.ExpandNamespaceDirectories; }
-        set { SetExpandNamespaceDirectories(value); }
-      }
-      public Builder SetExpandNamespaceDirectories(bool value) {
-        result.hasExpandNamespaceDirectories = true;
-        result.expandNamespaceDirectories_ = value;
-        return this;
-      }
-      public Builder ClearExpandNamespaceDirectories() {
-        result.hasExpandNamespaceDirectories = false;
-        result.expandNamespaceDirectories_ = false;
-        return this;
-      }
-      
-      public bool HasClsCompliance {
-        get { return result.HasClsCompliance; }
-      }
-      public bool ClsCompliance {
-        get { return result.ClsCompliance; }
-        set { SetClsCompliance(value); }
-      }
-      public Builder SetClsCompliance(bool value) {
-        result.hasClsCompliance = true;
-        result.clsCompliance_ = value;
-        return this;
-      }
-      public Builder ClearClsCompliance() {
-        result.hasClsCompliance = false;
-        result.clsCompliance_ = true;
-        return this;
-      }
-      
-      public bool HasFileExtension {
-        get { return result.HasFileExtension; }
-      }
-      public string FileExtension {
-        get { return result.FileExtension; }
-        set { SetFileExtension(value); }
-      }
-      public Builder SetFileExtension(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasFileExtension = true;
-        result.fileExtension_ = value;
-        return this;
-      }
-      public Builder ClearFileExtension() {
-        result.hasFileExtension = false;
-        result.fileExtension_ = ".cs";
-        return this;
-      }
-      
-      public bool HasUmbrellaNamespace {
-        get { return result.HasUmbrellaNamespace; }
-      }
-      public string UmbrellaNamespace {
-        get { return result.UmbrellaNamespace; }
-        set { SetUmbrellaNamespace(value); }
-      }
-      public Builder SetUmbrellaNamespace(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasUmbrellaNamespace = true;
-        result.umbrellaNamespace_ = value;
-        return this;
-      }
-      public Builder ClearUmbrellaNamespace() {
-        result.hasUmbrellaNamespace = false;
-        result.umbrellaNamespace_ = "";
-        return this;
-      }
-      
-      public bool HasOutputDirectory {
-        get { return result.HasOutputDirectory; }
-      }
-      public string OutputDirectory {
-        get { return result.OutputDirectory; }
-        set { SetOutputDirectory(value); }
-      }
-      public Builder SetOutputDirectory(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOutputDirectory = true;
-        result.outputDirectory_ = value;
-        return this;
-      }
-      public Builder ClearOutputDirectory() {
-        result.hasOutputDirectory = false;
-        result.outputDirectory_ = ".";
-        return this;
-      }
-      
-      public bool HasIgnoreGoogleProtobuf {
-        get { return result.HasIgnoreGoogleProtobuf; }
-      }
-      public bool IgnoreGoogleProtobuf {
-        get { return result.IgnoreGoogleProtobuf; }
-        set { SetIgnoreGoogleProtobuf(value); }
-      }
-      public Builder SetIgnoreGoogleProtobuf(bool value) {
-        result.hasIgnoreGoogleProtobuf = true;
-        result.ignoreGoogleProtobuf_ = value;
-        return this;
-      }
-      public Builder ClearIgnoreGoogleProtobuf() {
-        result.hasIgnoreGoogleProtobuf = false;
-        result.ignoreGoogleProtobuf_ = false;
-        return this;
-      }
-      
-      public bool HasServiceGeneratorType {
-       get { return result.HasServiceGeneratorType; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType ServiceGeneratorType {
-        get { return result.ServiceGeneratorType; }
-        set { SetServiceGeneratorType(value); }
-      }
-      public Builder SetServiceGeneratorType(global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType value) {
-        result.hasServiceGeneratorType = true;
-        result.serviceGeneratorType_ = value;
-        return this;
-      }
-      public Builder ClearServiceGeneratorType() {
-        result.hasServiceGeneratorType = false;
-        result.serviceGeneratorType_ = global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType.NONE;
-        return this;
-      }
-    }
-    static CSharpFileOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class CSharpFieldOptions : pb::GeneratedMessage<CSharpFieldOptions, CSharpFieldOptions.Builder> {
-    private static readonly CSharpFieldOptions defaultInstance = new Builder().BuildPartial();
-    public static CSharpFieldOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override CSharpFieldOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override CSharpFieldOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpFieldOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<CSharpFieldOptions, CSharpFieldOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable; }
-    }
-    
-    public const int PropertyNameFieldNumber = 1;
-    private bool hasPropertyName;
-    private string propertyName_ = "";
-    public bool HasPropertyName {
-      get { return hasPropertyName; }
-    }
-    public string PropertyName {
-      get { return propertyName_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasPropertyName) {
-        output.WriteString(1, PropertyName);
-      }
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasPropertyName) {
-          size += pb::CodedOutputStream.ComputeStringSize(1, PropertyName);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static CSharpFieldOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static CSharpFieldOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpFieldOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static CSharpFieldOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpFieldOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static CSharpFieldOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpFieldOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static CSharpFieldOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static CSharpFieldOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static CSharpFieldOptions 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(CSharpFieldOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+            }
+
+
+            public bool HasInterfaceId
+            {
+                get { return result.HasInterfaceId; }
+            }
+
+            public string InterfaceId
+            {
+                get { return result.InterfaceId; }
+                set { SetInterfaceId(value); }
+            }
+
+            public Builder SetInterfaceId(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasInterfaceId = true;
+                result.interfaceId_ = value;
+                return this;
+            }
+
+            public Builder ClearInterfaceId()
+            {
+                result.hasInterfaceId = false;
+                result.interfaceId_ = "";
+                return this;
+            }
+        }
+
+        static CSharpServiceOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, null);
+        }
     }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<CSharpFieldOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      CSharpFieldOptions result = new CSharpFieldOptions();
-      
-      protected override CSharpFieldOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new CSharpFieldOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Descriptor; }
-      }
-      
-      public override CSharpFieldOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.DefaultInstance; }
-      }
-      
-      public override CSharpFieldOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        CSharpFieldOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is CSharpFieldOptions) {
-          return MergeFrom((CSharpFieldOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(CSharpFieldOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.DefaultInstance) return this;
-        if (other.HasPropertyName) {
-          PropertyName = other.PropertyName;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
+
+    public sealed partial class CSharpMethodOptions :
+        pb::GeneratedMessage<CSharpMethodOptions, CSharpMethodOptions.Builder>
+    {
+        private static readonly CSharpMethodOptions defaultInstance = new Builder().BuildPartial();
+
+        public static CSharpMethodOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override CSharpMethodOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override CSharpMethodOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.
+                        internal__static_google_protobuf_CSharpMethodOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<CSharpMethodOptions, CSharpMethodOptions.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.
+                        internal__static_google_protobuf_CSharpMethodOptions__FieldAccessorTable;
+            }
+        }
+
+        public const int DispatchIdFieldNumber = 1;
+        private bool hasDispatchId;
+        private int dispatchId_ = 0;
+
+        public bool HasDispatchId
+        {
+            get { return hasDispatchId; }
+        }
+
+        public int DispatchId
+        {
+            get { return dispatchId_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get { return true; }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasDispatchId)
+            {
+                output.WriteInt32(1, DispatchId);
+            }
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                if (HasDispatchId)
+                {
+                    size += pb::CodedOutputStream.ComputeInt32Size(1, DispatchId);
                 }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static CSharpMethodOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static CSharpMethodOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpMethodOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static CSharpMethodOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpMethodOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static CSharpMethodOptions ParseFrom(global::System.IO.Stream input,
+                                                    pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static CSharpMethodOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static CSharpMethodOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                             pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static CSharpMethodOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static CSharpMethodOptions 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(CSharpMethodOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<CSharpMethodOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private CSharpMethodOptions result = new CSharpMethodOptions();
+
+            protected override CSharpMethodOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new CSharpMethodOptions();
                 return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              PropertyName = input.ReadString();
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasPropertyName {
-        get { return result.HasPropertyName; }
-      }
-      public string PropertyName {
-        get { return result.PropertyName; }
-        set { SetPropertyName(value); }
-      }
-      public Builder SetPropertyName(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasPropertyName = true;
-        result.propertyName_ = value;
-        return this;
-      }
-      public Builder ClearPropertyName() {
-        result.hasPropertyName = false;
-        result.propertyName_ = "";
-        return this;
-      }
-    }
-    static CSharpFieldOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class CSharpServiceOptions : pb::GeneratedMessage<CSharpServiceOptions, CSharpServiceOptions.Builder> {
-    private static readonly CSharpServiceOptions defaultInstance = new Builder().BuildPartial();
-    public static CSharpServiceOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override CSharpServiceOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override CSharpServiceOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpServiceOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<CSharpServiceOptions, CSharpServiceOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpServiceOptions__FieldAccessorTable; }
-    }
-    
-    public const int InterfaceIdFieldNumber = 1;
-    private bool hasInterfaceId;
-    private string interfaceId_ = "";
-    public bool HasInterfaceId {
-      get { return hasInterfaceId; }
-    }
-    public string InterfaceId {
-      get { return interfaceId_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasInterfaceId) {
-        output.WriteString(1, InterfaceId);
-      }
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasInterfaceId) {
-          size += pb::CodedOutputStream.ComputeStringSize(1, InterfaceId);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static CSharpServiceOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static CSharpServiceOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpServiceOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static CSharpServiceOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpServiceOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static CSharpServiceOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpServiceOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static CSharpServiceOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static CSharpServiceOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static CSharpServiceOptions 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(CSharpServiceOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<CSharpServiceOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      CSharpServiceOptions result = new CSharpServiceOptions();
-      
-      protected override CSharpServiceOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new CSharpServiceOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.Descriptor; }
-      }
-      
-      public override CSharpServiceOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.DefaultInstance; }
-      }
-      
-      public override CSharpServiceOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        CSharpServiceOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is CSharpServiceOptions) {
-          return MergeFrom((CSharpServiceOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(CSharpServiceOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.DefaultInstance) return this;
-        if (other.HasInterfaceId) {
-          InterfaceId = other.InterfaceId;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.Descriptor; }
+            }
+
+            public override CSharpMethodOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.DefaultInstance; }
+            }
+
+            public override CSharpMethodOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                CSharpMethodOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is CSharpMethodOptions)
+                {
+                    return MergeFrom((CSharpMethodOptions) other);
                 }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(CSharpMethodOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.DefaultInstance)
+                    return this;
+                if (other.HasDispatchId)
+                {
+                    DispatchId = other.DispatchId;
+                }
+                this.MergeUnknownFields(other.UnknownFields);
                 return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              InterfaceId = input.ReadString();
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasInterfaceId {
-        get { return result.HasInterfaceId; }
-      }
-      public string InterfaceId {
-        get { return result.InterfaceId; }
-        set { SetInterfaceId(value); }
-      }
-      public Builder SetInterfaceId(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasInterfaceId = true;
-        result.interfaceId_ = value;
-        return this;
-      }
-      public Builder ClearInterfaceId() {
-        result.hasInterfaceId = false;
-        result.interfaceId_ = "";
-        return this;
-      }
-    }
-    static CSharpServiceOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class CSharpMethodOptions : pb::GeneratedMessage<CSharpMethodOptions, CSharpMethodOptions.Builder> {
-    private static readonly CSharpMethodOptions defaultInstance = new Builder().BuildPartial();
-    public static CSharpMethodOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override CSharpMethodOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override CSharpMethodOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpMethodOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<CSharpMethodOptions, CSharpMethodOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpMethodOptions__FieldAccessorTable; }
-    }
-    
-    public const int DispatchIdFieldNumber = 1;
-    private bool hasDispatchId;
-    private int dispatchId_ = 0;
-    public bool HasDispatchId {
-      get { return hasDispatchId; }
-    }
-    public int DispatchId {
-      get { return dispatchId_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasDispatchId) {
-        output.WriteInt32(1, DispatchId);
-      }
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasDispatchId) {
-          size += pb::CodedOutputStream.ComputeInt32Size(1, DispatchId);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static CSharpMethodOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static CSharpMethodOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpMethodOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static CSharpMethodOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpMethodOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static CSharpMethodOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static CSharpMethodOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static CSharpMethodOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static CSharpMethodOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static CSharpMethodOptions 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(CSharpMethodOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<CSharpMethodOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      CSharpMethodOptions result = new CSharpMethodOptions();
-      
-      protected override CSharpMethodOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new CSharpMethodOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.Descriptor; }
-      }
-      
-      public override CSharpMethodOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.DefaultInstance; }
-      }
-      
-      public override CSharpMethodOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        CSharpMethodOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is CSharpMethodOptions) {
-          return MergeFrom((CSharpMethodOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(CSharpMethodOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.DefaultInstance) return this;
-        if (other.HasDispatchId) {
-          DispatchId = other.DispatchId;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
+            }
+
+            public override Builder MergeFrom(pb::CodedInputStream input)
+            {
+                return MergeFrom(input, pb::ExtensionRegistry.Empty);
+            }
+
+            public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 8:
+                            {
+                                DispatchId = input.ReadInt32();
+                                break;
+                            }
+                    }
                 }
+            }
+
+
+            public bool HasDispatchId
+            {
+                get { return result.HasDispatchId; }
+            }
+
+            public int DispatchId
+            {
+                get { return result.DispatchId; }
+                set { SetDispatchId(value); }
+            }
+
+            public Builder SetDispatchId(int value)
+            {
+                result.hasDispatchId = true;
+                result.dispatchId_ = value;
                 return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 8: {
-              DispatchId = input.ReadInt32();
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasDispatchId {
-        get { return result.HasDispatchId; }
-      }
-      public int DispatchId {
-        get { return result.DispatchId; }
-        set { SetDispatchId(value); }
-      }
-      public Builder SetDispatchId(int value) {
-        result.hasDispatchId = true;
-        result.dispatchId_ = value;
-        return this;
-      }
-      public Builder ClearDispatchId() {
-        result.hasDispatchId = false;
-        result.dispatchId_ = 0;
-        return this;
-      }
-    }
-    static CSharpMethodOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, null);
+            }
+
+            public Builder ClearDispatchId()
+            {
+                result.hasDispatchId = false;
+                result.dispatchId_ = 0;
+                return this;
+            }
+        }
+
+        static CSharpMethodOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, null);
+        }
     }
-  }
-  
-  #endregion
-  
-}
+
+    #endregion
+}

+ 10670 - 6956
src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs

@@ -4,7019 +4,10733 @@ 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.DescriptorProtos {
-  
-  public static partial class DescriptorProtoFile {
-  
-    #region Extension registration
-    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
-    }
-    #endregion
-    #region Static variables
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_FileDescriptorSet__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.Builder> internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_FileDescriptorProto__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder> internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_DescriptorProto__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder> internal__static_google_protobuf_DescriptorProto__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Builder> internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_FieldDescriptorProto__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder> internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumDescriptorProto__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder> internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder> internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_ServiceDescriptorProto__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder> internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_MethodDescriptorProto__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder> internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_FileOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FileOptions, global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Builder> internal__static_google_protobuf_FileOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_MessageOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions, global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Builder> internal__static_google_protobuf_MessageOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_FieldOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Builder> internal__static_google_protobuf_FieldOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions, global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Builder> internal__static_google_protobuf_EnumOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumValueOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions, global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Builder> internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_ServiceOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions, global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Builder> internal__static_google_protobuf_ServiceOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_MethodOptions__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions, global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Builder> internal__static_google_protobuf_MethodOptions__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_UninterpretedOption__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder> internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Builder> internal__static_google_protobuf_UninterpretedOption_NamePart__FieldAccessorTable;
-    #endregion
-    #region Descriptor
-    public static pbd::FileDescriptor Descriptor {
-      get { return descriptor; }
-    }
-    private static pbd::FileDescriptor descriptor;
-    
-    static DescriptorProtoFile() {
-      byte[] descriptorData = global::System.Convert.FromBase64String(
-          "CiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bxIPZ29vZ2xlLnBy" + 
-          "b3RvYnVmIkcKEUZpbGVEZXNjcmlwdG9yU2V0EjIKBGZpbGUYASADKAsyJC5n" + 
-          "b29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byLcAgoTRmlsZURl" + 
-          "c2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg8KB3BhY2thZ2UYAiABKAkS" + 
-          "EgoKZGVwZW5kZW5jeRgDIAMoCRI2CgxtZXNzYWdlX3R5cGUYBCADKAsyIC5n" + 
-          "b29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvEjcKCWVudW1fdHlwZRgF" + 
-          "IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvEjgK" + 
-          "B3NlcnZpY2UYBiADKAsyJy5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2Ny" + 
-          "aXB0b3JQcm90bxI4CglleHRlbnNpb24YByADKAsyJS5nb29nbGUucHJvdG9i" + 
-          "dWYuRmllbGREZXNjcmlwdG9yUHJvdG8SLQoHb3B0aW9ucxgIIAEoCzIcLmdv" + 
-          "b2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyKpAwoPRGVzY3JpcHRvclByb3Rv" + 
-          "EgwKBG5hbWUYASABKAkSNAoFZmllbGQYAiADKAsyJS5nb29nbGUucHJvdG9i" + 
-          "dWYuRmllbGREZXNjcmlwdG9yUHJvdG8SOAoJZXh0ZW5zaW9uGAYgAygLMiUu" + 
-          "Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvEjUKC25lc3Rl" + 
-          "ZF90eXBlGAMgAygLMiAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90" + 
-          "bxI3CgllbnVtX3R5cGUYBCADKAsyJC5nb29nbGUucHJvdG9idWYuRW51bURl" + 
-          "c2NyaXB0b3JQcm90bxJICg9leHRlbnNpb25fcmFuZ2UYBSADKAsyLy5nb29n" + 
-          "bGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlEjAK" + 
-          "B29wdGlvbnMYByABKAsyHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlv" + 
-          "bnMaLAoORXh0ZW5zaW9uUmFuZ2USDQoFc3RhcnQYASABKAUSCwoDZW5kGAIg" + 
-          "ASgFIpQFChRGaWVsZERlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg4K" + 
-          "Bm51bWJlchgDIAEoBRI6CgVsYWJlbBgEIAEoDjIrLmdvb2dsZS5wcm90b2J1" + 
-          "Zi5GaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbBI4CgR0eXBlGAUgASgOMiou" + 
-          "Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSEQoJ" + 
-          "dHlwZV9uYW1lGAYgASgJEhAKCGV4dGVuZGVlGAIgASgJEhUKDWRlZmF1bHRf" + 
-          "dmFsdWUYByABKAkSLgoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1" + 
-          "Zi5GaWVsZE9wdGlvbnMitgIKBFR5cGUSDwoLVFlQRV9ET1VCTEUQARIOCgpU" + 
-          "WVBFX0ZMT0FUEAISDgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0EAQS" + 
-          "DgoKVFlQRV9JTlQzMhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVfRklY" + 
-          "RUQzMhAHEg0KCVRZUEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoKVFlQ" + 
-          "RV9HUk9VUBAKEhAKDFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQDBIP" + 
-          "CgtUWVBFX1VJTlQzMhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJWEVE" + 
-          "MzIQDxIRCg1UWVBFX1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIPCgtU" + 
-          "WVBFX1NJTlQ2NBASIkMKBUxhYmVsEhIKDkxBQkVMX09QVElPTkFMEAESEgoO" + 
-          "TEFCRUxfUkVRVUlSRUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIowBChNFbnVt" + 
-          "RGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSOAoFdmFsdWUYAiADKAsy" + 
-          "KS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvEi0K" + 
-          "B29wdGlvbnMYAyABKAsyHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMi" + 
-          "bAoYRW51bVZhbHVlRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDgoG" + 
-          "bnVtYmVyGAIgASgFEjIKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9i" + 
-          "dWYuRW51bVZhbHVlT3B0aW9ucyKQAQoWU2VydmljZURlc2NyaXB0b3JQcm90" + 
-          "bxIMCgRuYW1lGAEgASgJEjYKBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90" + 
-          "b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8SMAoHb3B0aW9ucxgDIAEoCzIf" + 
-          "Lmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyJ/ChVNZXRob2REZXNj" + 
-          "cmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJ" + 
-          "EhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29n" + 
-          "bGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyKkAwoLRmlsZU9wdGlvbnMSFAoM" + 
-          "amF2YV9wYWNrYWdlGAEgASgJEhwKFGphdmFfb3V0ZXJfY2xhc3NuYW1lGAgg" + 
-          "ASgJEiIKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlEkYKDG9w" + 
-          "dGltaXplX2ZvchgJIAEoDjIpLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9u" + 
-          "cy5PcHRpbWl6ZU1vZGU6BVNQRUVEEiEKE2NjX2dlbmVyaWNfc2VydmljZXMY" + 
-          "ECABKAg6BHRydWUSIwoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgR0" + 
-          "cnVlEiEKE3B5X2dlbmVyaWNfc2VydmljZXMYEiABKAg6BHRydWUSQwoUdW5p" + 
-          "bnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVu" + 
-          "aW50ZXJwcmV0ZWRPcHRpb24iOgoMT3B0aW1pemVNb2RlEgkKBVNQRUVEEAES" + 
-          "DQoJQ09ERV9TSVpFEAISEAoMTElURV9SVU5USU1FEAMqCQjoBxCAgICAAiK4" + 
-          "AQoOTWVzc2FnZU9wdGlvbnMSJgoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQY" + 
-          "ASABKAg6BWZhbHNlEi4KH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNz" + 
-          "b3IYAiABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMo" + 
-          "CzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQ" + 
-          "gICAgAIilAIKDEZpZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2ds" + 
-          "ZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNr" + 
-          "ZWQYAiABKAgSGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USHAoUZXhwZXJp" + 
-          "bWVudGFsX21hcF9rZXkYCSABKAkSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y" + 
-          "5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24i" + 
-          "LwoFQ1R5cGUSCgoGU1RSSU5HEAASCAoEQ09SRBABEhAKDFNUUklOR19QSUVD" + 
-          "RRACKgkI6AcQgICAgAIiXQoLRW51bU9wdGlvbnMSQwoUdW5pbnRlcnByZXRl" + 
-          "ZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0" + 
-          "ZWRPcHRpb24qCQjoBxCAgICAAiJiChBFbnVtVmFsdWVPcHRpb25zEkMKFHVu" + 
-          "aW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5V" + 
-          "bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiYAoOU2VydmljZU9wdGlv" + 
-          "bnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnBy" + 
-          "b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiJfCg1NZXRo" + 
-          "b2RPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv" + 
-          "b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi" + 
-          "hQIKE1VuaW50ZXJwcmV0ZWRPcHRpb24SOwoEbmFtZRgCIAMoCzItLmdvb2ds" + 
-          "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0EhgKEGlk" + 
-          "ZW50aWZpZXJfdmFsdWUYAyABKAkSGgoScG9zaXRpdmVfaW50X3ZhbHVlGAQg" + 
-          "ASgEEhoKEm5lZ2F0aXZlX2ludF92YWx1ZRgFIAEoAxIUCgxkb3VibGVfdmFs" + 
-          "dWUYBiABKAESFAoMc3RyaW5nX3ZhbHVlGAcgASgMGjMKCE5hbWVQYXJ0EhEK" + 
-          "CW5hbWVfcGFydBgBIAIoCRIUCgxpc19leHRlbnNpb24YAiACKAhCKQoTY29t" + 
-          "Lmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rvc0gB");
-      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
-        descriptor = root;
-        internal__static_google_protobuf_FileDescriptorSet__Descriptor = Descriptor.MessageTypes[0];
-        internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.Builder>(internal__static_google_protobuf_FileDescriptorSet__Descriptor,
-                new string[] { "File", });
-        internal__static_google_protobuf_FileDescriptorProto__Descriptor = Descriptor.MessageTypes[1];
-        internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder>(internal__static_google_protobuf_FileDescriptorProto__Descriptor,
-                new string[] { "Name", "Package", "Dependency", "MessageType", "EnumType", "Service", "Extension", "Options", });
-        internal__static_google_protobuf_DescriptorProto__Descriptor = Descriptor.MessageTypes[2];
-        internal__static_google_protobuf_DescriptorProto__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder>(internal__static_google_protobuf_DescriptorProto__Descriptor,
-                new string[] { "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "Options", });
-        internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor = internal__static_google_protobuf_DescriptorProto__Descriptor.NestedTypes[0];
-        internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Builder>(internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor,
-                new string[] { "Start", "End", });
-        internal__static_google_protobuf_FieldDescriptorProto__Descriptor = Descriptor.MessageTypes[3];
-        internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder>(internal__static_google_protobuf_FieldDescriptorProto__Descriptor,
-                new string[] { "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "Options", });
-        internal__static_google_protobuf_EnumDescriptorProto__Descriptor = Descriptor.MessageTypes[4];
-        internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder>(internal__static_google_protobuf_EnumDescriptorProto__Descriptor,
-                new string[] { "Name", "Value", "Options", });
-        internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor = Descriptor.MessageTypes[5];
-        internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder>(internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor,
-                new string[] { "Name", "Number", "Options", });
-        internal__static_google_protobuf_ServiceDescriptorProto__Descriptor = Descriptor.MessageTypes[6];
-        internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder>(internal__static_google_protobuf_ServiceDescriptorProto__Descriptor,
-                new string[] { "Name", "Method", "Options", });
-        internal__static_google_protobuf_MethodDescriptorProto__Descriptor = Descriptor.MessageTypes[7];
-        internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto, global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder>(internal__static_google_protobuf_MethodDescriptorProto__Descriptor,
-                new string[] { "Name", "InputType", "OutputType", "Options", });
-        internal__static_google_protobuf_FileOptions__Descriptor = Descriptor.MessageTypes[8];
-        internal__static_google_protobuf_FileOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FileOptions, global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Builder>(internal__static_google_protobuf_FileOptions__Descriptor,
-                new string[] { "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "OptimizeFor", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "UninterpretedOption", });
-        internal__static_google_protobuf_MessageOptions__Descriptor = Descriptor.MessageTypes[9];
-        internal__static_google_protobuf_MessageOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions, global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Builder>(internal__static_google_protobuf_MessageOptions__Descriptor,
-                new string[] { "MessageSetWireFormat", "NoStandardDescriptorAccessor", "UninterpretedOption", });
-        internal__static_google_protobuf_FieldOptions__Descriptor = Descriptor.MessageTypes[10];
-        internal__static_google_protobuf_FieldOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Builder>(internal__static_google_protobuf_FieldOptions__Descriptor,
-                new string[] { "Ctype", "Packed", "Deprecated", "ExperimentalMapKey", "UninterpretedOption", });
-        internal__static_google_protobuf_EnumOptions__Descriptor = Descriptor.MessageTypes[11];
-        internal__static_google_protobuf_EnumOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions, global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Builder>(internal__static_google_protobuf_EnumOptions__Descriptor,
-                new string[] { "UninterpretedOption", });
-        internal__static_google_protobuf_EnumValueOptions__Descriptor = Descriptor.MessageTypes[12];
-        internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions, global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Builder>(internal__static_google_protobuf_EnumValueOptions__Descriptor,
-                new string[] { "UninterpretedOption", });
-        internal__static_google_protobuf_ServiceOptions__Descriptor = Descriptor.MessageTypes[13];
-        internal__static_google_protobuf_ServiceOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions, global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Builder>(internal__static_google_protobuf_ServiceOptions__Descriptor,
-                new string[] { "UninterpretedOption", });
-        internal__static_google_protobuf_MethodOptions__Descriptor = Descriptor.MessageTypes[14];
-        internal__static_google_protobuf_MethodOptions__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions, global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Builder>(internal__static_google_protobuf_MethodOptions__Descriptor,
-                new string[] { "UninterpretedOption", });
-        internal__static_google_protobuf_UninterpretedOption__Descriptor = Descriptor.MessageTypes[15];
-        internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder>(internal__static_google_protobuf_UninterpretedOption__Descriptor,
-                new string[] { "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", });
-        internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor = internal__static_google_protobuf_UninterpretedOption__Descriptor.NestedTypes[0];
-        internal__static_google_protobuf_UninterpretedOption_NamePart__FieldAccessorTable = 
-            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Builder>(internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor,
-                new string[] { "NamePart_", "IsExtension", });
-        return null;
-      };
-      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
-          new pbd::FileDescriptor[] {
-          }, assigner);
-    }
-    #endregion
-    
-  }
-  #region Messages
-  public sealed partial class FileDescriptorSet : pb::GeneratedMessage<FileDescriptorSet, FileDescriptorSet.Builder> {
-    private static readonly FileDescriptorSet defaultInstance = new Builder().BuildPartial();
-    public static FileDescriptorSet DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override FileDescriptorSet DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override FileDescriptorSet ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileDescriptorSet__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<FileDescriptorSet, FileDescriptorSet.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable; }
-    }
-    
-    public const int FileFieldNumber = 1;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> file_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> FileList {
-      get { return file_; }
-    }
-    public int FileCount {
-      get { return file_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto GetFile(int index) {
-      return file_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto element in FileList) {
-          if (!element.IsInitialized) return false;
-        }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto element in FileList) {
-        output.WriteMessage(1, element);
-      }
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto element in FileList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(1, element);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static FileDescriptorSet ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FileDescriptorSet ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FileDescriptorSet ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FileDescriptorSet ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FileDescriptorSet ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FileDescriptorSet ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static FileDescriptorSet ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static FileDescriptorSet ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static FileDescriptorSet ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FileDescriptorSet 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(FileDescriptorSet prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<FileDescriptorSet, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      FileDescriptorSet result = new FileDescriptorSet();
-      
-      protected override FileDescriptorSet MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new FileDescriptorSet();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.Descriptor; }
-      }
-      
-      public override FileDescriptorSet DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.DefaultInstance; }
-      }
-      
-      public override FileDescriptorSet BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.file_.MakeReadOnly();
-        FileDescriptorSet returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is FileDescriptorSet) {
-          return MergeFrom((FileDescriptorSet) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(FileDescriptorSet other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.DefaultInstance) return this;
-        if (other.file_.Count != 0) {
-          base.AddRange(other.file_, result.file_);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddFile(subBuilder.BuildPartial());
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> FileList {
-        get { return result.file_; }
-      }
-      public int FileCount {
-        get { return result.FileCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto GetFile(int index) {
-        return result.GetFile(index);
-      }
-      public Builder SetFile(int index, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.file_[index] = value;
-        return this;
-      }
-      public Builder SetFile(int index, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.file_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddFile(global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.file_.Add(value);
-        return this;
-      }
-      public Builder AddFile(global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.file_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeFile(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> values) {
-        base.AddRange(values, result.file_);
-        return this;
-      }
-      public Builder ClearFile() {
-        result.file_.Clear();
-        return this;
-      }
-    }
-    static FileDescriptorSet() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class FileDescriptorProto : pb::GeneratedMessage<FileDescriptorProto, FileDescriptorProto.Builder> {
-    private static readonly FileDescriptorProto defaultInstance = new Builder().BuildPartial();
-    public static FileDescriptorProto DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override FileDescriptorProto DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override FileDescriptorProto ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileDescriptorProto__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<FileDescriptorProto, FileDescriptorProto.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable; }
-    }
-    
-    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 PackageFieldNumber = 2;
-    private bool hasPackage;
-    private string package_ = "";
-    public bool HasPackage {
-      get { return hasPackage; }
-    }
-    public string Package {
-      get { return package_; }
-    }
-    
-    public const int DependencyFieldNumber = 3;
-    private pbc::PopsicleList<string> dependency_ = new pbc::PopsicleList<string>();
-    public scg::IList<string> DependencyList {
-      get { return pbc::Lists.AsReadOnly(dependency_); }
-    }
-    public int DependencyCount {
-      get { return dependency_.Count; }
-    }
-    public string GetDependency(int index) {
-      return dependency_[index];
-    }
-    
-    public const int MessageTypeFieldNumber = 4;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> messageType_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> MessageTypeList {
-      get { return messageType_; }
-    }
-    public int MessageTypeCount {
-      get { return messageType_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto GetMessageType(int index) {
-      return messageType_[index];
-    }
-    
-    public const int EnumTypeFieldNumber = 5;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> enumType_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> EnumTypeList {
-      get { return enumType_; }
-    }
-    public int EnumTypeCount {
-      get { return enumType_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto GetEnumType(int index) {
-      return enumType_[index];
-    }
-    
-    public const int ServiceFieldNumber = 6;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto> service_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto> ServiceList {
-      get { return service_; }
-    }
-    public int ServiceCount {
-      get { return service_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto GetService(int index) {
-      return service_[index];
-    }
-    
-    public const int ExtensionFieldNumber = 7;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> extension_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> ExtensionList {
-      get { return extension_; }
-    }
-    public int ExtensionCount {
-      get { return extension_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetExtension(int index) {
-      return extension_[index];
-    }
-    
-    public const int OptionsFieldNumber = 8;
-    private bool hasOptions;
-    private global::Google.ProtocolBuffers.DescriptorProtos.FileOptions options_ = global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance;
-    public bool HasOptions {
-      get { return hasOptions; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FileOptions Options {
-      get { return options_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in MessageTypeList) {
-          if (!element.IsInitialized) return false;
+
+namespace Google.ProtocolBuffers.DescriptorProtos
+{
+    public static partial class DescriptorProtoFile
+    {
+        #region Extension registration
+
+        public static void RegisterAllExtensions(pb::ExtensionRegistry registry)
+        {
         }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList) {
-          if (!element.IsInitialized) return false;
+
+        #endregion
+
+        #region Static variables
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_FileDescriptorSet__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet,
+                    global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.Builder>
+            internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_FileDescriptorProto__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto,
+                    global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder>
+            internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_DescriptorProto__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto,
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder>
+            internal__static_google_protobuf_DescriptorProto__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor
+            internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange,
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Builder>
+            internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_FieldDescriptorProto__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto,
+                    global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder>
+            internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumDescriptorProto__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto,
+                    global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder>
+            internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto,
+                    global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder>
+            internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_ServiceDescriptorProto__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto,
+                    global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder>
+            internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_MethodDescriptorProto__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto,
+                    global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder>
+            internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_FileOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.FileOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Builder>
+            internal__static_google_protobuf_FileOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_MessageOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Builder>
+            internal__static_google_protobuf_MessageOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_FieldOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Builder>
+            internal__static_google_protobuf_FieldOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Builder>
+            internal__static_google_protobuf_EnumOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumValueOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Builder>
+            internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_ServiceOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Builder>
+            internal__static_google_protobuf_ServiceOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_MethodOptions__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions,
+                    global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Builder>
+            internal__static_google_protobuf_MethodOptions__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_UninterpretedOption__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption,
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder>
+            internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable;
+
+        internal static pbd::MessageDescriptor internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor;
+
+        internal static
+            pb::FieldAccess.FieldAccessorTable
+                <global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart,
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Builder>
+            internal__static_google_protobuf_UninterpretedOption_NamePart__FieldAccessorTable;
+
+        #endregion
+
+        #region Descriptor
+
+        public static pbd::FileDescriptor Descriptor
+        {
+            get { return descriptor; }
         }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto element in ServiceList) {
-          if (!element.IsInitialized) return false;
+
+        private static pbd::FileDescriptor descriptor;
+
+        static DescriptorProtoFile()
+        {
+            byte[] descriptorData = global::System.Convert.FromBase64String(
+                "CiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bxIPZ29vZ2xlLnBy" +
+                "b3RvYnVmIkcKEUZpbGVEZXNjcmlwdG9yU2V0EjIKBGZpbGUYASADKAsyJC5n" +
+                "b29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byLcAgoTRmlsZURl" +
+                "c2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg8KB3BhY2thZ2UYAiABKAkS" +
+                "EgoKZGVwZW5kZW5jeRgDIAMoCRI2CgxtZXNzYWdlX3R5cGUYBCADKAsyIC5n" +
+                "b29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvEjcKCWVudW1fdHlwZRgF" +
+                "IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvEjgK" +
+                "B3NlcnZpY2UYBiADKAsyJy5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2Ny" +
+                "aXB0b3JQcm90bxI4CglleHRlbnNpb24YByADKAsyJS5nb29nbGUucHJvdG9i" +
+                "dWYuRmllbGREZXNjcmlwdG9yUHJvdG8SLQoHb3B0aW9ucxgIIAEoCzIcLmdv" +
+                "b2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyKpAwoPRGVzY3JpcHRvclByb3Rv" +
+                "EgwKBG5hbWUYASABKAkSNAoFZmllbGQYAiADKAsyJS5nb29nbGUucHJvdG9i" +
+                "dWYuRmllbGREZXNjcmlwdG9yUHJvdG8SOAoJZXh0ZW5zaW9uGAYgAygLMiUu" +
+                "Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvEjUKC25lc3Rl" +
+                "ZF90eXBlGAMgAygLMiAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90" +
+                "bxI3CgllbnVtX3R5cGUYBCADKAsyJC5nb29nbGUucHJvdG9idWYuRW51bURl" +
+                "c2NyaXB0b3JQcm90bxJICg9leHRlbnNpb25fcmFuZ2UYBSADKAsyLy5nb29n" +
+                "bGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlEjAK" +
+                "B29wdGlvbnMYByABKAsyHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlv" +
+                "bnMaLAoORXh0ZW5zaW9uUmFuZ2USDQoFc3RhcnQYASABKAUSCwoDZW5kGAIg" +
+                "ASgFIpQFChRGaWVsZERlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg4K" +
+                "Bm51bWJlchgDIAEoBRI6CgVsYWJlbBgEIAEoDjIrLmdvb2dsZS5wcm90b2J1" +
+                "Zi5GaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbBI4CgR0eXBlGAUgASgOMiou" +
+                "Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSEQoJ" +
+                "dHlwZV9uYW1lGAYgASgJEhAKCGV4dGVuZGVlGAIgASgJEhUKDWRlZmF1bHRf" +
+                "dmFsdWUYByABKAkSLgoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1" +
+                "Zi5GaWVsZE9wdGlvbnMitgIKBFR5cGUSDwoLVFlQRV9ET1VCTEUQARIOCgpU" +
+                "WVBFX0ZMT0FUEAISDgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0EAQS" +
+                "DgoKVFlQRV9JTlQzMhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVfRklY" +
+                "RUQzMhAHEg0KCVRZUEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoKVFlQ" +
+                "RV9HUk9VUBAKEhAKDFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQDBIP" +
+                "CgtUWVBFX1VJTlQzMhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJWEVE" +
+                "MzIQDxIRCg1UWVBFX1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIPCgtU" +
+                "WVBFX1NJTlQ2NBASIkMKBUxhYmVsEhIKDkxBQkVMX09QVElPTkFMEAESEgoO" +
+                "TEFCRUxfUkVRVUlSRUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIowBChNFbnVt" +
+                "RGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSOAoFdmFsdWUYAiADKAsy" +
+                "KS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvEi0K" +
+                "B29wdGlvbnMYAyABKAsyHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMi" +
+                "bAoYRW51bVZhbHVlRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDgoG" +
+                "bnVtYmVyGAIgASgFEjIKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9i" +
+                "dWYuRW51bVZhbHVlT3B0aW9ucyKQAQoWU2VydmljZURlc2NyaXB0b3JQcm90" +
+                "bxIMCgRuYW1lGAEgASgJEjYKBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90" +
+                "b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8SMAoHb3B0aW9ucxgDIAEoCzIf" +
+                "Lmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyJ/ChVNZXRob2REZXNj" +
+                "cmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJ" +
+                "EhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29n" +
+                "bGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyKkAwoLRmlsZU9wdGlvbnMSFAoM" +
+                "amF2YV9wYWNrYWdlGAEgASgJEhwKFGphdmFfb3V0ZXJfY2xhc3NuYW1lGAgg" +
+                "ASgJEiIKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlEkYKDG9w" +
+                "dGltaXplX2ZvchgJIAEoDjIpLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9u" +
+                "cy5PcHRpbWl6ZU1vZGU6BVNQRUVEEiEKE2NjX2dlbmVyaWNfc2VydmljZXMY" +
+                "ECABKAg6BHRydWUSIwoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgR0" +
+                "cnVlEiEKE3B5X2dlbmVyaWNfc2VydmljZXMYEiABKAg6BHRydWUSQwoUdW5p" +
+                "bnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVu" +
+                "aW50ZXJwcmV0ZWRPcHRpb24iOgoMT3B0aW1pemVNb2RlEgkKBVNQRUVEEAES" +
+                "DQoJQ09ERV9TSVpFEAISEAoMTElURV9SVU5USU1FEAMqCQjoBxCAgICAAiK4" +
+                "AQoOTWVzc2FnZU9wdGlvbnMSJgoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQY" +
+                "ASABKAg6BWZhbHNlEi4KH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNz" +
+                "b3IYAiABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMo" +
+                "CzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQ" +
+                "gICAgAIilAIKDEZpZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2ds" +
+                "ZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNr" +
+                "ZWQYAiABKAgSGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USHAoUZXhwZXJp" +
+                "bWVudGFsX21hcF9rZXkYCSABKAkSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y" +
+                "5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24i" +
+                "LwoFQ1R5cGUSCgoGU1RSSU5HEAASCAoEQ09SRBABEhAKDFNUUklOR19QSUVD" +
+                "RRACKgkI6AcQgICAgAIiXQoLRW51bU9wdGlvbnMSQwoUdW5pbnRlcnByZXRl" +
+                "ZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0" +
+                "ZWRPcHRpb24qCQjoBxCAgICAAiJiChBFbnVtVmFsdWVPcHRpb25zEkMKFHVu" +
+                "aW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5V" +
+                "bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiYAoOU2VydmljZU9wdGlv" +
+                "bnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnBy" +
+                "b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiJfCg1NZXRo" +
+                "b2RPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv" +
+                "b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi" +
+                "hQIKE1VuaW50ZXJwcmV0ZWRPcHRpb24SOwoEbmFtZRgCIAMoCzItLmdvb2ds" +
+                "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0EhgKEGlk" +
+                "ZW50aWZpZXJfdmFsdWUYAyABKAkSGgoScG9zaXRpdmVfaW50X3ZhbHVlGAQg" +
+                "ASgEEhoKEm5lZ2F0aXZlX2ludF92YWx1ZRgFIAEoAxIUCgxkb3VibGVfdmFs" +
+                "dWUYBiABKAESFAoMc3RyaW5nX3ZhbHVlGAcgASgMGjMKCE5hbWVQYXJ0EhEK" +
+                "CW5hbWVfcGFydBgBIAIoCRIUCgxpc19leHRlbnNpb24YAiACKAhCKQoTY29t" +
+                "Lmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rvc0gB");
+            pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root)
+                                                                          {
+                                                                              descriptor = root;
+                                                                              internal__static_google_protobuf_FileDescriptorSet__Descriptor
+                                                                                  = Descriptor.MessageTypes[0];
+                                                                              internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FileDescriptorSet,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FileDescriptorSet.Builder>
+                                                                                      (internal__static_google_protobuf_FileDescriptorSet__Descriptor,
+                                                                                       new string[] {"File",});
+                                                                              internal__static_google_protobuf_FileDescriptorProto__Descriptor
+                                                                                  = Descriptor.MessageTypes[1];
+                                                                              internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FileDescriptorProto,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FileDescriptorProto.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_FileDescriptorProto__Descriptor,
+                                                                                      new string[]
+                                                                                          {
+                                                                                              "Name", "Package",
+                                                                                              "Dependency", "MessageType",
+                                                                                              "EnumType", "Service",
+                                                                                              "Extension", "Options",
+                                                                                          });
+                                                                              internal__static_google_protobuf_DescriptorProto__Descriptor
+                                                                                  = Descriptor.MessageTypes[2];
+                                                                              internal__static_google_protobuf_DescriptorProto__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              DescriptorProto,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              DescriptorProto.Builder>(
+                                                                                      internal__static_google_protobuf_DescriptorProto__Descriptor,
+                                                                                      new string[]
+                                                                                          {
+                                                                                              "Name", "Field", "Extension",
+                                                                                              "NestedType", "EnumType",
+                                                                                              "ExtensionRange", "Options",
+                                                                                          });
+                                                                              internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor
+                                                                                  =
+                                                                                  internal__static_google_protobuf_DescriptorProto__Descriptor
+                                                                                      .NestedTypes[0];
+                                                                              internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              DescriptorProto.Types.
+                                                                                              ExtensionRange,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              DescriptorProto.Types.
+                                                                                              ExtensionRange.Builder>(
+                                                                                      internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor,
+                                                                                      new string[] {"Start", "End",});
+                                                                              internal__static_google_protobuf_FieldDescriptorProto__Descriptor
+                                                                                  = Descriptor.MessageTypes[3];
+                                                                              internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FieldDescriptorProto,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FieldDescriptorProto.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_FieldDescriptorProto__Descriptor,
+                                                                                      new string[]
+                                                                                          {
+                                                                                              "Name", "Number", "Label",
+                                                                                              "Type", "TypeName",
+                                                                                              "Extendee", "DefaultValue",
+                                                                                              "Options",
+                                                                                          });
+                                                                              internal__static_google_protobuf_EnumDescriptorProto__Descriptor
+                                                                                  = Descriptor.MessageTypes[4];
+                                                                              internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              EnumDescriptorProto,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              EnumDescriptorProto.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_EnumDescriptorProto__Descriptor,
+                                                                                      new string[]
+                                                                                          {"Name", "Value", "Options",});
+                                                                              internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor
+                                                                                  = Descriptor.MessageTypes[5];
+                                                                              internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              EnumValueDescriptorProto,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              EnumValueDescriptorProto.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor,
+                                                                                      new string[]
+                                                                                          {"Name", "Number", "Options",});
+                                                                              internal__static_google_protobuf_ServiceDescriptorProto__Descriptor
+                                                                                  = Descriptor.MessageTypes[6];
+                                                                              internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              ServiceDescriptorProto,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              ServiceDescriptorProto.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_ServiceDescriptorProto__Descriptor,
+                                                                                      new string[]
+                                                                                          {"Name", "Method", "Options",});
+                                                                              internal__static_google_protobuf_MethodDescriptorProto__Descriptor
+                                                                                  = Descriptor.MessageTypes[7];
+                                                                              internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              MethodDescriptorProto,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              MethodDescriptorProto.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_MethodDescriptorProto__Descriptor,
+                                                                                      new string[]
+                                                                                          {
+                                                                                              "Name", "InputType",
+                                                                                              "OutputType", "Options",
+                                                                                          });
+                                                                              internal__static_google_protobuf_FileOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[8];
+                                                                              internal__static_google_protobuf_FileOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FileOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FileOptions.Builder>(
+                                                                                      internal__static_google_protobuf_FileOptions__Descriptor,
+                                                                                      new string[]
+                                                                                          {
+                                                                                              "JavaPackage",
+                                                                                              "JavaOuterClassname",
+                                                                                              "JavaMultipleFiles",
+                                                                                              "OptimizeFor",
+                                                                                              "CcGenericServices",
+                                                                                              "JavaGenericServices",
+                                                                                              "PyGenericServices",
+                                                                                              "UninterpretedOption",
+                                                                                          });
+                                                                              internal__static_google_protobuf_MessageOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[9];
+                                                                              internal__static_google_protobuf_MessageOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              MessageOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              MessageOptions.Builder>(
+                                                                                      internal__static_google_protobuf_MessageOptions__Descriptor,
+                                                                                      new string[]
+                                                                                          {
+                                                                                              "MessageSetWireFormat",
+                                                                                              "NoStandardDescriptorAccessor"
+                                                                                              , "UninterpretedOption",
+                                                                                          });
+                                                                              internal__static_google_protobuf_FieldOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[10];
+                                                                              internal__static_google_protobuf_FieldOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FieldOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              FieldOptions.Builder>(
+                                                                                      internal__static_google_protobuf_FieldOptions__Descriptor,
+                                                                                      new string[]
+                                                                                          {
+                                                                                              "Ctype", "Packed",
+                                                                                              "Deprecated",
+                                                                                              "ExperimentalMapKey",
+                                                                                              "UninterpretedOption",
+                                                                                          });
+                                                                              internal__static_google_protobuf_EnumOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[11];
+                                                                              internal__static_google_protobuf_EnumOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              EnumOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              EnumOptions.Builder>(
+                                                                                      internal__static_google_protobuf_EnumOptions__Descriptor,
+                                                                                      new string[]
+                                                                                          {"UninterpretedOption",});
+                                                                              internal__static_google_protobuf_EnumValueOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[12];
+                                                                              internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              EnumValueOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              EnumValueOptions.Builder>(
+                                                                                      internal__static_google_protobuf_EnumValueOptions__Descriptor,
+                                                                                      new string[]
+                                                                                          {"UninterpretedOption",});
+                                                                              internal__static_google_protobuf_ServiceOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[13];
+                                                                              internal__static_google_protobuf_ServiceOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              ServiceOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              ServiceOptions.Builder>(
+                                                                                      internal__static_google_protobuf_ServiceOptions__Descriptor,
+                                                                                      new string[]
+                                                                                          {"UninterpretedOption",});
+                                                                              internal__static_google_protobuf_MethodOptions__Descriptor
+                                                                                  = Descriptor.MessageTypes[14];
+                                                                              internal__static_google_protobuf_MethodOptions__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              MethodOptions,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              MethodOptions.Builder>(
+                                                                                      internal__static_google_protobuf_MethodOptions__Descriptor,
+                                                                                      new string[]
+                                                                                          {"UninterpretedOption",});
+                                                                              internal__static_google_protobuf_UninterpretedOption__Descriptor
+                                                                                  = Descriptor.MessageTypes[15];
+                                                                              internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              UninterpretedOption,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              UninterpretedOption.
+                                                                                              Builder>(
+                                                                                      internal__static_google_protobuf_UninterpretedOption__Descriptor,
+                                                                                      new string[]
+                                                                                          {
+                                                                                              "Name", "IdentifierValue",
+                                                                                              "PositiveIntValue",
+                                                                                              "NegativeIntValue",
+                                                                                              "DoubleValue", "StringValue",
+                                                                                          });
+                                                                              internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor
+                                                                                  =
+                                                                                  internal__static_google_protobuf_UninterpretedOption__Descriptor
+                                                                                      .NestedTypes[0];
+                                                                              internal__static_google_protobuf_UninterpretedOption_NamePart__FieldAccessorTable
+                                                                                  =
+                                                                                  new pb::FieldAccess.FieldAccessorTable
+                                                                                      <
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              UninterpretedOption.Types.
+                                                                                              NamePart,
+                                                                                          global::Google.ProtocolBuffers
+                                                                                              .DescriptorProtos.
+                                                                                              UninterpretedOption.Types.
+                                                                                              NamePart.Builder>(
+                                                                                      internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor,
+                                                                                      new string[]
+                                                                                          {"NamePart_", "IsExtension",});
+                                                                              return null;
+                                                                          };
+            pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+                                                               new pbd::FileDescriptor[]
+                                                                   {
+                                                                   }, assigner);
         }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList) {
-          if (!element.IsInitialized) return false;
+
+        #endregion
+    }
+
+    #region Messages
+
+    public sealed partial class FileDescriptorSet : pb::GeneratedMessage<FileDescriptorSet, FileDescriptorSet.Builder>
+    {
+        private static readonly FileDescriptorSet defaultInstance = new Builder().BuildPartial();
+
+        public static FileDescriptorSet DefaultInstance
+        {
+            get { return defaultInstance; }
         }
-        if (HasOptions) {
-          if (!Options.IsInitialized) return false;
+
+        public override FileDescriptorSet DefaultInstanceForType
+        {
+            get { return defaultInstance; }
         }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasName) {
-        output.WriteString(1, Name);
-      }
-      if (HasPackage) {
-        output.WriteString(2, Package);
-      }
-      if (dependency_.Count > 0) {
-        foreach (string element in dependency_) {
-          output.WriteString(3, element);
-        }
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in MessageTypeList) {
-        output.WriteMessage(4, element);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList) {
-        output.WriteMessage(5, element);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto element in ServiceList) {
-        output.WriteMessage(6, element);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList) {
-        output.WriteMessage(7, element);
-      }
-      if (HasOptions) {
-        output.WriteMessage(8, Options);
-      }
-      UnknownFields.WriteTo(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 (HasPackage) {
-          size += pb::CodedOutputStream.ComputeStringSize(2, Package);
-        }
-        {
-          int dataSize = 0;
-          foreach (string element in DependencyList) {
-            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
-          }
-          size += dataSize;
-          size += 1 * dependency_.Count;
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in MessageTypeList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(4, element);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(5, element);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto element in ServiceList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(6, element);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(7, element);
-        }
-        if (HasOptions) {
-          size += pb::CodedOutputStream.ComputeMessageSize(8, Options);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static FileDescriptorProto ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FileDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FileDescriptorProto ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FileDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FileDescriptorProto ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FileDescriptorProto ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static FileDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static FileDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static FileDescriptorProto ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FileDescriptorProto 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(FileDescriptorProto prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<FileDescriptorProto, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      FileDescriptorProto result = new FileDescriptorProto();
-      
-      protected override FileDescriptorProto MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new FileDescriptorProto();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Descriptor; }
-      }
-      
-      public override FileDescriptorProto DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.DefaultInstance; }
-      }
-      
-      public override FileDescriptorProto BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.dependency_.MakeReadOnly();
-        result.messageType_.MakeReadOnly();
-        result.enumType_.MakeReadOnly();
-        result.service_.MakeReadOnly();
-        result.extension_.MakeReadOnly();
-        FileDescriptorProto returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is FileDescriptorProto) {
-          return MergeFrom((FileDescriptorProto) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(FileDescriptorProto other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.DefaultInstance) return this;
-        if (other.HasName) {
-          Name = other.Name;
-        }
-        if (other.HasPackage) {
-          Package = other.Package;
-        }
-        if (other.dependency_.Count != 0) {
-          base.AddRange(other.dependency_, result.dependency_);
-        }
-        if (other.messageType_.Count != 0) {
-          base.AddRange(other.messageType_, result.messageType_);
-        }
-        if (other.enumType_.Count != 0) {
-          base.AddRange(other.enumType_, result.enumType_);
-        }
-        if (other.service_.Count != 0) {
-          base.AddRange(other.service_, result.service_);
-        }
-        if (other.extension_.Count != 0) {
-          base.AddRange(other.extension_, result.extension_);
-        }
-        if (other.HasOptions) {
-          MergeOptions(other.Options);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Name = input.ReadString();
-              break;
-            }
-            case 18: {
-              Package = input.ReadString();
-              break;
-            }
-            case 26: {
-              AddDependency(input.ReadString());
-              break;
-            }
-            case 34: {
-              global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddMessageType(subBuilder.BuildPartial());
-              break;
-            }
-            case 42: {
-              global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddEnumType(subBuilder.BuildPartial());
-              break;
-            }
-            case 50: {
-              global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddService(subBuilder.BuildPartial());
-              break;
-            }
-            case 58: {
-              global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddExtension(subBuilder.BuildPartial());
-              break;
-            }
-            case 66: {
-              global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.CreateBuilder();
-              if (HasOptions) {
-                subBuilder.MergeFrom(Options);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Options = subBuilder.BuildPartial();
-              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 HasPackage {
-        get { return result.HasPackage; }
-      }
-      public string Package {
-        get { return result.Package; }
-        set { SetPackage(value); }
-      }
-      public Builder SetPackage(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasPackage = true;
-        result.package_ = value;
-        return this;
-      }
-      public Builder ClearPackage() {
-        result.hasPackage = false;
-        result.package_ = "";
-        return this;
-      }
-      
-      public pbc::IPopsicleList<string> DependencyList {
-        get { return result.dependency_; }
-      }
-      public int DependencyCount {
-        get { return result.DependencyCount; }
-      }
-      public string GetDependency(int index) {
-        return result.GetDependency(index);
-      }
-      public Builder SetDependency(int index, string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.dependency_[index] = value;
-        return this;
-      }
-      public Builder AddDependency(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.dependency_.Add(value);
-        return this;
-      }
-      public Builder AddRangeDependency(scg::IEnumerable<string> values) {
-        base.AddRange(values, result.dependency_);
-        return this;
-      }
-      public Builder ClearDependency() {
-        result.dependency_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> MessageTypeList {
-        get { return result.messageType_; }
-      }
-      public int MessageTypeCount {
-        get { return result.MessageTypeCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto GetMessageType(int index) {
-        return result.GetMessageType(index);
-      }
-      public Builder SetMessageType(int index, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.messageType_[index] = value;
-        return this;
-      }
-      public Builder SetMessageType(int index, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.messageType_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddMessageType(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.messageType_.Add(value);
-        return this;
-      }
-      public Builder AddMessageType(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.messageType_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeMessageType(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> values) {
-        base.AddRange(values, result.messageType_);
-        return this;
-      }
-      public Builder ClearMessageType() {
-        result.messageType_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> EnumTypeList {
-        get { return result.enumType_; }
-      }
-      public int EnumTypeCount {
-        get { return result.EnumTypeCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto GetEnumType(int index) {
-        return result.GetEnumType(index);
-      }
-      public Builder SetEnumType(int index, global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.enumType_[index] = value;
-        return this;
-      }
-      public Builder SetEnumType(int index, global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.enumType_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddEnumType(global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.enumType_.Add(value);
-        return this;
-      }
-      public Builder AddEnumType(global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.enumType_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeEnumType(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> values) {
-        base.AddRange(values, result.enumType_);
-        return this;
-      }
-      public Builder ClearEnumType() {
-        result.enumType_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto> ServiceList {
-        get { return result.service_; }
-      }
-      public int ServiceCount {
-        get { return result.ServiceCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto GetService(int index) {
-        return result.GetService(index);
-      }
-      public Builder SetService(int index, global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.service_[index] = value;
-        return this;
-      }
-      public Builder SetService(int index, global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.service_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddService(global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.service_.Add(value);
-        return this;
-      }
-      public Builder AddService(global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.service_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeService(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto> values) {
-        base.AddRange(values, result.service_);
-        return this;
-      }
-      public Builder ClearService() {
-        result.service_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> ExtensionList {
-        get { return result.extension_; }
-      }
-      public int ExtensionCount {
-        get { return result.ExtensionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetExtension(int index) {
-        return result.GetExtension(index);
-      }
-      public Builder SetExtension(int index, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.extension_[index] = value;
-        return this;
-      }
-      public Builder SetExtension(int index, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.extension_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddExtension(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.extension_.Add(value);
-        return this;
-      }
-      public Builder AddExtension(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.extension_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeExtension(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> values) {
-        base.AddRange(values, result.extension_);
-        return this;
-      }
-      public Builder ClearExtension() {
-        result.extension_.Clear();
-        return this;
-      }
-      
-      public bool HasOptions {
-       get { return result.HasOptions; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FileOptions Options {
-        get { return result.Options; }
-        set { SetOptions(value); }
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOptions = true;
-        result.options_ = value;
-        return this;
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.hasOptions = true;
-        result.options_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        if (result.HasOptions &&
-            result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance) {
-            result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.CreateBuilder(result.options_).MergeFrom(value).BuildPartial();
-        } else {
-          result.options_ = value;
-        }
-        result.hasOptions = true;
-        return this;
-      }
-      public Builder ClearOptions() {
-        result.hasOptions = false;
-        result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance;
-        return this;
-      }
-    }
-    static FileDescriptorProto() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class DescriptorProto : pb::GeneratedMessage<DescriptorProto, DescriptorProto.Builder> {
-    private static readonly DescriptorProto defaultInstance = new Builder().BuildPartial();
-    public static DescriptorProto DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override DescriptorProto DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override DescriptorProto ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_DescriptorProto__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<DescriptorProto, DescriptorProto.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_DescriptorProto__FieldAccessorTable; }
-    }
-    
-    #region Nested types
-    public static class Types {
-      public sealed partial class ExtensionRange : pb::GeneratedMessage<ExtensionRange, ExtensionRange.Builder> {
-        private static readonly ExtensionRange defaultInstance = new Builder().BuildPartial();
-        public static ExtensionRange DefaultInstance {
-          get { return defaultInstance; }
-        }
-        
-        public override ExtensionRange DefaultInstanceForType {
-          get { return defaultInstance; }
-        }
-        
-        protected override ExtensionRange ThisMessage {
-          get { return this; }
-        }
-        
-        public static pbd::MessageDescriptor Descriptor {
-          get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor; }
-        }
-        
-        protected override pb::FieldAccess.FieldAccessorTable<ExtensionRange, ExtensionRange.Builder> InternalFieldAccessors {
-          get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable; }
-        }
-        
-        public const int StartFieldNumber = 1;
-        private bool hasStart;
-        private int start_ = 0;
-        public bool HasStart {
-          get { return hasStart; }
-        }
-        public int Start {
-          get { return start_; }
-        }
-        
-        public const int EndFieldNumber = 2;
-        private bool hasEnd;
-        private int end_ = 0;
-        public bool HasEnd {
-          get { return hasEnd; }
-        }
-        public int End {
-          get { return end_; }
-        }
-        
-        public override bool IsInitialized {
-          get {
-            return true;
-          }
-        }
-        
-        public override void WriteTo(pb::CodedOutputStream output) {
-          int size = SerializedSize;
-          if (HasStart) {
-            output.WriteInt32(1, Start);
-          }
-          if (HasEnd) {
-            output.WriteInt32(2, End);
-          }
-          UnknownFields.WriteTo(output);
-        }
-        
-        private int memoizedSerializedSize = -1;
-        public override int SerializedSize {
-          get {
-            int size = memoizedSerializedSize;
-            if (size != -1) return size;
-            
-            size = 0;
-            if (HasStart) {
-              size += pb::CodedOutputStream.ComputeInt32Size(1, Start);
+
+        protected override FileDescriptorSet ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FileDescriptorSet__Descriptor;
             }
-            if (HasEnd) {
-              size += pb::CodedOutputStream.ComputeInt32Size(2, End);
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<FileDescriptorSet, FileDescriptorSet.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable;
             }
-            size += UnknownFields.SerializedSize;
-            memoizedSerializedSize = size;
-            return size;
-          }
         }
-        
-        public static ExtensionRange ParseFrom(pb::ByteString data) {
-          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+
+        public const int FileFieldNumber = 1;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> file_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> FileList
+        {
+            get { return file_; }
         }
-        public static ExtensionRange ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+
+        public int FileCount
+        {
+            get { return file_.Count; }
         }
-        public static ExtensionRange ParseFrom(byte[] data) {
-          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto GetFile(int index)
+        {
+            return file_[index];
         }
-        public static ExtensionRange ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto element in FileList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                return true;
+            }
         }
-        public static ExtensionRange ParseFrom(global::System.IO.Stream input) {
-          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto element in FileList)
+            {
+                output.WriteMessage(1, element);
+            }
+            UnknownFields.WriteTo(output);
         }
-        public static ExtensionRange ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto element in FileList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(1, element);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
         }
-        public static ExtensionRange ParseDelimitedFrom(global::System.IO.Stream input) {
-          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+
+        public static FileDescriptorSet ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
         }
-        public static ExtensionRange ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+
+        public static FileDescriptorSet ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
         }
-        public static ExtensionRange ParseFrom(pb::CodedInputStream input) {
-          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+
+        public static FileDescriptorSet ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
         }
-        public static ExtensionRange ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+
+        public static FileDescriptorSet ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, 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(ExtensionRange prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
+
+        public static FileDescriptorSet ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
         }
-        
-        public sealed partial class Builder : pb::GeneratedBuilder<ExtensionRange, Builder> {
-          protected override Builder ThisBuilder {
-            get { return this; }
-          }
-          public Builder() {}
-          
-          ExtensionRange result = new ExtensionRange();
-          
-          protected override ExtensionRange MessageBeingBuilt {
-            get { return result; }
-          }
-          
-          public override Builder Clear() {
-            result = new ExtensionRange();
-            return this;
-          }
-          
-          public override Builder Clone() {
-            return new Builder().MergeFrom(result);
-          }
-          
-          public override pbd::MessageDescriptor DescriptorForType {
-            get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Descriptor; }
-          }
-          
-          public override ExtensionRange DefaultInstanceForType {
-            get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.DefaultInstance; }
-          }
-          
-          public override ExtensionRange BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-            }
-            ExtensionRange returnMe = result;
-            result = null;
-            return returnMe;
-          }
-          
-          public override Builder MergeFrom(pb::IMessage other) {
-            if (other is ExtensionRange) {
-              return MergeFrom((ExtensionRange) other);
-            } else {
-              base.MergeFrom(other);
-              return this;
-            }
-          }
-          
-          public override Builder MergeFrom(ExtensionRange other) {
-            if (other == global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.DefaultInstance) return this;
-            if (other.HasStart) {
-              Start = other.Start;
-            }
-            if (other.HasEnd) {
-              End = other.End;
-            }
-            this.MergeUnknownFields(other.UnknownFields);
-            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) {
-            pb::UnknownFieldSet.Builder unknownFields = null;
-            while (true) {
-              uint tag = input.ReadTag();
-              switch (tag) {
-                case 0: {
-                  if (unknownFields != null) {
-                    this.UnknownFields = unknownFields.Build();
-                  }
-                  return this;
-                }
-                default: {
-                  if (pb::WireFormat.IsEndGroupTag(tag)) {
-                    if (unknownFields != null) {
-                      this.UnknownFields = unknownFields.Build();
-                    }
-                    return this;
-                  }
-                  if (unknownFields == null) {
-                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                  }
-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-                  break;
-                }
-                case 8: {
-                  Start = input.ReadInt32();
-                  break;
-                }
-                case 16: {
-                  End = input.ReadInt32();
-                  break;
-                }
-              }
-            }
-          }
-          
-          
-          public bool HasStart {
-            get { return result.HasStart; }
-          }
-          public int Start {
-            get { return result.Start; }
-            set { SetStart(value); }
-          }
-          public Builder SetStart(int value) {
-            result.hasStart = true;
-            result.start_ = value;
-            return this;
-          }
-          public Builder ClearStart() {
-            result.hasStart = false;
-            result.start_ = 0;
-            return this;
-          }
-          
-          public bool HasEnd {
-            get { return result.HasEnd; }
-          }
-          public int End {
-            get { return result.End; }
-            set { SetEnd(value); }
-          }
-          public Builder SetEnd(int value) {
-            result.hasEnd = true;
-            result.end_ = value;
-            return this;
-          }
-          public Builder ClearEnd() {
-            result.hasEnd = false;
-            result.end_ = 0;
-            return this;
-          }
-        }
-        static ExtensionRange() {
-          object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.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 FieldFieldNumber = 2;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> field_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> FieldList {
-      get { return field_; }
-    }
-    public int FieldCount {
-      get { return field_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetField(int index) {
-      return field_[index];
-    }
-    
-    public const int ExtensionFieldNumber = 6;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> extension_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> ExtensionList {
-      get { return extension_; }
-    }
-    public int ExtensionCount {
-      get { return extension_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetExtension(int index) {
-      return extension_[index];
-    }
-    
-    public const int NestedTypeFieldNumber = 3;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> nestedType_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> NestedTypeList {
-      get { return nestedType_; }
-    }
-    public int NestedTypeCount {
-      get { return nestedType_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto GetNestedType(int index) {
-      return nestedType_[index];
-    }
-    
-    public const int EnumTypeFieldNumber = 4;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> enumType_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> EnumTypeList {
-      get { return enumType_; }
-    }
-    public int EnumTypeCount {
-      get { return enumType_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto GetEnumType(int index) {
-      return enumType_[index];
-    }
-    
-    public const int ExtensionRangeFieldNumber = 5;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange> extensionRange_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange> ExtensionRangeList {
-      get { return extensionRange_; }
-    }
-    public int ExtensionRangeCount {
-      get { return extensionRange_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange GetExtensionRange(int index) {
-      return extensionRange_[index];
-    }
-    
-    public const int OptionsFieldNumber = 7;
-    private bool hasOptions;
-    private global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions options_ = global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance;
-    public bool HasOptions {
-      get { return hasOptions; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions Options {
-      get { return options_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in FieldList) {
-          if (!element.IsInitialized) return false;
+
+        public static FileDescriptorSet ParseFrom(global::System.IO.Stream input,
+                                                  pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList) {
-          if (!element.IsInitialized) return false;
+
+        public static FileDescriptorSet ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
         }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in NestedTypeList) {
-          if (!element.IsInitialized) return false;
+
+        public static FileDescriptorSet ParseDelimitedFrom(global::System.IO.Stream input,
+                                                           pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
         }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList) {
-          if (!element.IsInitialized) return false;
+
+        public static FileDescriptorSet ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
         }
-        if (HasOptions) {
-          if (!Options.IsInitialized) return false;
+
+        public static FileDescriptorSet ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasName) {
-        output.WriteString(1, Name);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in FieldList) {
-        output.WriteMessage(2, element);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in NestedTypeList) {
-        output.WriteMessage(3, element);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList) {
-        output.WriteMessage(4, element);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange element in ExtensionRangeList) {
-        output.WriteMessage(5, element);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList) {
-        output.WriteMessage(6, element);
-      }
-      if (HasOptions) {
-        output.WriteMessage(7, Options);
-      }
-      UnknownFields.WriteTo(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);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in FieldList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(2, element);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(6, element);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in NestedTypeList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(3, element);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(4, element);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange element in ExtensionRangeList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(5, element);
-        }
-        if (HasOptions) {
-          size += pb::CodedOutputStream.ComputeMessageSize(7, Options);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static DescriptorProto ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static DescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static DescriptorProto ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static DescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static DescriptorProto ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static DescriptorProto ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static DescriptorProto ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static DescriptorProto ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static DescriptorProto ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static DescriptorProto 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(DescriptorProto prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<DescriptorProto, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      DescriptorProto result = new DescriptorProto();
-      
-      protected override DescriptorProto MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new DescriptorProto();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Descriptor; }
-      }
-      
-      public override DescriptorProto DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.DefaultInstance; }
-      }
-      
-      public override DescriptorProto BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.field_.MakeReadOnly();
-        result.extension_.MakeReadOnly();
-        result.nestedType_.MakeReadOnly();
-        result.enumType_.MakeReadOnly();
-        result.extensionRange_.MakeReadOnly();
-        DescriptorProto returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is DescriptorProto) {
-          return MergeFrom((DescriptorProto) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(DescriptorProto other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.DefaultInstance) return this;
-        if (other.HasName) {
-          Name = other.Name;
-        }
-        if (other.field_.Count != 0) {
-          base.AddRange(other.field_, result.field_);
-        }
-        if (other.extension_.Count != 0) {
-          base.AddRange(other.extension_, result.extension_);
-        }
-        if (other.nestedType_.Count != 0) {
-          base.AddRange(other.nestedType_, result.nestedType_);
-        }
-        if (other.enumType_.Count != 0) {
-          base.AddRange(other.enumType_, result.enumType_);
-        }
-        if (other.extensionRange_.Count != 0) {
-          base.AddRange(other.extensionRange_, result.extensionRange_);
-        }
-        if (other.HasOptions) {
-          MergeOptions(other.Options);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Name = input.ReadString();
-              break;
-            }
-            case 18: {
-              global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddField(subBuilder.BuildPartial());
-              break;
-            }
-            case 26: {
-              global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddNestedType(subBuilder.BuildPartial());
-              break;
-            }
-            case 34: {
-              global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddEnumType(subBuilder.BuildPartial());
-              break;
-            }
-            case 42: {
-              global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddExtensionRange(subBuilder.BuildPartial());
-              break;
-            }
-            case 50: {
-              global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddExtension(subBuilder.BuildPartial());
-              break;
-            }
-            case 58: {
-              global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.CreateBuilder();
-              if (HasOptions) {
-                subBuilder.MergeFrom(Options);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Options = subBuilder.BuildPartial();
-              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 pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> FieldList {
-        get { return result.field_; }
-      }
-      public int FieldCount {
-        get { return result.FieldCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetField(int index) {
-        return result.GetField(index);
-      }
-      public Builder SetField(int index, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.field_[index] = value;
-        return this;
-      }
-      public Builder SetField(int index, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.field_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddField(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.field_.Add(value);
-        return this;
-      }
-      public Builder AddField(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.field_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeField(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> values) {
-        base.AddRange(values, result.field_);
-        return this;
-      }
-      public Builder ClearField() {
-        result.field_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> ExtensionList {
-        get { return result.extension_; }
-      }
-      public int ExtensionCount {
-        get { return result.ExtensionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetExtension(int index) {
-        return result.GetExtension(index);
-      }
-      public Builder SetExtension(int index, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.extension_[index] = value;
-        return this;
-      }
-      public Builder SetExtension(int index, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.extension_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddExtension(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.extension_.Add(value);
-        return this;
-      }
-      public Builder AddExtension(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.extension_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeExtension(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> values) {
-        base.AddRange(values, result.extension_);
-        return this;
-      }
-      public Builder ClearExtension() {
-        result.extension_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> NestedTypeList {
-        get { return result.nestedType_; }
-      }
-      public int NestedTypeCount {
-        get { return result.NestedTypeCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto GetNestedType(int index) {
-        return result.GetNestedType(index);
-      }
-      public Builder SetNestedType(int index, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.nestedType_[index] = value;
-        return this;
-      }
-      public Builder SetNestedType(int index, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.nestedType_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddNestedType(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.nestedType_.Add(value);
-        return this;
-      }
-      public Builder AddNestedType(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.nestedType_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeNestedType(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> values) {
-        base.AddRange(values, result.nestedType_);
-        return this;
-      }
-      public Builder ClearNestedType() {
-        result.nestedType_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> EnumTypeList {
-        get { return result.enumType_; }
-      }
-      public int EnumTypeCount {
-        get { return result.EnumTypeCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto GetEnumType(int index) {
-        return result.GetEnumType(index);
-      }
-      public Builder SetEnumType(int index, global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.enumType_[index] = value;
-        return this;
-      }
-      public Builder SetEnumType(int index, global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.enumType_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddEnumType(global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.enumType_.Add(value);
-        return this;
-      }
-      public Builder AddEnumType(global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.enumType_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeEnumType(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> values) {
-        base.AddRange(values, result.enumType_);
-        return this;
-      }
-      public Builder ClearEnumType() {
-        result.enumType_.Clear();
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange> ExtensionRangeList {
-        get { return result.extensionRange_; }
-      }
-      public int ExtensionRangeCount {
-        get { return result.ExtensionRangeCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange GetExtensionRange(int index) {
-        return result.GetExtensionRange(index);
-      }
-      public Builder SetExtensionRange(int index, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.extensionRange_[index] = value;
-        return this;
-      }
-      public Builder SetExtensionRange(int index, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.extensionRange_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddExtensionRange(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.extensionRange_.Add(value);
-        return this;
-      }
-      public Builder AddExtensionRange(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.extensionRange_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeExtensionRange(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange> values) {
-        base.AddRange(values, result.extensionRange_);
-        return this;
-      }
-      public Builder ClearExtensionRange() {
-        result.extensionRange_.Clear();
-        return this;
-      }
-      
-      public bool HasOptions {
-       get { return result.HasOptions; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions Options {
-        get { return result.Options; }
-        set { SetOptions(value); }
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOptions = true;
-        result.options_ = value;
-        return this;
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.hasOptions = true;
-        result.options_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        if (result.HasOptions &&
-            result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance) {
-            result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.CreateBuilder(result.options_).MergeFrom(value).BuildPartial();
-        } else {
-          result.options_ = value;
-        }
-        result.hasOptions = true;
-        return this;
-      }
-      public Builder ClearOptions() {
-        result.hasOptions = false;
-        result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance;
-        return this;
-      }
-    }
-    static DescriptorProto() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class FieldDescriptorProto : pb::GeneratedMessage<FieldDescriptorProto, FieldDescriptorProto.Builder> {
-    private static readonly FieldDescriptorProto defaultInstance = new Builder().BuildPartial();
-    public static FieldDescriptorProto DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override FieldDescriptorProto DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override FieldDescriptorProto ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FieldDescriptorProto__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<FieldDescriptorProto, FieldDescriptorProto.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable; }
-    }
-    
-    #region Nested types
-    public static class Types {
-      public enum Type {
-        TYPE_DOUBLE = 1,
-        TYPE_FLOAT = 2,
-        TYPE_INT64 = 3,
-        TYPE_UINT64 = 4,
-        TYPE_INT32 = 5,
-        TYPE_FIXED64 = 6,
-        TYPE_FIXED32 = 7,
-        TYPE_BOOL = 8,
-        TYPE_STRING = 9,
-        TYPE_GROUP = 10,
-        TYPE_MESSAGE = 11,
-        TYPE_BYTES = 12,
-        TYPE_UINT32 = 13,
-        TYPE_ENUM = 14,
-        TYPE_SFIXED32 = 15,
-        TYPE_SFIXED64 = 16,
-        TYPE_SINT32 = 17,
-        TYPE_SINT64 = 18,
-      }
-      
-      public enum Label {
-        LABEL_OPTIONAL = 1,
-        LABEL_REQUIRED = 2,
-        LABEL_REPEATED = 3,
-      }
-      
-    }
-    #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 NumberFieldNumber = 3;
-    private bool hasNumber;
-    private int number_ = 0;
-    public bool HasNumber {
-      get { return hasNumber; }
-    }
-    public int Number {
-      get { return number_; }
-    }
-    
-    public const int LabelFieldNumber = 4;
-    private bool hasLabel;
-    private global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label label_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL;
-    public bool HasLabel {
-      get { return hasLabel; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label Label {
-      get { return label_; }
-    }
-    
-    public const int TypeFieldNumber = 5;
-    private bool hasType;
-    private global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type type_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type.TYPE_DOUBLE;
-    public bool HasType {
-      get { return hasType; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type Type {
-      get { return type_; }
-    }
-    
-    public const int TypeNameFieldNumber = 6;
-    private bool hasTypeName;
-    private string typeName_ = "";
-    public bool HasTypeName {
-      get { return hasTypeName; }
-    }
-    public string TypeName {
-      get { return typeName_; }
-    }
-    
-    public const int ExtendeeFieldNumber = 2;
-    private bool hasExtendee;
-    private string extendee_ = "";
-    public bool HasExtendee {
-      get { return hasExtendee; }
-    }
-    public string Extendee {
-      get { return extendee_; }
-    }
-    
-    public const int DefaultValueFieldNumber = 7;
-    private bool hasDefaultValue;
-    private string defaultValue_ = "";
-    public bool HasDefaultValue {
-      get { return hasDefaultValue; }
-    }
-    public string DefaultValue {
-      get { return defaultValue_; }
-    }
-    
-    public const int OptionsFieldNumber = 8;
-    private bool hasOptions;
-    private global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions options_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance;
-    public bool HasOptions {
-      get { return hasOptions; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions Options {
-      get { return options_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        if (HasOptions) {
-          if (!Options.IsInitialized) return false;
-        }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasName) {
-        output.WriteString(1, Name);
-      }
-      if (HasExtendee) {
-        output.WriteString(2, Extendee);
-      }
-      if (HasNumber) {
-        output.WriteInt32(3, Number);
-      }
-      if (HasLabel) {
-        output.WriteEnum(4, (int) Label);
-      }
-      if (HasType) {
-        output.WriteEnum(5, (int) Type);
-      }
-      if (HasTypeName) {
-        output.WriteString(6, TypeName);
-      }
-      if (HasDefaultValue) {
-        output.WriteString(7, DefaultValue);
-      }
-      if (HasOptions) {
-        output.WriteMessage(8, Options);
-      }
-      UnknownFields.WriteTo(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 (HasNumber) {
-          size += pb::CodedOutputStream.ComputeInt32Size(3, Number);
-        }
-        if (HasLabel) {
-          size += pb::CodedOutputStream.ComputeEnumSize(4, (int) Label);
-        }
-        if (HasType) {
-          size += pb::CodedOutputStream.ComputeEnumSize(5, (int) Type);
-        }
-        if (HasTypeName) {
-          size += pb::CodedOutputStream.ComputeStringSize(6, TypeName);
-        }
-        if (HasExtendee) {
-          size += pb::CodedOutputStream.ComputeStringSize(2, Extendee);
-        }
-        if (HasDefaultValue) {
-          size += pb::CodedOutputStream.ComputeStringSize(7, DefaultValue);
-        }
-        if (HasOptions) {
-          size += pb::CodedOutputStream.ComputeMessageSize(8, Options);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static FieldDescriptorProto ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FieldDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FieldDescriptorProto ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FieldDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FieldDescriptorProto ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FieldDescriptorProto ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static FieldDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static FieldDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static FieldDescriptorProto ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FieldDescriptorProto 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(FieldDescriptorProto prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<FieldDescriptorProto, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      FieldDescriptorProto result = new FieldDescriptorProto();
-      
-      protected override FieldDescriptorProto MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new FieldDescriptorProto();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Descriptor; }
-      }
-      
-      public override FieldDescriptorProto DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.DefaultInstance; }
-      }
-      
-      public override FieldDescriptorProto BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        FieldDescriptorProto returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is FieldDescriptorProto) {
-          return MergeFrom((FieldDescriptorProto) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(FieldDescriptorProto other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.DefaultInstance) return this;
-        if (other.HasName) {
-          Name = other.Name;
-        }
-        if (other.HasNumber) {
-          Number = other.Number;
-        }
-        if (other.HasLabel) {
-          Label = other.Label;
-        }
-        if (other.HasType) {
-          Type = other.Type;
-        }
-        if (other.HasTypeName) {
-          TypeName = other.TypeName;
-        }
-        if (other.HasExtendee) {
-          Extendee = other.Extendee;
-        }
-        if (other.HasDefaultValue) {
-          DefaultValue = other.DefaultValue;
-        }
-        if (other.HasOptions) {
-          MergeOptions(other.Options);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Name = input.ReadString();
-              break;
-            }
-            case 18: {
-              Extendee = input.ReadString();
-              break;
-            }
-            case 24: {
-              Number = input.ReadInt32();
-              break;
-            }
-            case 32: {
-              int rawValue = input.ReadEnum();
-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label), rawValue)) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                }
-                unknownFields.MergeVarintField(4, (ulong) rawValue);
-              } else {
-                Label = (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label) rawValue;
-              }
-              break;
-            }
-            case 40: {
-              int rawValue = input.ReadEnum();
-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type), rawValue)) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                }
-                unknownFields.MergeVarintField(5, (ulong) rawValue);
-              } else {
-                Type = (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type) rawValue;
-              }
-              break;
-            }
-            case 50: {
-              TypeName = input.ReadString();
-              break;
-            }
-            case 58: {
-              DefaultValue = input.ReadString();
-              break;
-            }
-            case 66: {
-              global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.CreateBuilder();
-              if (HasOptions) {
-                subBuilder.MergeFrom(Options);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Options = subBuilder.BuildPartial();
-              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 HasNumber {
-        get { return result.HasNumber; }
-      }
-      public int Number {
-        get { return result.Number; }
-        set { SetNumber(value); }
-      }
-      public Builder SetNumber(int value) {
-        result.hasNumber = true;
-        result.number_ = value;
-        return this;
-      }
-      public Builder ClearNumber() {
-        result.hasNumber = false;
-        result.number_ = 0;
-        return this;
-      }
-      
-      public bool HasLabel {
-       get { return result.HasLabel; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label Label {
-        get { return result.Label; }
-        set { SetLabel(value); }
-      }
-      public Builder SetLabel(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label value) {
-        result.hasLabel = true;
-        result.label_ = value;
-        return this;
-      }
-      public Builder ClearLabel() {
-        result.hasLabel = false;
-        result.label_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL;
-        return this;
-      }
-      
-      public bool HasType {
-       get { return result.HasType; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type Type {
-        get { return result.Type; }
-        set { SetType(value); }
-      }
-      public Builder SetType(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type value) {
-        result.hasType = true;
-        result.type_ = value;
-        return this;
-      }
-      public Builder ClearType() {
-        result.hasType = false;
-        result.type_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type.TYPE_DOUBLE;
-        return this;
-      }
-      
-      public bool HasTypeName {
-        get { return result.HasTypeName; }
-      }
-      public string TypeName {
-        get { return result.TypeName; }
-        set { SetTypeName(value); }
-      }
-      public Builder SetTypeName(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasTypeName = true;
-        result.typeName_ = value;
-        return this;
-      }
-      public Builder ClearTypeName() {
-        result.hasTypeName = false;
-        result.typeName_ = "";
-        return this;
-      }
-      
-      public bool HasExtendee {
-        get { return result.HasExtendee; }
-      }
-      public string Extendee {
-        get { return result.Extendee; }
-        set { SetExtendee(value); }
-      }
-      public Builder SetExtendee(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasExtendee = true;
-        result.extendee_ = value;
-        return this;
-      }
-      public Builder ClearExtendee() {
-        result.hasExtendee = false;
-        result.extendee_ = "";
-        return this;
-      }
-      
-      public bool HasDefaultValue {
-        get { return result.HasDefaultValue; }
-      }
-      public string DefaultValue {
-        get { return result.DefaultValue; }
-        set { SetDefaultValue(value); }
-      }
-      public Builder SetDefaultValue(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasDefaultValue = true;
-        result.defaultValue_ = value;
-        return this;
-      }
-      public Builder ClearDefaultValue() {
-        result.hasDefaultValue = false;
-        result.defaultValue_ = "";
-        return this;
-      }
-      
-      public bool HasOptions {
-       get { return result.HasOptions; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions Options {
-        get { return result.Options; }
-        set { SetOptions(value); }
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOptions = true;
-        result.options_ = value;
-        return this;
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.hasOptions = true;
-        result.options_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        if (result.HasOptions &&
-            result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance) {
-            result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.CreateBuilder(result.options_).MergeFrom(value).BuildPartial();
-        } else {
-          result.options_ = value;
-        }
-        result.hasOptions = true;
-        return this;
-      }
-      public Builder ClearOptions() {
-        result.hasOptions = false;
-        result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance;
-        return this;
-      }
-    }
-    static FieldDescriptorProto() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class EnumDescriptorProto : pb::GeneratedMessage<EnumDescriptorProto, EnumDescriptorProto.Builder> {
-    private static readonly EnumDescriptorProto defaultInstance = new Builder().BuildPartial();
-    public static EnumDescriptorProto DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override EnumDescriptorProto DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override EnumDescriptorProto ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumDescriptorProto__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<EnumDescriptorProto, EnumDescriptorProto.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable; }
-    }
-    
-    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 ValueFieldNumber = 2;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto> value_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto> ValueList {
-      get { return value_; }
-    }
-    public int ValueCount {
-      get { return value_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto GetValue(int index) {
-      return value_[index];
-    }
-    
-    public const int OptionsFieldNumber = 3;
-    private bool hasOptions;
-    private global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions options_ = global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance;
-    public bool HasOptions {
-      get { return hasOptions; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions Options {
-      get { return options_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto element in ValueList) {
-          if (!element.IsInitialized) return false;
+
+        public static Builder CreateBuilder()
+        {
+            return new Builder();
         }
-        if (HasOptions) {
-          if (!Options.IsInitialized) return false;
+
+        public override Builder ToBuilder()
+        {
+            return CreateBuilder(this);
         }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasName) {
-        output.WriteString(1, Name);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto element in ValueList) {
-        output.WriteMessage(2, element);
-      }
-      if (HasOptions) {
-        output.WriteMessage(3, Options);
-      }
-      UnknownFields.WriteTo(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);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto element in ValueList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(2, element);
-        }
-        if (HasOptions) {
-          size += pb::CodedOutputStream.ComputeMessageSize(3, Options);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static EnumDescriptorProto ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static EnumDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static EnumDescriptorProto ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static EnumDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static EnumDescriptorProto ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static EnumDescriptorProto ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static EnumDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static EnumDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static EnumDescriptorProto ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static EnumDescriptorProto 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(EnumDescriptorProto prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<EnumDescriptorProto, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      EnumDescriptorProto result = new EnumDescriptorProto();
-      
-      protected override EnumDescriptorProto MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new EnumDescriptorProto();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Descriptor; }
-      }
-      
-      public override EnumDescriptorProto DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.DefaultInstance; }
-      }
-      
-      public override EnumDescriptorProto BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.value_.MakeReadOnly();
-        EnumDescriptorProto returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is EnumDescriptorProto) {
-          return MergeFrom((EnumDescriptorProto) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(EnumDescriptorProto other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.DefaultInstance) return this;
-        if (other.HasName) {
-          Name = other.Name;
-        }
-        if (other.value_.Count != 0) {
-          base.AddRange(other.value_, result.value_);
-        }
-        if (other.HasOptions) {
-          MergeOptions(other.Options);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Name = input.ReadString();
-              break;
-            }
-            case 18: {
-              global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddValue(subBuilder.BuildPartial());
-              break;
-            }
-            case 26: {
-              global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.CreateBuilder();
-              if (HasOptions) {
-                subBuilder.MergeFrom(Options);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Options = subBuilder.BuildPartial();
-              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 pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto> ValueList {
-        get { return result.value_; }
-      }
-      public int ValueCount {
-        get { return result.ValueCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto GetValue(int index) {
-        return result.GetValue(index);
-      }
-      public Builder SetValue(int index, global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.value_[index] = value;
-        return this;
-      }
-      public Builder SetValue(int index, global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.value_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddValue(global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.value_.Add(value);
-        return this;
-      }
-      public Builder AddValue(global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.value_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeValue(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto> values) {
-        base.AddRange(values, result.value_);
-        return this;
-      }
-      public Builder ClearValue() {
-        result.value_.Clear();
-        return this;
-      }
-      
-      public bool HasOptions {
-       get { return result.HasOptions; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions Options {
-        get { return result.Options; }
-        set { SetOptions(value); }
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOptions = true;
-        result.options_ = value;
-        return this;
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.hasOptions = true;
-        result.options_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        if (result.HasOptions &&
-            result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance) {
-            result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.CreateBuilder(result.options_).MergeFrom(value).BuildPartial();
-        } else {
-          result.options_ = value;
-        }
-        result.hasOptions = true;
-        return this;
-      }
-      public Builder ClearOptions() {
-        result.hasOptions = false;
-        result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance;
-        return this;
-      }
-    }
-    static EnumDescriptorProto() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class EnumValueDescriptorProto : pb::GeneratedMessage<EnumValueDescriptorProto, EnumValueDescriptorProto.Builder> {
-    private static readonly EnumValueDescriptorProto defaultInstance = new Builder().BuildPartial();
-    public static EnumValueDescriptorProto DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override EnumValueDescriptorProto DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override EnumValueDescriptorProto ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<EnumValueDescriptorProto, EnumValueDescriptorProto.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable; }
-    }
-    
-    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 NumberFieldNumber = 2;
-    private bool hasNumber;
-    private int number_ = 0;
-    public bool HasNumber {
-      get { return hasNumber; }
-    }
-    public int Number {
-      get { return number_; }
-    }
-    
-    public const int OptionsFieldNumber = 3;
-    private bool hasOptions;
-    private global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions options_ = global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance;
-    public bool HasOptions {
-      get { return hasOptions; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions Options {
-      get { return options_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        if (HasOptions) {
-          if (!Options.IsInitialized) return false;
-        }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasName) {
-        output.WriteString(1, Name);
-      }
-      if (HasNumber) {
-        output.WriteInt32(2, Number);
-      }
-      if (HasOptions) {
-        output.WriteMessage(3, Options);
-      }
-      UnknownFields.WriteTo(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 (HasNumber) {
-          size += pb::CodedOutputStream.ComputeInt32Size(2, Number);
-        }
-        if (HasOptions) {
-          size += pb::CodedOutputStream.ComputeMessageSize(3, Options);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static EnumValueDescriptorProto ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static EnumValueDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static EnumValueDescriptorProto ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static EnumValueDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static EnumValueDescriptorProto ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static EnumValueDescriptorProto ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static EnumValueDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static EnumValueDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static EnumValueDescriptorProto ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static EnumValueDescriptorProto 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(EnumValueDescriptorProto prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<EnumValueDescriptorProto, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      EnumValueDescriptorProto result = new EnumValueDescriptorProto();
-      
-      protected override EnumValueDescriptorProto MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new EnumValueDescriptorProto();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Descriptor; }
-      }
-      
-      public override EnumValueDescriptorProto DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.DefaultInstance; }
-      }
-      
-      public override EnumValueDescriptorProto BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        EnumValueDescriptorProto returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is EnumValueDescriptorProto) {
-          return MergeFrom((EnumValueDescriptorProto) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(EnumValueDescriptorProto other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.DefaultInstance) return this;
-        if (other.HasName) {
-          Name = other.Name;
-        }
-        if (other.HasNumber) {
-          Number = other.Number;
-        }
-        if (other.HasOptions) {
-          MergeOptions(other.Options);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Name = input.ReadString();
-              break;
-            }
-            case 16: {
-              Number = input.ReadInt32();
-              break;
-            }
-            case 26: {
-              global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.CreateBuilder();
-              if (HasOptions) {
-                subBuilder.MergeFrom(Options);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Options = subBuilder.BuildPartial();
-              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 HasNumber {
-        get { return result.HasNumber; }
-      }
-      public int Number {
-        get { return result.Number; }
-        set { SetNumber(value); }
-      }
-      public Builder SetNumber(int value) {
-        result.hasNumber = true;
-        result.number_ = value;
-        return this;
-      }
-      public Builder ClearNumber() {
-        result.hasNumber = false;
-        result.number_ = 0;
-        return this;
-      }
-      
-      public bool HasOptions {
-       get { return result.HasOptions; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions Options {
-        get { return result.Options; }
-        set { SetOptions(value); }
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOptions = true;
-        result.options_ = value;
-        return this;
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.hasOptions = true;
-        result.options_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        if (result.HasOptions &&
-            result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance) {
-            result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.CreateBuilder(result.options_).MergeFrom(value).BuildPartial();
-        } else {
-          result.options_ = value;
-        }
-        result.hasOptions = true;
-        return this;
-      }
-      public Builder ClearOptions() {
-        result.hasOptions = false;
-        result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance;
-        return this;
-      }
-    }
-    static EnumValueDescriptorProto() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class ServiceDescriptorProto : pb::GeneratedMessage<ServiceDescriptorProto, ServiceDescriptorProto.Builder> {
-    private static readonly ServiceDescriptorProto defaultInstance = new Builder().BuildPartial();
-    public static ServiceDescriptorProto DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override ServiceDescriptorProto DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override ServiceDescriptorProto ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_ServiceDescriptorProto__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<ServiceDescriptorProto, ServiceDescriptorProto.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable; }
-    }
-    
-    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 MethodFieldNumber = 2;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto> method_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto> MethodList {
-      get { return method_; }
-    }
-    public int MethodCount {
-      get { return method_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto GetMethod(int index) {
-      return method_[index];
-    }
-    
-    public const int OptionsFieldNumber = 3;
-    private bool hasOptions;
-    private global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions options_ = global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance;
-    public bool HasOptions {
-      get { return hasOptions; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions Options {
-      get { return options_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto element in MethodList) {
-          if (!element.IsInitialized) return false;
+
+        public override Builder CreateBuilderForType()
+        {
+            return new Builder();
         }
-        if (HasOptions) {
-          if (!Options.IsInitialized) return false;
+
+        public static Builder CreateBuilder(FileDescriptorSet prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<FileDescriptorSet, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private FileDescriptorSet result = new FileDescriptorSet();
+
+            protected override FileDescriptorSet MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new FileDescriptorSet();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.Descriptor; }
+            }
+
+            public override FileDescriptorSet DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.DefaultInstance; }
+            }
+
+            public override FileDescriptorSet BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.file_.MakeReadOnly();
+                FileDescriptorSet returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is FileDescriptorSet)
+                {
+                    return MergeFrom((FileDescriptorSet) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(FileDescriptorSet other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorSet.DefaultInstance)
+                    return this;
+                if (other.file_.Count != 0)
+                {
+                    base.AddRange(other.file_, result.file_);
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddFile(subBuilder.BuildPartial());
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> FileList
+            {
+                get { return result.file_; }
+            }
+
+            public int FileCount
+            {
+                get { return result.FileCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto GetFile(int index)
+            {
+                return result.GetFile(index);
+            }
+
+            public Builder SetFile(int index, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.file_[index] = value;
+                return this;
+            }
+
+            public Builder SetFile(int index,
+                                   global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder
+                                       builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.file_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddFile(global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.file_.Add(value);
+                return this;
+            }
+
+            public Builder AddFile(
+                global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.file_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeFile(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> values)
+            {
+                base.AddRange(values, result.file_);
+                return this;
+            }
+
+            public Builder ClearFile()
+            {
+                result.file_.Clear();
+                return this;
+            }
+        }
+
+        static FileDescriptorSet()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
         }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasName) {
-        output.WriteString(1, Name);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto element in MethodList) {
-        output.WriteMessage(2, element);
-      }
-      if (HasOptions) {
-        output.WriteMessage(3, Options);
-      }
-      UnknownFields.WriteTo(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);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto element in MethodList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(2, element);
-        }
-        if (HasOptions) {
-          size += pb::CodedOutputStream.ComputeMessageSize(3, Options);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static ServiceDescriptorProto ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static ServiceDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static ServiceDescriptorProto ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static ServiceDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static ServiceDescriptorProto ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static ServiceDescriptorProto ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static ServiceDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static ServiceDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static ServiceDescriptorProto ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static ServiceDescriptorProto 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(ServiceDescriptorProto prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<ServiceDescriptorProto, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      ServiceDescriptorProto result = new ServiceDescriptorProto();
-      
-      protected override ServiceDescriptorProto MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new ServiceDescriptorProto();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Descriptor; }
-      }
-      
-      public override ServiceDescriptorProto DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.DefaultInstance; }
-      }
-      
-      public override ServiceDescriptorProto BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.method_.MakeReadOnly();
-        ServiceDescriptorProto returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is ServiceDescriptorProto) {
-          return MergeFrom((ServiceDescriptorProto) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(ServiceDescriptorProto other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.DefaultInstance) return this;
-        if (other.HasName) {
-          Name = other.Name;
-        }
-        if (other.method_.Count != 0) {
-          base.AddRange(other.method_, result.method_);
-        }
-        if (other.HasOptions) {
-          MergeOptions(other.Options);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Name = input.ReadString();
-              break;
-            }
-            case 18: {
-              global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddMethod(subBuilder.BuildPartial());
-              break;
-            }
-            case 26: {
-              global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.CreateBuilder();
-              if (HasOptions) {
-                subBuilder.MergeFrom(Options);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Options = subBuilder.BuildPartial();
-              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 pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto> MethodList {
-        get { return result.method_; }
-      }
-      public int MethodCount {
-        get { return result.MethodCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto GetMethod(int index) {
-        return result.GetMethod(index);
-      }
-      public Builder SetMethod(int index, global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.method_[index] = value;
-        return this;
-      }
-      public Builder SetMethod(int index, global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.method_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddMethod(global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.method_.Add(value);
-        return this;
-      }
-      public Builder AddMethod(global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.method_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeMethod(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto> values) {
-        base.AddRange(values, result.method_);
-        return this;
-      }
-      public Builder ClearMethod() {
-        result.method_.Clear();
-        return this;
-      }
-      
-      public bool HasOptions {
-       get { return result.HasOptions; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions Options {
-        get { return result.Options; }
-        set { SetOptions(value); }
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOptions = true;
-        result.options_ = value;
-        return this;
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.hasOptions = true;
-        result.options_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        if (result.HasOptions &&
-            result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance) {
-            result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.CreateBuilder(result.options_).MergeFrom(value).BuildPartial();
-        } else {
-          result.options_ = value;
-        }
-        result.hasOptions = true;
-        return this;
-      }
-      public Builder ClearOptions() {
-        result.hasOptions = false;
-        result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance;
-        return this;
-      }
-    }
-    static ServiceDescriptorProto() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class MethodDescriptorProto : pb::GeneratedMessage<MethodDescriptorProto, MethodDescriptorProto.Builder> {
-    private static readonly MethodDescriptorProto defaultInstance = new Builder().BuildPartial();
-    public static MethodDescriptorProto DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override MethodDescriptorProto DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override MethodDescriptorProto ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MethodDescriptorProto__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<MethodDescriptorProto, MethodDescriptorProto.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable; }
-    }
-    
-    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 InputTypeFieldNumber = 2;
-    private bool hasInputType;
-    private string inputType_ = "";
-    public bool HasInputType {
-      get { return hasInputType; }
-    }
-    public string InputType {
-      get { return inputType_; }
-    }
-    
-    public const int OutputTypeFieldNumber = 3;
-    private bool hasOutputType;
-    private string outputType_ = "";
-    public bool HasOutputType {
-      get { return hasOutputType; }
-    }
-    public string OutputType {
-      get { return outputType_; }
-    }
-    
-    public const int OptionsFieldNumber = 4;
-    private bool hasOptions;
-    private global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions options_ = global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance;
-    public bool HasOptions {
-      get { return hasOptions; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions Options {
-      get { return options_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        if (HasOptions) {
-          if (!Options.IsInitialized) return false;
-        }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      if (HasName) {
-        output.WriteString(1, Name);
-      }
-      if (HasInputType) {
-        output.WriteString(2, InputType);
-      }
-      if (HasOutputType) {
-        output.WriteString(3, OutputType);
-      }
-      if (HasOptions) {
-        output.WriteMessage(4, Options);
-      }
-      UnknownFields.WriteTo(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 (HasInputType) {
-          size += pb::CodedOutputStream.ComputeStringSize(2, InputType);
-        }
-        if (HasOutputType) {
-          size += pb::CodedOutputStream.ComputeStringSize(3, OutputType);
-        }
-        if (HasOptions) {
-          size += pb::CodedOutputStream.ComputeMessageSize(4, Options);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static MethodDescriptorProto ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static MethodDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static MethodDescriptorProto ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static MethodDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static MethodDescriptorProto ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static MethodDescriptorProto ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static MethodDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static MethodDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static MethodDescriptorProto ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static MethodDescriptorProto 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(MethodDescriptorProto prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<MethodDescriptorProto, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      MethodDescriptorProto result = new MethodDescriptorProto();
-      
-      protected override MethodDescriptorProto MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new MethodDescriptorProto();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Descriptor; }
-      }
-      
-      public override MethodDescriptorProto DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.DefaultInstance; }
-      }
-      
-      public override MethodDescriptorProto BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        MethodDescriptorProto returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is MethodDescriptorProto) {
-          return MergeFrom((MethodDescriptorProto) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(MethodDescriptorProto other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.DefaultInstance) return this;
-        if (other.HasName) {
-          Name = other.Name;
-        }
-        if (other.HasInputType) {
-          InputType = other.InputType;
-        }
-        if (other.HasOutputType) {
-          OutputType = other.OutputType;
-        }
-        if (other.HasOptions) {
-          MergeOptions(other.Options);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              Name = input.ReadString();
-              break;
-            }
-            case 18: {
-              InputType = input.ReadString();
-              break;
-            }
-            case 26: {
-              OutputType = input.ReadString();
-              break;
-            }
-            case 34: {
-              global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.CreateBuilder();
-              if (HasOptions) {
-                subBuilder.MergeFrom(Options);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Options = subBuilder.BuildPartial();
-              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 HasInputType {
-        get { return result.HasInputType; }
-      }
-      public string InputType {
-        get { return result.InputType; }
-        set { SetInputType(value); }
-      }
-      public Builder SetInputType(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasInputType = true;
-        result.inputType_ = value;
-        return this;
-      }
-      public Builder ClearInputType() {
-        result.hasInputType = false;
-        result.inputType_ = "";
-        return this;
-      }
-      
-      public bool HasOutputType {
-        get { return result.HasOutputType; }
-      }
-      public string OutputType {
-        get { return result.OutputType; }
-        set { SetOutputType(value); }
-      }
-      public Builder SetOutputType(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOutputType = true;
-        result.outputType_ = value;
-        return this;
-      }
-      public Builder ClearOutputType() {
-        result.hasOutputType = false;
-        result.outputType_ = "";
-        return this;
-      }
-      
-      public bool HasOptions {
-       get { return result.HasOptions; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions Options {
-        get { return result.Options; }
-        set { SetOptions(value); }
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasOptions = true;
-        result.options_ = value;
-        return this;
-      }
-      public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.hasOptions = true;
-        result.options_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        if (result.HasOptions &&
-            result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance) {
-            result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.CreateBuilder(result.options_).MergeFrom(value).BuildPartial();
-        } else {
-          result.options_ = value;
-        }
-        result.hasOptions = true;
-        return this;
-      }
-      public Builder ClearOptions() {
-        result.hasOptions = false;
-        result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance;
-        return this;
-      }
-    }
-    static MethodDescriptorProto() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class FileOptions : pb::ExtendableMessage<FileOptions, FileOptions.Builder> {
-    private static readonly FileOptions defaultInstance = new Builder().BuildPartial();
-    public static FileOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override FileOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override FileOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<FileOptions, FileOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileOptions__FieldAccessorTable; }
-    }
-    
-    #region Nested types
-    public static class Types {
-      public enum OptimizeMode {
-        SPEED = 1,
-        CODE_SIZE = 2,
-        LITE_RUNTIME = 3,
-      }
-      
-    }
-    #endregion
-    
-    public const int JavaPackageFieldNumber = 1;
-    private bool hasJavaPackage;
-    private string javaPackage_ = "";
-    public bool HasJavaPackage {
-      get { return hasJavaPackage; }
-    }
-    public string JavaPackage {
-      get { return javaPackage_; }
-    }
-    
-    public const int JavaOuterClassnameFieldNumber = 8;
-    private bool hasJavaOuterClassname;
-    private string javaOuterClassname_ = "";
-    public bool HasJavaOuterClassname {
-      get { return hasJavaOuterClassname; }
-    }
-    public string JavaOuterClassname {
-      get { return javaOuterClassname_; }
-    }
-    
-    public const int JavaMultipleFilesFieldNumber = 10;
-    private bool hasJavaMultipleFiles;
-    private bool javaMultipleFiles_ = false;
-    public bool HasJavaMultipleFiles {
-      get { return hasJavaMultipleFiles; }
-    }
-    public bool JavaMultipleFiles {
-      get { return javaMultipleFiles_; }
-    }
-    
-    public const int OptimizeForFieldNumber = 9;
-    private bool hasOptimizeFor;
-    private global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode optimizeFor_ = global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED;
-    public bool HasOptimizeFor {
-      get { return hasOptimizeFor; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode OptimizeFor {
-      get { return optimizeFor_; }
-    }
-    
-    public const int CcGenericServicesFieldNumber = 16;
-    private bool hasCcGenericServices;
-    private bool ccGenericServices_ = true;
-    public bool HasCcGenericServices {
-      get { return hasCcGenericServices; }
-    }
-    public bool CcGenericServices {
-      get { return ccGenericServices_; }
-    }
-    
-    public const int JavaGenericServicesFieldNumber = 17;
-    private bool hasJavaGenericServices;
-    private bool javaGenericServices_ = true;
-    public bool HasJavaGenericServices {
-      get { return hasJavaGenericServices; }
-    }
-    public bool JavaGenericServices {
-      get { return javaGenericServices_; }
-    }
-    
-    public const int PyGenericServicesFieldNumber = 18;
-    private bool hasPyGenericServices;
-    private bool pyGenericServices_ = true;
-    public bool HasPyGenericServices {
-      get { return hasPyGenericServices; }
-    }
-    public bool PyGenericServices {
-      get { return pyGenericServices_; }
-    }
-    
-    public const int UninterpretedOptionFieldNumber = 999;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-      get { return uninterpretedOption_; }
-    }
-    public int UninterpretedOptionCount {
-      get { return uninterpretedOption_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-      return uninterpretedOption_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          if (!element.IsInitialized) return false;
-        }
-        if (!ExtensionsAreInitialized) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      pb::ExtendableMessage<FileOptions, FileOptions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
-      if (HasJavaPackage) {
-        output.WriteString(1, JavaPackage);
-      }
-      if (HasJavaOuterClassname) {
-        output.WriteString(8, JavaOuterClassname);
-      }
-      if (HasOptimizeFor) {
-        output.WriteEnum(9, (int) OptimizeFor);
-      }
-      if (HasJavaMultipleFiles) {
-        output.WriteBool(10, JavaMultipleFiles);
-      }
-      if (HasCcGenericServices) {
-        output.WriteBool(16, CcGenericServices);
-      }
-      if (HasJavaGenericServices) {
-        output.WriteBool(17, JavaGenericServices);
-      }
-      if (HasPyGenericServices) {
-        output.WriteBool(18, PyGenericServices);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-        output.WriteMessage(999, element);
-      }
-      extensionWriter.WriteUntil(536870912, output);
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasJavaPackage) {
-          size += pb::CodedOutputStream.ComputeStringSize(1, JavaPackage);
-        }
-        if (HasJavaOuterClassname) {
-          size += pb::CodedOutputStream.ComputeStringSize(8, JavaOuterClassname);
-        }
-        if (HasJavaMultipleFiles) {
-          size += pb::CodedOutputStream.ComputeBoolSize(10, JavaMultipleFiles);
-        }
-        if (HasOptimizeFor) {
-          size += pb::CodedOutputStream.ComputeEnumSize(9, (int) OptimizeFor);
-        }
-        if (HasCcGenericServices) {
-          size += pb::CodedOutputStream.ComputeBoolSize(16, CcGenericServices);
-        }
-        if (HasJavaGenericServices) {
-          size += pb::CodedOutputStream.ComputeBoolSize(17, JavaGenericServices);
-        }
-        if (HasPyGenericServices) {
-          size += pb::CodedOutputStream.ComputeBoolSize(18, PyGenericServices);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(999, element);
-        }
-        size += ExtensionsSerializedSize;
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static FileOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FileOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FileOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FileOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FileOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FileOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static FileOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static FileOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static FileOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FileOptions 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(FileOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::ExtendableBuilder<FileOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      FileOptions result = new FileOptions();
-      
-      protected override FileOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new FileOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Descriptor; }
-      }
-      
-      public override FileOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance; }
-      }
-      
-      public override FileOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.uninterpretedOption_.MakeReadOnly();
-        FileOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is FileOptions) {
-          return MergeFrom((FileOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(FileOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance) return this;
-        if (other.HasJavaPackage) {
-          JavaPackage = other.JavaPackage;
-        }
-        if (other.HasJavaOuterClassname) {
-          JavaOuterClassname = other.JavaOuterClassname;
-        }
-        if (other.HasJavaMultipleFiles) {
-          JavaMultipleFiles = other.JavaMultipleFiles;
-        }
-        if (other.HasOptimizeFor) {
-          OptimizeFor = other.OptimizeFor;
-        }
-        if (other.HasCcGenericServices) {
-          CcGenericServices = other.CcGenericServices;
-        }
-        if (other.HasJavaGenericServices) {
-          JavaGenericServices = other.JavaGenericServices;
-        }
-        if (other.HasPyGenericServices) {
-          PyGenericServices = other.PyGenericServices;
-        }
-        if (other.uninterpretedOption_.Count != 0) {
-          base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
-        }
-          this.MergeExtensionFields(other);
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 10: {
-              JavaPackage = input.ReadString();
-              break;
-            }
-            case 66: {
-              JavaOuterClassname = input.ReadString();
-              break;
-            }
-            case 72: {
-              int rawValue = input.ReadEnum();
-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode), rawValue)) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                }
-                unknownFields.MergeVarintField(9, (ulong) rawValue);
-              } else {
-                OptimizeFor = (global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode) rawValue;
-              }
-              break;
-            }
-            case 80: {
-              JavaMultipleFiles = input.ReadBool();
-              break;
-            }
-            case 128: {
-              CcGenericServices = input.ReadBool();
-              break;
-            }
-            case 136: {
-              JavaGenericServices = input.ReadBool();
-              break;
-            }
-            case 144: {
-              PyGenericServices = input.ReadBool();
-              break;
-            }
-            case 7994: {
-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddUninterpretedOption(subBuilder.BuildPartial());
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasJavaPackage {
-        get { return result.HasJavaPackage; }
-      }
-      public string JavaPackage {
-        get { return result.JavaPackage; }
-        set { SetJavaPackage(value); }
-      }
-      public Builder SetJavaPackage(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasJavaPackage = true;
-        result.javaPackage_ = value;
-        return this;
-      }
-      public Builder ClearJavaPackage() {
-        result.hasJavaPackage = false;
-        result.javaPackage_ = "";
-        return this;
-      }
-      
-      public bool HasJavaOuterClassname {
-        get { return result.HasJavaOuterClassname; }
-      }
-      public string JavaOuterClassname {
-        get { return result.JavaOuterClassname; }
-        set { SetJavaOuterClassname(value); }
-      }
-      public Builder SetJavaOuterClassname(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasJavaOuterClassname = true;
-        result.javaOuterClassname_ = value;
-        return this;
-      }
-      public Builder ClearJavaOuterClassname() {
-        result.hasJavaOuterClassname = false;
-        result.javaOuterClassname_ = "";
-        return this;
-      }
-      
-      public bool HasJavaMultipleFiles {
-        get { return result.HasJavaMultipleFiles; }
-      }
-      public bool JavaMultipleFiles {
-        get { return result.JavaMultipleFiles; }
-        set { SetJavaMultipleFiles(value); }
-      }
-      public Builder SetJavaMultipleFiles(bool value) {
-        result.hasJavaMultipleFiles = true;
-        result.javaMultipleFiles_ = value;
-        return this;
-      }
-      public Builder ClearJavaMultipleFiles() {
-        result.hasJavaMultipleFiles = false;
-        result.javaMultipleFiles_ = false;
-        return this;
-      }
-      
-      public bool HasOptimizeFor {
-       get { return result.HasOptimizeFor; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode OptimizeFor {
-        get { return result.OptimizeFor; }
-        set { SetOptimizeFor(value); }
-      }
-      public Builder SetOptimizeFor(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode value) {
-        result.hasOptimizeFor = true;
-        result.optimizeFor_ = value;
-        return this;
-      }
-      public Builder ClearOptimizeFor() {
-        result.hasOptimizeFor = false;
-        result.optimizeFor_ = global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED;
-        return this;
-      }
-      
-      public bool HasCcGenericServices {
-        get { return result.HasCcGenericServices; }
-      }
-      public bool CcGenericServices {
-        get { return result.CcGenericServices; }
-        set { SetCcGenericServices(value); }
-      }
-      public Builder SetCcGenericServices(bool value) {
-        result.hasCcGenericServices = true;
-        result.ccGenericServices_ = value;
-        return this;
-      }
-      public Builder ClearCcGenericServices() {
-        result.hasCcGenericServices = false;
-        result.ccGenericServices_ = true;
-        return this;
-      }
-      
-      public bool HasJavaGenericServices {
-        get { return result.HasJavaGenericServices; }
-      }
-      public bool JavaGenericServices {
-        get { return result.JavaGenericServices; }
-        set { SetJavaGenericServices(value); }
-      }
-      public Builder SetJavaGenericServices(bool value) {
-        result.hasJavaGenericServices = true;
-        result.javaGenericServices_ = value;
-        return this;
-      }
-      public Builder ClearJavaGenericServices() {
-        result.hasJavaGenericServices = false;
-        result.javaGenericServices_ = true;
-        return this;
-      }
-      
-      public bool HasPyGenericServices {
-        get { return result.HasPyGenericServices; }
-      }
-      public bool PyGenericServices {
-        get { return result.PyGenericServices; }
-        set { SetPyGenericServices(value); }
-      }
-      public Builder SetPyGenericServices(bool value) {
-        result.hasPyGenericServices = true;
-        result.pyGenericServices_ = value;
-        return this;
-      }
-      public Builder ClearPyGenericServices() {
-        result.hasPyGenericServices = false;
-        result.pyGenericServices_ = true;
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-        get { return result.uninterpretedOption_; }
-      }
-      public int UninterpretedOptionCount {
-        get { return result.UninterpretedOptionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-        return result.GetUninterpretedOption(index);
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_[index] = value;
-        return this;
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_.Add(value);
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeUninterpretedOption(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values) {
-        base.AddRange(values, result.uninterpretedOption_);
-        return this;
-      }
-      public Builder ClearUninterpretedOption() {
-        result.uninterpretedOption_.Clear();
-        return this;
-      }
-    }
-    static FileOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class MessageOptions : pb::ExtendableMessage<MessageOptions, MessageOptions.Builder> {
-    private static readonly MessageOptions defaultInstance = new Builder().BuildPartial();
-    public static MessageOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override MessageOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override MessageOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MessageOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<MessageOptions, MessageOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MessageOptions__FieldAccessorTable; }
-    }
-    
-    public const int MessageSetWireFormatFieldNumber = 1;
-    private bool hasMessageSetWireFormat;
-    private bool messageSetWireFormat_ = false;
-    public bool HasMessageSetWireFormat {
-      get { return hasMessageSetWireFormat; }
-    }
-    public bool MessageSetWireFormat {
-      get { return messageSetWireFormat_; }
-    }
-    
-    public const int NoStandardDescriptorAccessorFieldNumber = 2;
-    private bool hasNoStandardDescriptorAccessor;
-    private bool noStandardDescriptorAccessor_ = false;
-    public bool HasNoStandardDescriptorAccessor {
-      get { return hasNoStandardDescriptorAccessor; }
-    }
-    public bool NoStandardDescriptorAccessor {
-      get { return noStandardDescriptorAccessor_; }
-    }
-    
-    public const int UninterpretedOptionFieldNumber = 999;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-      get { return uninterpretedOption_; }
-    }
-    public int UninterpretedOptionCount {
-      get { return uninterpretedOption_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-      return uninterpretedOption_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          if (!element.IsInitialized) return false;
-        }
-        if (!ExtensionsAreInitialized) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      pb::ExtendableMessage<MessageOptions, MessageOptions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
-      if (HasMessageSetWireFormat) {
-        output.WriteBool(1, MessageSetWireFormat);
-      }
-      if (HasNoStandardDescriptorAccessor) {
-        output.WriteBool(2, NoStandardDescriptorAccessor);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-        output.WriteMessage(999, element);
-      }
-      extensionWriter.WriteUntil(536870912, output);
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasMessageSetWireFormat) {
-          size += pb::CodedOutputStream.ComputeBoolSize(1, MessageSetWireFormat);
-        }
-        if (HasNoStandardDescriptorAccessor) {
-          size += pb::CodedOutputStream.ComputeBoolSize(2, NoStandardDescriptorAccessor);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(999, element);
-        }
-        size += ExtensionsSerializedSize;
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static MessageOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static MessageOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static MessageOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static MessageOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static MessageOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static MessageOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static MessageOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static MessageOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static MessageOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
     }
-    public static MessageOptions 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(MessageOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::ExtendableBuilder<MessageOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      MessageOptions result = new MessageOptions();
-      
-      protected override MessageOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new MessageOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Descriptor; }
-      }
-      
-      public override MessageOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance; }
-      }
-      
-      public override MessageOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.uninterpretedOption_.MakeReadOnly();
-        MessageOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is MessageOptions) {
-          return MergeFrom((MessageOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(MessageOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance) return this;
-        if (other.HasMessageSetWireFormat) {
-          MessageSetWireFormat = other.MessageSetWireFormat;
-        }
-        if (other.HasNoStandardDescriptorAccessor) {
-          NoStandardDescriptorAccessor = other.NoStandardDescriptorAccessor;
-        }
-        if (other.uninterpretedOption_.Count != 0) {
-          base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
-        }
-          this.MergeExtensionFields(other);
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 8: {
-              MessageSetWireFormat = input.ReadBool();
-              break;
-            }
-            case 16: {
-              NoStandardDescriptorAccessor = input.ReadBool();
-              break;
-            }
-            case 7994: {
-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddUninterpretedOption(subBuilder.BuildPartial());
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasMessageSetWireFormat {
-        get { return result.HasMessageSetWireFormat; }
-      }
-      public bool MessageSetWireFormat {
-        get { return result.MessageSetWireFormat; }
-        set { SetMessageSetWireFormat(value); }
-      }
-      public Builder SetMessageSetWireFormat(bool value) {
-        result.hasMessageSetWireFormat = true;
-        result.messageSetWireFormat_ = value;
-        return this;
-      }
-      public Builder ClearMessageSetWireFormat() {
-        result.hasMessageSetWireFormat = false;
-        result.messageSetWireFormat_ = false;
-        return this;
-      }
-      
-      public bool HasNoStandardDescriptorAccessor {
-        get { return result.HasNoStandardDescriptorAccessor; }
-      }
-      public bool NoStandardDescriptorAccessor {
-        get { return result.NoStandardDescriptorAccessor; }
-        set { SetNoStandardDescriptorAccessor(value); }
-      }
-      public Builder SetNoStandardDescriptorAccessor(bool value) {
-        result.hasNoStandardDescriptorAccessor = true;
-        result.noStandardDescriptorAccessor_ = value;
-        return this;
-      }
-      public Builder ClearNoStandardDescriptorAccessor() {
-        result.hasNoStandardDescriptorAccessor = false;
-        result.noStandardDescriptorAccessor_ = false;
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-        get { return result.uninterpretedOption_; }
-      }
-      public int UninterpretedOptionCount {
-        get { return result.UninterpretedOptionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-        return result.GetUninterpretedOption(index);
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_[index] = value;
-        return this;
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_.Add(value);
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeUninterpretedOption(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values) {
-        base.AddRange(values, result.uninterpretedOption_);
-        return this;
-      }
-      public Builder ClearUninterpretedOption() {
-        result.uninterpretedOption_.Clear();
-        return this;
-      }
-    }
-    static MessageOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class FieldOptions : pb::ExtendableMessage<FieldOptions, FieldOptions.Builder> {
-    private static readonly FieldOptions defaultInstance = new Builder().BuildPartial();
-    public static FieldOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override FieldOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override FieldOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FieldOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<FieldOptions, FieldOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FieldOptions__FieldAccessorTable; }
-    }
-    
-    #region Nested types
-    public static class Types {
-      public enum CType {
-        STRING = 0,
-        CORD = 1,
-        STRING_PIECE = 2,
-      }
-      
-    }
-    #endregion
-    
-    public const int CtypeFieldNumber = 1;
-    private bool hasCtype;
-    private global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType ctype_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType.STRING;
-    public bool HasCtype {
-      get { return hasCtype; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType Ctype {
-      get { return ctype_; }
-    }
-    
-    public const int PackedFieldNumber = 2;
-    private bool hasPacked;
-    private bool packed_ = false;
-    public bool HasPacked {
-      get { return hasPacked; }
-    }
-    public bool Packed {
-      get { return packed_; }
-    }
-    
-    public const int DeprecatedFieldNumber = 3;
-    private bool hasDeprecated;
-    private bool deprecated_ = false;
-    public bool HasDeprecated {
-      get { return hasDeprecated; }
-    }
-    public bool Deprecated {
-      get { return deprecated_; }
-    }
-    
-    public const int ExperimentalMapKeyFieldNumber = 9;
-    private bool hasExperimentalMapKey;
-    private string experimentalMapKey_ = "";
-    public bool HasExperimentalMapKey {
-      get { return hasExperimentalMapKey; }
-    }
-    public string ExperimentalMapKey {
-      get { return experimentalMapKey_; }
-    }
-    
-    public const int UninterpretedOptionFieldNumber = 999;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-      get { return uninterpretedOption_; }
-    }
-    public int UninterpretedOptionCount {
-      get { return uninterpretedOption_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-      return uninterpretedOption_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          if (!element.IsInitialized) return false;
-        }
-        if (!ExtensionsAreInitialized) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      pb::ExtendableMessage<FieldOptions, FieldOptions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
-      if (HasCtype) {
-        output.WriteEnum(1, (int) Ctype);
-      }
-      if (HasPacked) {
-        output.WriteBool(2, Packed);
-      }
-      if (HasDeprecated) {
-        output.WriteBool(3, Deprecated);
-      }
-      if (HasExperimentalMapKey) {
-        output.WriteString(9, ExperimentalMapKey);
-      }
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-        output.WriteMessage(999, element);
-      }
-      extensionWriter.WriteUntil(536870912, output);
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        if (HasCtype) {
-          size += pb::CodedOutputStream.ComputeEnumSize(1, (int) Ctype);
-        }
-        if (HasPacked) {
-          size += pb::CodedOutputStream.ComputeBoolSize(2, Packed);
-        }
-        if (HasDeprecated) {
-          size += pb::CodedOutputStream.ComputeBoolSize(3, Deprecated);
-        }
-        if (HasExperimentalMapKey) {
-          size += pb::CodedOutputStream.ComputeStringSize(9, ExperimentalMapKey);
-        }
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(999, element);
-        }
-        size += ExtensionsSerializedSize;
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static FieldOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FieldOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FieldOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FieldOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FieldOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FieldOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static FieldOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static FieldOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static FieldOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FieldOptions 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(FieldOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::ExtendableBuilder<FieldOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      FieldOptions result = new FieldOptions();
-      
-      protected override FieldOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new FieldOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Descriptor; }
-      }
-      
-      public override FieldOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance; }
-      }
-      
-      public override FieldOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.uninterpretedOption_.MakeReadOnly();
-        FieldOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is FieldOptions) {
-          return MergeFrom((FieldOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(FieldOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance) return this;
-        if (other.HasCtype) {
-          Ctype = other.Ctype;
-        }
-        if (other.HasPacked) {
-          Packed = other.Packed;
-        }
-        if (other.HasDeprecated) {
-          Deprecated = other.Deprecated;
-        }
-        if (other.HasExperimentalMapKey) {
-          ExperimentalMapKey = other.ExperimentalMapKey;
-        }
-        if (other.uninterpretedOption_.Count != 0) {
-          base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
-        }
-          this.MergeExtensionFields(other);
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 8: {
-              int rawValue = input.ReadEnum();
-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType), rawValue)) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                }
-                unknownFields.MergeVarintField(1, (ulong) rawValue);
-              } else {
-                Ctype = (global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType) rawValue;
-              }
-              break;
-            }
-            case 16: {
-              Packed = input.ReadBool();
-              break;
-            }
-            case 24: {
-              Deprecated = input.ReadBool();
-              break;
-            }
-            case 74: {
-              ExperimentalMapKey = input.ReadString();
-              break;
-            }
-            case 7994: {
-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddUninterpretedOption(subBuilder.BuildPartial());
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public bool HasCtype {
-       get { return result.HasCtype; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType Ctype {
-        get { return result.Ctype; }
-        set { SetCtype(value); }
-      }
-      public Builder SetCtype(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType value) {
-        result.hasCtype = true;
-        result.ctype_ = value;
-        return this;
-      }
-      public Builder ClearCtype() {
-        result.hasCtype = false;
-        result.ctype_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType.STRING;
-        return this;
-      }
-      
-      public bool HasPacked {
-        get { return result.HasPacked; }
-      }
-      public bool Packed {
-        get { return result.Packed; }
-        set { SetPacked(value); }
-      }
-      public Builder SetPacked(bool value) {
-        result.hasPacked = true;
-        result.packed_ = value;
-        return this;
-      }
-      public Builder ClearPacked() {
-        result.hasPacked = false;
-        result.packed_ = false;
-        return this;
-      }
-      
-      public bool HasDeprecated {
-        get { return result.HasDeprecated; }
-      }
-      public bool Deprecated {
-        get { return result.Deprecated; }
-        set { SetDeprecated(value); }
-      }
-      public Builder SetDeprecated(bool value) {
-        result.hasDeprecated = true;
-        result.deprecated_ = value;
-        return this;
-      }
-      public Builder ClearDeprecated() {
-        result.hasDeprecated = false;
-        result.deprecated_ = false;
-        return this;
-      }
-      
-      public bool HasExperimentalMapKey {
-        get { return result.HasExperimentalMapKey; }
-      }
-      public string ExperimentalMapKey {
-        get { return result.ExperimentalMapKey; }
-        set { SetExperimentalMapKey(value); }
-      }
-      public Builder SetExperimentalMapKey(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasExperimentalMapKey = true;
-        result.experimentalMapKey_ = value;
-        return this;
-      }
-      public Builder ClearExperimentalMapKey() {
-        result.hasExperimentalMapKey = false;
-        result.experimentalMapKey_ = "";
-        return this;
-      }
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-        get { return result.uninterpretedOption_; }
-      }
-      public int UninterpretedOptionCount {
-        get { return result.UninterpretedOptionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-        return result.GetUninterpretedOption(index);
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_[index] = value;
-        return this;
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_.Add(value);
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeUninterpretedOption(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values) {
-        base.AddRange(values, result.uninterpretedOption_);
-        return this;
-      }
-      public Builder ClearUninterpretedOption() {
-        result.uninterpretedOption_.Clear();
-        return this;
-      }
-    }
-    static FieldOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class EnumOptions : pb::ExtendableMessage<EnumOptions, EnumOptions.Builder> {
-    private static readonly EnumOptions defaultInstance = new Builder().BuildPartial();
-    public static EnumOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override EnumOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override EnumOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<EnumOptions, EnumOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumOptions__FieldAccessorTable; }
-    }
-    
-    public const int UninterpretedOptionFieldNumber = 999;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-      get { return uninterpretedOption_; }
-    }
-    public int UninterpretedOptionCount {
-      get { return uninterpretedOption_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-      return uninterpretedOption_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          if (!element.IsInitialized) return false;
-        }
-        if (!ExtensionsAreInitialized) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      pb::ExtendableMessage<EnumOptions, EnumOptions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-        output.WriteMessage(999, element);
-      }
-      extensionWriter.WriteUntil(536870912, output);
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(999, element);
-        }
-        size += ExtensionsSerializedSize;
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static EnumOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static EnumOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static EnumOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static EnumOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static EnumOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static EnumOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static EnumOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static EnumOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static EnumOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static EnumOptions 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(EnumOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::ExtendableBuilder<EnumOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      EnumOptions result = new EnumOptions();
-      
-      protected override EnumOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new EnumOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Descriptor; }
-      }
-      
-      public override EnumOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance; }
-      }
-      
-      public override EnumOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.uninterpretedOption_.MakeReadOnly();
-        EnumOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is EnumOptions) {
-          return MergeFrom((EnumOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(EnumOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance) return this;
-        if (other.uninterpretedOption_.Count != 0) {
-          base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
-        }
-          this.MergeExtensionFields(other);
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 7994: {
-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddUninterpretedOption(subBuilder.BuildPartial());
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-        get { return result.uninterpretedOption_; }
-      }
-      public int UninterpretedOptionCount {
-        get { return result.UninterpretedOptionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-        return result.GetUninterpretedOption(index);
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_[index] = value;
-        return this;
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_.Add(value);
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeUninterpretedOption(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values) {
-        base.AddRange(values, result.uninterpretedOption_);
-        return this;
-      }
-      public Builder ClearUninterpretedOption() {
-        result.uninterpretedOption_.Clear();
-        return this;
-      }
-    }
-    static EnumOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class EnumValueOptions : pb::ExtendableMessage<EnumValueOptions, EnumValueOptions.Builder> {
-    private static readonly EnumValueOptions defaultInstance = new Builder().BuildPartial();
-    public static EnumValueOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override EnumValueOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override EnumValueOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumValueOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<EnumValueOptions, EnumValueOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable; }
-    }
-    
-    public const int UninterpretedOptionFieldNumber = 999;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-      get { return uninterpretedOption_; }
-    }
-    public int UninterpretedOptionCount {
-      get { return uninterpretedOption_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-      return uninterpretedOption_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          if (!element.IsInitialized) return false;
-        }
-        if (!ExtensionsAreInitialized) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      pb::ExtendableMessage<EnumValueOptions, EnumValueOptions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-        output.WriteMessage(999, element);
-      }
-      extensionWriter.WriteUntil(536870912, output);
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(999, element);
-        }
-        size += ExtensionsSerializedSize;
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static EnumValueOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static EnumValueOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static EnumValueOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static EnumValueOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static EnumValueOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static EnumValueOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static EnumValueOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static EnumValueOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static EnumValueOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static EnumValueOptions 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(EnumValueOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::ExtendableBuilder<EnumValueOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      EnumValueOptions result = new EnumValueOptions();
-      
-      protected override EnumValueOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new EnumValueOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Descriptor; }
-      }
-      
-      public override EnumValueOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance; }
-      }
-      
-      public override EnumValueOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.uninterpretedOption_.MakeReadOnly();
-        EnumValueOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is EnumValueOptions) {
-          return MergeFrom((EnumValueOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(EnumValueOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance) return this;
-        if (other.uninterpretedOption_.Count != 0) {
-          base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
-        }
-          this.MergeExtensionFields(other);
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 7994: {
-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddUninterpretedOption(subBuilder.BuildPartial());
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-        get { return result.uninterpretedOption_; }
-      }
-      public int UninterpretedOptionCount {
-        get { return result.UninterpretedOptionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-        return result.GetUninterpretedOption(index);
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_[index] = value;
-        return this;
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_.Add(value);
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeUninterpretedOption(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values) {
-        base.AddRange(values, result.uninterpretedOption_);
-        return this;
-      }
-      public Builder ClearUninterpretedOption() {
-        result.uninterpretedOption_.Clear();
-        return this;
-      }
-    }
-    static EnumValueOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class ServiceOptions : pb::ExtendableMessage<ServiceOptions, ServiceOptions.Builder> {
-    private static readonly ServiceOptions defaultInstance = new Builder().BuildPartial();
-    public static ServiceOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override ServiceOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override ServiceOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_ServiceOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<ServiceOptions, ServiceOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_ServiceOptions__FieldAccessorTable; }
-    }
-    
-    public const int UninterpretedOptionFieldNumber = 999;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-      get { return uninterpretedOption_; }
-    }
-    public int UninterpretedOptionCount {
-      get { return uninterpretedOption_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-      return uninterpretedOption_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          if (!element.IsInitialized) return false;
-        }
-        if (!ExtensionsAreInitialized) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      pb::ExtendableMessage<ServiceOptions, ServiceOptions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-        output.WriteMessage(999, element);
-      }
-      extensionWriter.WriteUntil(536870912, output);
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(999, element);
-        }
-        size += ExtensionsSerializedSize;
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static ServiceOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static ServiceOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static ServiceOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static ServiceOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static ServiceOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static ServiceOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static ServiceOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static ServiceOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static ServiceOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static ServiceOptions 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(ServiceOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::ExtendableBuilder<ServiceOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      ServiceOptions result = new ServiceOptions();
-      
-      protected override ServiceOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new ServiceOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Descriptor; }
-      }
-      
-      public override ServiceOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance; }
-      }
-      
-      public override ServiceOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.uninterpretedOption_.MakeReadOnly();
-        ServiceOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is ServiceOptions) {
-          return MergeFrom((ServiceOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(ServiceOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance) return this;
-        if (other.uninterpretedOption_.Count != 0) {
-          base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
-        }
-          this.MergeExtensionFields(other);
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 7994: {
-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddUninterpretedOption(subBuilder.BuildPartial());
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-        get { return result.uninterpretedOption_; }
-      }
-      public int UninterpretedOptionCount {
-        get { return result.UninterpretedOptionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-        return result.GetUninterpretedOption(index);
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_[index] = value;
-        return this;
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_.Add(value);
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeUninterpretedOption(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values) {
-        base.AddRange(values, result.uninterpretedOption_);
-        return this;
-      }
-      public Builder ClearUninterpretedOption() {
-        result.uninterpretedOption_.Clear();
-        return this;
-      }
-    }
-    static ServiceOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  public sealed partial class MethodOptions : pb::ExtendableMessage<MethodOptions, MethodOptions.Builder> {
-    private static readonly MethodOptions defaultInstance = new Builder().BuildPartial();
-    public static MethodOptions DefaultInstance {
-      get { return defaultInstance; }
-    }
-    
-    public override MethodOptions DefaultInstanceForType {
-      get { return defaultInstance; }
-    }
-    
-    protected override MethodOptions ThisMessage {
-      get { return this; }
-    }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MethodOptions__Descriptor; }
-    }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<MethodOptions, MethodOptions.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MethodOptions__FieldAccessorTable; }
-    }
-    
-    public const int UninterpretedOptionFieldNumber = 999;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-      get { return uninterpretedOption_; }
-    }
-    public int UninterpretedOptionCount {
-      get { return uninterpretedOption_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-      return uninterpretedOption_[index];
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          if (!element.IsInitialized) return false;
-        }
-        if (!ExtensionsAreInitialized) return false;
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      pb::ExtendableMessage<MethodOptions, MethodOptions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-        output.WriteMessage(999, element);
-      }
-      extensionWriter.WriteUntil(536870912, output);
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(999, element);
-        }
-        size += ExtensionsSerializedSize;
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static MethodOptions ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static MethodOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static MethodOptions ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static MethodOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static MethodOptions ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static MethodOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+
+    public sealed partial class FileDescriptorProto :
+        pb::GeneratedMessage<FileDescriptorProto, FileDescriptorProto.Builder>
+    {
+        private static readonly FileDescriptorProto defaultInstance = new Builder().BuildPartial();
+
+        public static FileDescriptorProto DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override FileDescriptorProto DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override FileDescriptorProto ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FileDescriptorProto__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<FileDescriptorProto, FileDescriptorProto.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable;
+            }
+        }
+
+        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 PackageFieldNumber = 2;
+        private bool hasPackage;
+        private string package_ = "";
+
+        public bool HasPackage
+        {
+            get { return hasPackage; }
+        }
+
+        public string Package
+        {
+            get { return package_; }
+        }
+
+        public const int DependencyFieldNumber = 3;
+        private pbc::PopsicleList<string> dependency_ = new pbc::PopsicleList<string>();
+
+        public scg::IList<string> DependencyList
+        {
+            get { return pbc::Lists.AsReadOnly(dependency_); }
+        }
+
+        public int DependencyCount
+        {
+            get { return dependency_.Count; }
+        }
+
+        public string GetDependency(int index)
+        {
+            return dependency_[index];
+        }
+
+        public const int MessageTypeFieldNumber = 4;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> messageType_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> MessageTypeList
+        {
+            get { return messageType_; }
+        }
+
+        public int MessageTypeCount
+        {
+            get { return messageType_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto GetMessageType(int index)
+        {
+            return messageType_[index];
+        }
+
+        public const int EnumTypeFieldNumber = 5;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> enumType_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> EnumTypeList
+        {
+            get { return enumType_; }
+        }
+
+        public int EnumTypeCount
+        {
+            get { return enumType_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto GetEnumType(int index)
+        {
+            return enumType_[index];
+        }
+
+        public const int ServiceFieldNumber = 6;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto> service_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto> ServiceList
+        {
+            get { return service_; }
+        }
+
+        public int ServiceCount
+        {
+            get { return service_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto GetService(int index)
+        {
+            return service_[index];
+        }
+
+        public const int ExtensionFieldNumber = 7;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> extension_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> ExtensionList
+        {
+            get { return extension_; }
+        }
+
+        public int ExtensionCount
+        {
+            get { return extension_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetExtension(int index)
+        {
+            return extension_[index];
+        }
+
+        public const int OptionsFieldNumber = 8;
+        private bool hasOptions;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.FileOptions options_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance;
+
+        public bool HasOptions
+        {
+            get { return hasOptions; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FileOptions Options
+        {
+            get { return options_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in MessageTypeList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto element in ServiceList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (HasOptions)
+                {
+                    if (!Options.IsInitialized) return false;
+                }
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasName)
+            {
+                output.WriteString(1, Name);
+            }
+            if (HasPackage)
+            {
+                output.WriteString(2, Package);
+            }
+            if (dependency_.Count > 0)
+            {
+                foreach (string element in dependency_)
+                {
+                    output.WriteString(3, element);
+                }
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in MessageTypeList)
+            {
+                output.WriteMessage(4, element);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList)
+            {
+                output.WriteMessage(5, element);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto element in ServiceList)
+            {
+                output.WriteMessage(6, element);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList)
+            {
+                output.WriteMessage(7, element);
+            }
+            if (HasOptions)
+            {
+                output.WriteMessage(8, Options);
+            }
+            UnknownFields.WriteTo(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 (HasPackage)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(2, Package);
+                }
+                {
+                    int dataSize = 0;
+                    foreach (string element in DependencyList)
+                    {
+                        dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
+                    }
+                    size += dataSize;
+                    size += 1*dependency_.Count;
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in MessageTypeList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(4, element);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(5, element);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto element in ServiceList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(6, element);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(7, element);
+                }
+                if (HasOptions)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(8, Options);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static FileDescriptorProto ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static FileDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static FileDescriptorProto ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static FileDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static FileDescriptorProto ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static FileDescriptorProto ParseFrom(global::System.IO.Stream input,
+                                                    pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static FileDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static FileDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input,
+                                                             pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static FileDescriptorProto ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static FileDescriptorProto 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(FileDescriptorProto prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<FileDescriptorProto, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private FileDescriptorProto result = new FileDescriptorProto();
+
+            protected override FileDescriptorProto MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new FileDescriptorProto();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Descriptor; }
+            }
+
+            public override FileDescriptorProto DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.DefaultInstance; }
+            }
+
+            public override FileDescriptorProto BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.dependency_.MakeReadOnly();
+                result.messageType_.MakeReadOnly();
+                result.enumType_.MakeReadOnly();
+                result.service_.MakeReadOnly();
+                result.extension_.MakeReadOnly();
+                FileDescriptorProto returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is FileDescriptorProto)
+                {
+                    return MergeFrom((FileDescriptorProto) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(FileDescriptorProto other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.DefaultInstance)
+                    return this;
+                if (other.HasName)
+                {
+                    Name = other.Name;
+                }
+                if (other.HasPackage)
+                {
+                    Package = other.Package;
+                }
+                if (other.dependency_.Count != 0)
+                {
+                    base.AddRange(other.dependency_, result.dependency_);
+                }
+                if (other.messageType_.Count != 0)
+                {
+                    base.AddRange(other.messageType_, result.messageType_);
+                }
+                if (other.enumType_.Count != 0)
+                {
+                    base.AddRange(other.enumType_, result.enumType_);
+                }
+                if (other.service_.Count != 0)
+                {
+                    base.AddRange(other.service_, result.service_);
+                }
+                if (other.extension_.Count != 0)
+                {
+                    base.AddRange(other.extension_, result.extension_);
+                }
+                if (other.HasOptions)
+                {
+                    MergeOptions(other.Options);
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                Name = input.ReadString();
+                                break;
+                            }
+                        case 18:
+                            {
+                                Package = input.ReadString();
+                                break;
+                            }
+                        case 26:
+                            {
+                                AddDependency(input.ReadString());
+                                break;
+                            }
+                        case 34:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddMessageType(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 42:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddEnumType(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 50:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder
+                                    subBuilder =
+                                        global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.
+                                            CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddService(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 58:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder
+                                    =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddExtension(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 66:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.CreateBuilder();
+                                if (HasOptions)
+                                {
+                                    subBuilder.MergeFrom(Options);
+                                }
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                Options = subBuilder.BuildPartial();
+                                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 HasPackage
+            {
+                get { return result.HasPackage; }
+            }
+
+            public string Package
+            {
+                get { return result.Package; }
+                set { SetPackage(value); }
+            }
+
+            public Builder SetPackage(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasPackage = true;
+                result.package_ = value;
+                return this;
+            }
+
+            public Builder ClearPackage()
+            {
+                result.hasPackage = false;
+                result.package_ = "";
+                return this;
+            }
+
+            public pbc::IPopsicleList<string> DependencyList
+            {
+                get { return result.dependency_; }
+            }
+
+            public int DependencyCount
+            {
+                get { return result.DependencyCount; }
+            }
+
+            public string GetDependency(int index)
+            {
+                return result.GetDependency(index);
+            }
+
+            public Builder SetDependency(int index, string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.dependency_[index] = value;
+                return this;
+            }
+
+            public Builder AddDependency(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.dependency_.Add(value);
+                return this;
+            }
+
+            public Builder AddRangeDependency(scg::IEnumerable<string> values)
+            {
+                base.AddRange(values, result.dependency_);
+                return this;
+            }
+
+            public Builder ClearDependency()
+            {
+                result.dependency_.Clear();
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> MessageTypeList
+            {
+                get { return result.messageType_; }
+            }
+
+            public int MessageTypeCount
+            {
+                get { return result.MessageTypeCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto GetMessageType(int index)
+            {
+                return result.GetMessageType(index);
+            }
+
+            public Builder SetMessageType(int index,
+                                          global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.messageType_[index] = value;
+                return this;
+            }
+
+            public Builder SetMessageType(int index,
+                                          global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder
+                                              builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.messageType_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddMessageType(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.messageType_.Add(value);
+                return this;
+            }
+
+            public Builder AddMessageType(
+                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.messageType_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeMessageType(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> values)
+            {
+                base.AddRange(values, result.messageType_);
+                return this;
+            }
+
+            public Builder ClearMessageType()
+            {
+                result.messageType_.Clear();
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> EnumTypeList
+            {
+                get { return result.enumType_; }
+            }
+
+            public int EnumTypeCount
+            {
+                get { return result.EnumTypeCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto GetEnumType(int index)
+            {
+                return result.GetEnumType(index);
+            }
+
+            public Builder SetEnumType(int index,
+                                       global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.enumType_[index] = value;
+                return this;
+            }
+
+            public Builder SetEnumType(int index,
+                                       global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder
+                                           builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.enumType_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddEnumType(global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.enumType_.Add(value);
+                return this;
+            }
+
+            public Builder AddEnumType(
+                global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.enumType_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeEnumType(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> values)
+            {
+                base.AddRange(values, result.enumType_);
+                return this;
+            }
+
+            public Builder ClearEnumType()
+            {
+                result.enumType_.Clear();
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto>
+                ServiceList
+            {
+                get { return result.service_; }
+            }
+
+            public int ServiceCount
+            {
+                get { return result.ServiceCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto GetService(int index)
+            {
+                return result.GetService(index);
+            }
+
+            public Builder SetService(int index,
+                                      global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.service_[index] = value;
+                return this;
+            }
+
+            public Builder SetService(int index,
+                                      global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder
+                                          builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.service_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddService(global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.service_.Add(value);
+                return this;
+            }
+
+            public Builder AddService(
+                global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.service_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeService(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto> values)
+            {
+                base.AddRange(values, result.service_);
+                return this;
+            }
+
+            public Builder ClearService()
+            {
+                result.service_.Clear();
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto>
+                ExtensionList
+            {
+                get { return result.extension_; }
+            }
+
+            public int ExtensionCount
+            {
+                get { return result.ExtensionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetExtension(int index)
+            {
+                return result.GetExtension(index);
+            }
+
+            public Builder SetExtension(int index,
+                                        global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.extension_[index] = value;
+                return this;
+            }
+
+            public Builder SetExtension(int index,
+                                        global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder
+                                            builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.extension_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddExtension(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.extension_.Add(value);
+                return this;
+            }
+
+            public Builder AddExtension(
+                global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.extension_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeExtension(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> values)
+            {
+                base.AddRange(values, result.extension_);
+                return this;
+            }
+
+            public Builder ClearExtension()
+            {
+                result.extension_.Clear();
+                return this;
+            }
+
+            public bool HasOptions
+            {
+                get { return result.HasOptions; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FileOptions Options
+            {
+                get { return result.Options; }
+                set { SetOptions(value); }
+            }
+
+            public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOptions = true;
+                result.options_ = value;
+                return this;
+            }
+
+            public Builder SetOptions(
+                global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.hasOptions = true;
+                result.options_ = builderForValue.Build();
+                return this;
+            }
+
+            public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                if (result.HasOptions &&
+                    result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance)
+                {
+                    result.options_ =
+                        global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.CreateBuilder(result.options_).
+                            MergeFrom(value).BuildPartial();
+                }
+                else
+                {
+                    result.options_ = value;
+                }
+                result.hasOptions = true;
+                return this;
+            }
+
+            public Builder ClearOptions()
+            {
+                result.hasOptions = false;
+                result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance;
+                return this;
+            }
+        }
+
+        static FileDescriptorProto()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    public static MethodOptions ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+
+    public sealed partial class DescriptorProto : pb::GeneratedMessage<DescriptorProto, DescriptorProto.Builder>
+    {
+        private static readonly DescriptorProto defaultInstance = new Builder().BuildPartial();
+
+        public static DescriptorProto DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override DescriptorProto DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override DescriptorProto ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_DescriptorProto__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<DescriptorProto, DescriptorProto.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_DescriptorProto__FieldAccessorTable;
+            }
+        }
+
+        #region Nested types
+
+        public static class Types
+        {
+            public sealed partial class ExtensionRange : pb::GeneratedMessage<ExtensionRange, ExtensionRange.Builder>
+            {
+                private static readonly ExtensionRange defaultInstance = new Builder().BuildPartial();
+
+                public static ExtensionRange DefaultInstance
+                {
+                    get { return defaultInstance; }
+                }
+
+                public override ExtensionRange DefaultInstanceForType
+                {
+                    get { return defaultInstance; }
+                }
+
+                protected override ExtensionRange ThisMessage
+                {
+                    get { return this; }
+                }
+
+                public static pbd::MessageDescriptor Descriptor
+                {
+                    get
+                    {
+                        return
+                            global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                                internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor;
+                    }
+                }
+
+                protected override pb::FieldAccess.FieldAccessorTable<ExtensionRange, ExtensionRange.Builder>
+                    InternalFieldAccessors
+                {
+                    get
+                    {
+                        return
+                            global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                                internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable;
+                    }
+                }
+
+                public const int StartFieldNumber = 1;
+                private bool hasStart;
+                private int start_ = 0;
+
+                public bool HasStart
+                {
+                    get { return hasStart; }
+                }
+
+                public int Start
+                {
+                    get { return start_; }
+                }
+
+                public const int EndFieldNumber = 2;
+                private bool hasEnd;
+                private int end_ = 0;
+
+                public bool HasEnd
+                {
+                    get { return hasEnd; }
+                }
+
+                public int End
+                {
+                    get { return end_; }
+                }
+
+                public override bool IsInitialized
+                {
+                    get { return true; }
+                }
+
+                public override void WriteTo(pb::CodedOutputStream output)
+                {
+                    int size = SerializedSize;
+                    if (HasStart)
+                    {
+                        output.WriteInt32(1, Start);
+                    }
+                    if (HasEnd)
+                    {
+                        output.WriteInt32(2, End);
+                    }
+                    UnknownFields.WriteTo(output);
+                }
+
+                private int memoizedSerializedSize = -1;
+
+                public override int SerializedSize
+                {
+                    get
+                    {
+                        int size = memoizedSerializedSize;
+                        if (size != -1) return size;
+
+                        size = 0;
+                        if (HasStart)
+                        {
+                            size += pb::CodedOutputStream.ComputeInt32Size(1, Start);
+                        }
+                        if (HasEnd)
+                        {
+                            size += pb::CodedOutputStream.ComputeInt32Size(2, End);
+                        }
+                        size += UnknownFields.SerializedSize;
+                        memoizedSerializedSize = size;
+                        return size;
+                    }
+                }
+
+                public static ExtensionRange ParseFrom(pb::ByteString data)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+                }
+
+                public static ExtensionRange ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+                }
+
+                public static ExtensionRange ParseFrom(byte[] data)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+                }
+
+                public static ExtensionRange ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+                }
+
+                public static ExtensionRange ParseFrom(global::System.IO.Stream input)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+                }
+
+                public static ExtensionRange ParseFrom(global::System.IO.Stream input,
+                                                       pb::ExtensionRegistry extensionRegistry)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+                }
+
+                public static ExtensionRange ParseDelimitedFrom(global::System.IO.Stream input)
+                {
+                    return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+                }
+
+                public static ExtensionRange ParseDelimitedFrom(global::System.IO.Stream input,
+                                                                pb::ExtensionRegistry extensionRegistry)
+                {
+                    return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+                }
+
+                public static ExtensionRange ParseFrom(pb::CodedInputStream input)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+                }
+
+                public static ExtensionRange 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(ExtensionRange prototype)
+                {
+                    return (Builder) new Builder().MergeFrom(prototype);
+                }
+
+                public sealed partial class Builder : pb::GeneratedBuilder<ExtensionRange, Builder>
+                {
+                    protected override Builder ThisBuilder
+                    {
+                        get { return this; }
+                    }
+
+                    public Builder()
+                    {
+                    }
+
+                    private ExtensionRange result = new ExtensionRange();
+
+                    protected override ExtensionRange MessageBeingBuilt
+                    {
+                        get { return result; }
+                    }
+
+                    public override Builder Clear()
+                    {
+                        result = new ExtensionRange();
+                        return this;
+                    }
+
+                    public override Builder Clone()
+                    {
+                        return new Builder().MergeFrom(result);
+                    }
+
+                    public override pbd::MessageDescriptor DescriptorForType
+                    {
+                        get
+                        {
+                            return
+                                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.
+                                    Descriptor;
+                        }
+                    }
+
+                    public override ExtensionRange DefaultInstanceForType
+                    {
+                        get
+                        {
+                            return
+                                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.
+                                    DefaultInstance;
+                        }
+                    }
+
+                    public override ExtensionRange BuildPartial()
+                    {
+                        if (result == null)
+                        {
+                            throw new global::System.InvalidOperationException(
+                                "build() has already been called on this Builder");
+                        }
+                        ExtensionRange returnMe = result;
+                        result = null;
+                        return returnMe;
+                    }
+
+                    public override Builder MergeFrom(pb::IMessage other)
+                    {
+                        if (other is ExtensionRange)
+                        {
+                            return MergeFrom((ExtensionRange) other);
+                        }
+                        else
+                        {
+                            base.MergeFrom(other);
+                            return this;
+                        }
+                    }
+
+                    public override Builder MergeFrom(ExtensionRange other)
+                    {
+                        if (other ==
+                            global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.
+                                DefaultInstance) return this;
+                        if (other.HasStart)
+                        {
+                            Start = other.Start;
+                        }
+                        if (other.HasEnd)
+                        {
+                            End = other.End;
+                        }
+                        this.MergeUnknownFields(other.UnknownFields);
+                        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)
+                    {
+                        pb::UnknownFieldSet.Builder unknownFields = null;
+                        while (true)
+                        {
+                            uint tag = input.ReadTag();
+                            switch (tag)
+                            {
+                                case 0:
+                                    {
+                                        if (unknownFields != null)
+                                        {
+                                            this.UnknownFields = unknownFields.Build();
+                                        }
+                                        return this;
+                                    }
+                                default:
+                                    {
+                                        if (pb::WireFormat.IsEndGroupTag(tag))
+                                        {
+                                            if (unknownFields != null)
+                                            {
+                                                this.UnknownFields = unknownFields.Build();
+                                            }
+                                            return this;
+                                        }
+                                        if (unknownFields == null)
+                                        {
+                                            unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                        }
+                                        ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                        break;
+                                    }
+                                case 8:
+                                    {
+                                        Start = input.ReadInt32();
+                                        break;
+                                    }
+                                case 16:
+                                    {
+                                        End = input.ReadInt32();
+                                        break;
+                                    }
+                            }
+                        }
+                    }
+
+
+                    public bool HasStart
+                    {
+                        get { return result.HasStart; }
+                    }
+
+                    public int Start
+                    {
+                        get { return result.Start; }
+                        set { SetStart(value); }
+                    }
+
+                    public Builder SetStart(int value)
+                    {
+                        result.hasStart = true;
+                        result.start_ = value;
+                        return this;
+                    }
+
+                    public Builder ClearStart()
+                    {
+                        result.hasStart = false;
+                        result.start_ = 0;
+                        return this;
+                    }
+
+                    public bool HasEnd
+                    {
+                        get { return result.HasEnd; }
+                    }
+
+                    public int End
+                    {
+                        get { return result.End; }
+                        set { SetEnd(value); }
+                    }
+
+                    public Builder SetEnd(int value)
+                    {
+                        result.hasEnd = true;
+                        result.end_ = value;
+                        return this;
+                    }
+
+                    public Builder ClearEnd()
+                    {
+                        result.hasEnd = false;
+                        result.end_ = 0;
+                        return this;
+                    }
+                }
+
+                static ExtensionRange()
+                {
+                    object.ReferenceEquals(
+                        global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.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 FieldFieldNumber = 2;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> field_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> FieldList
+        {
+            get { return field_; }
+        }
+
+        public int FieldCount
+        {
+            get { return field_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetField(int index)
+        {
+            return field_[index];
+        }
+
+        public const int ExtensionFieldNumber = 6;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> extension_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> ExtensionList
+        {
+            get { return extension_; }
+        }
+
+        public int ExtensionCount
+        {
+            get { return extension_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetExtension(int index)
+        {
+            return extension_[index];
+        }
+
+        public const int NestedTypeFieldNumber = 3;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> nestedType_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> NestedTypeList
+        {
+            get { return nestedType_; }
+        }
+
+        public int NestedTypeCount
+        {
+            get { return nestedType_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto GetNestedType(int index)
+        {
+            return nestedType_[index];
+        }
+
+        public const int EnumTypeFieldNumber = 4;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> enumType_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> EnumTypeList
+        {
+            get { return enumType_; }
+        }
+
+        public int EnumTypeCount
+        {
+            get { return enumType_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto GetEnumType(int index)
+        {
+            return enumType_[index];
+        }
+
+        public const int ExtensionRangeFieldNumber = 5;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange>
+            extensionRange_ =
+                new pbc::PopsicleList
+                    <global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange>
+            ExtensionRangeList
+        {
+            get { return extensionRange_; }
+        }
+
+        public int ExtensionRangeCount
+        {
+            get { return extensionRange_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange GetExtensionRange(
+            int index)
+        {
+            return extensionRange_[index];
+        }
+
+        public const int OptionsFieldNumber = 7;
+        private bool hasOptions;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions options_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance;
+
+        public bool HasOptions
+        {
+            get { return hasOptions; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions Options
+        {
+            get { return options_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in FieldList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in NestedTypeList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (HasOptions)
+                {
+                    if (!Options.IsInitialized) return false;
+                }
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasName)
+            {
+                output.WriteString(1, Name);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in FieldList)
+            {
+                output.WriteMessage(2, element);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in NestedTypeList)
+            {
+                output.WriteMessage(3, element);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList)
+            {
+                output.WriteMessage(4, element);
+            }
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange element in
+                    ExtensionRangeList)
+            {
+                output.WriteMessage(5, element);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList)
+            {
+                output.WriteMessage(6, element);
+            }
+            if (HasOptions)
+            {
+                output.WriteMessage(7, Options);
+            }
+            UnknownFields.WriteTo(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);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in FieldList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(2, element);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto element in ExtensionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(6, element);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto element in NestedTypeList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(3, element);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto element in EnumTypeList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(4, element);
+                }
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange element in
+                        ExtensionRangeList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(5, element);
+                }
+                if (HasOptions)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(7, Options);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static DescriptorProto ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static DescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static DescriptorProto ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static DescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static DescriptorProto ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static DescriptorProto ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static DescriptorProto ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static DescriptorProto ParseDelimitedFrom(global::System.IO.Stream input,
+                                                         pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static DescriptorProto ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static DescriptorProto 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(DescriptorProto prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<DescriptorProto, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private DescriptorProto result = new DescriptorProto();
+
+            protected override DescriptorProto MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new DescriptorProto();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Descriptor; }
+            }
+
+            public override DescriptorProto DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.DefaultInstance; }
+            }
+
+            public override DescriptorProto BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.field_.MakeReadOnly();
+                result.extension_.MakeReadOnly();
+                result.nestedType_.MakeReadOnly();
+                result.enumType_.MakeReadOnly();
+                result.extensionRange_.MakeReadOnly();
+                DescriptorProto returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is DescriptorProto)
+                {
+                    return MergeFrom((DescriptorProto) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(DescriptorProto other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.DefaultInstance)
+                    return this;
+                if (other.HasName)
+                {
+                    Name = other.Name;
+                }
+                if (other.field_.Count != 0)
+                {
+                    base.AddRange(other.field_, result.field_);
+                }
+                if (other.extension_.Count != 0)
+                {
+                    base.AddRange(other.extension_, result.extension_);
+                }
+                if (other.nestedType_.Count != 0)
+                {
+                    base.AddRange(other.nestedType_, result.nestedType_);
+                }
+                if (other.enumType_.Count != 0)
+                {
+                    base.AddRange(other.enumType_, result.enumType_);
+                }
+                if (other.extensionRange_.Count != 0)
+                {
+                    base.AddRange(other.extensionRange_, result.extensionRange_);
+                }
+                if (other.HasOptions)
+                {
+                    MergeOptions(other.Options);
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                Name = input.ReadString();
+                                break;
+                            }
+                        case 18:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder
+                                    =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddField(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 26:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddNestedType(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 34:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddEnumType(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 42:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.
+                                    Builder subBuilder =
+                                        global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.
+                                            ExtensionRange.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddExtensionRange(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 50:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder
+                                    =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddExtension(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 58:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.CreateBuilder();
+                                if (HasOptions)
+                                {
+                                    subBuilder.MergeFrom(Options);
+                                }
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                Options = subBuilder.BuildPartial();
+                                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 pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> FieldList
+            {
+                get { return result.field_; }
+            }
+
+            public int FieldCount
+            {
+                get { return result.FieldCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetField(int index)
+            {
+                return result.GetField(index);
+            }
+
+            public Builder SetField(int index,
+                                    global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.field_[index] = value;
+                return this;
+            }
+
+            public Builder SetField(int index,
+                                    global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder
+                                        builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.field_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddField(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.field_.Add(value);
+                return this;
+            }
+
+            public Builder AddField(
+                global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.field_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeField(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> values)
+            {
+                base.AddRange(values, result.field_);
+                return this;
+            }
+
+            public Builder ClearField()
+            {
+                result.field_.Clear();
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto>
+                ExtensionList
+            {
+                get { return result.extension_; }
+            }
+
+            public int ExtensionCount
+            {
+                get { return result.ExtensionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto GetExtension(int index)
+            {
+                return result.GetExtension(index);
+            }
+
+            public Builder SetExtension(int index,
+                                        global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.extension_[index] = value;
+                return this;
+            }
+
+            public Builder SetExtension(int index,
+                                        global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder
+                                            builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.extension_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddExtension(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.extension_.Add(value);
+                return this;
+            }
+
+            public Builder AddExtension(
+                global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.extension_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeExtension(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto> values)
+            {
+                base.AddRange(values, result.extension_);
+                return this;
+            }
+
+            public Builder ClearExtension()
+            {
+                result.extension_.Clear();
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> NestedTypeList
+            {
+                get { return result.nestedType_; }
+            }
+
+            public int NestedTypeCount
+            {
+                get { return result.NestedTypeCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto GetNestedType(int index)
+            {
+                return result.GetNestedType(index);
+            }
+
+            public Builder SetNestedType(int index,
+                                         global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.nestedType_[index] = value;
+                return this;
+            }
+
+            public Builder SetNestedType(int index,
+                                         global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder
+                                             builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.nestedType_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddNestedType(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.nestedType_.Add(value);
+                return this;
+            }
+
+            public Builder AddNestedType(
+                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.nestedType_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeNestedType(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto> values)
+            {
+                base.AddRange(values, result.nestedType_);
+                return this;
+            }
+
+            public Builder ClearNestedType()
+            {
+                result.nestedType_.Clear();
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> EnumTypeList
+            {
+                get { return result.enumType_; }
+            }
+
+            public int EnumTypeCount
+            {
+                get { return result.EnumTypeCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto GetEnumType(int index)
+            {
+                return result.GetEnumType(index);
+            }
+
+            public Builder SetEnumType(int index,
+                                       global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.enumType_[index] = value;
+                return this;
+            }
+
+            public Builder SetEnumType(int index,
+                                       global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder
+                                           builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.enumType_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddEnumType(global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.enumType_.Add(value);
+                return this;
+            }
+
+            public Builder AddEnumType(
+                global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.enumType_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeEnumType(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto> values)
+            {
+                base.AddRange(values, result.enumType_);
+                return this;
+            }
+
+            public Builder ClearEnumType()
+            {
+                result.enumType_.Clear();
+                return this;
+            }
+
+            public
+                pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange>
+                ExtensionRangeList
+            {
+                get { return result.extensionRange_; }
+            }
+
+            public int ExtensionRangeCount
+            {
+                get { return result.ExtensionRangeCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange
+                GetExtensionRange(int index)
+            {
+                return result.GetExtensionRange(index);
+            }
+
+            public Builder SetExtensionRange(int index,
+                                             global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.
+                                                 ExtensionRange value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.extensionRange_[index] = value;
+                return this;
+            }
+
+            public Builder SetExtensionRange(int index,
+                                             global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.
+                                                 ExtensionRange.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.extensionRange_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddExtensionRange(
+                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.extensionRange_.Add(value);
+                return this;
+            }
+
+            public Builder AddExtensionRange(
+                global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Builder
+                    builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.extensionRange_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeExtensionRange(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange>
+                    values)
+            {
+                base.AddRange(values, result.extensionRange_);
+                return this;
+            }
+
+            public Builder ClearExtensionRange()
+            {
+                result.extensionRange_.Clear();
+                return this;
+            }
+
+            public bool HasOptions
+            {
+                get { return result.HasOptions; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions Options
+            {
+                get { return result.Options; }
+                set { SetOptions(value); }
+            }
+
+            public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOptions = true;
+                result.options_ = value;
+                return this;
+            }
+
+            public Builder SetOptions(
+                global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.hasOptions = true;
+                result.options_ = builderForValue.Build();
+                return this;
+            }
+
+            public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                if (result.HasOptions &&
+                    result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance)
+                {
+                    result.options_ =
+                        global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.CreateBuilder(result.options_).
+                            MergeFrom(value).BuildPartial();
+                }
+                else
+                {
+                    result.options_ = value;
+                }
+                result.hasOptions = true;
+                return this;
+            }
+
+            public Builder ClearOptions()
+            {
+                result.hasOptions = false;
+                result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance;
+                return this;
+            }
+        }
+
+        static DescriptorProto()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    public static MethodOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+
+    public sealed partial class FieldDescriptorProto :
+        pb::GeneratedMessage<FieldDescriptorProto, FieldDescriptorProto.Builder>
+    {
+        private static readonly FieldDescriptorProto defaultInstance = new Builder().BuildPartial();
+
+        public static FieldDescriptorProto DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override FieldDescriptorProto DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override FieldDescriptorProto ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FieldDescriptorProto__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<FieldDescriptorProto, FieldDescriptorProto.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable;
+            }
+        }
+
+        #region Nested types
+
+        public static class Types
+        {
+            public enum Type
+            {
+                TYPE_DOUBLE = 1,
+                TYPE_FLOAT = 2,
+                TYPE_INT64 = 3,
+                TYPE_UINT64 = 4,
+                TYPE_INT32 = 5,
+                TYPE_FIXED64 = 6,
+                TYPE_FIXED32 = 7,
+                TYPE_BOOL = 8,
+                TYPE_STRING = 9,
+                TYPE_GROUP = 10,
+                TYPE_MESSAGE = 11,
+                TYPE_BYTES = 12,
+                TYPE_UINT32 = 13,
+                TYPE_ENUM = 14,
+                TYPE_SFIXED32 = 15,
+                TYPE_SFIXED64 = 16,
+                TYPE_SINT32 = 17,
+                TYPE_SINT64 = 18,
+            }
+
+            public enum Label
+            {
+                LABEL_OPTIONAL = 1,
+                LABEL_REQUIRED = 2,
+                LABEL_REPEATED = 3,
+            }
+        }
+
+        #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 NumberFieldNumber = 3;
+        private bool hasNumber;
+        private int number_ = 0;
+
+        public bool HasNumber
+        {
+            get { return hasNumber; }
+        }
+
+        public int Number
+        {
+            get { return number_; }
+        }
+
+        public const int LabelFieldNumber = 4;
+        private bool hasLabel;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label label_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL;
+
+        public bool HasLabel
+        {
+            get { return hasLabel; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label Label
+        {
+            get { return label_; }
+        }
+
+        public const int TypeFieldNumber = 5;
+        private bool hasType;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type type_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type.TYPE_DOUBLE;
+
+        public bool HasType
+        {
+            get { return hasType; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type Type
+        {
+            get { return type_; }
+        }
+
+        public const int TypeNameFieldNumber = 6;
+        private bool hasTypeName;
+        private string typeName_ = "";
+
+        public bool HasTypeName
+        {
+            get { return hasTypeName; }
+        }
+
+        public string TypeName
+        {
+            get { return typeName_; }
+        }
+
+        public const int ExtendeeFieldNumber = 2;
+        private bool hasExtendee;
+        private string extendee_ = "";
+
+        public bool HasExtendee
+        {
+            get { return hasExtendee; }
+        }
+
+        public string Extendee
+        {
+            get { return extendee_; }
+        }
+
+        public const int DefaultValueFieldNumber = 7;
+        private bool hasDefaultValue;
+        private string defaultValue_ = "";
+
+        public bool HasDefaultValue
+        {
+            get { return hasDefaultValue; }
+        }
+
+        public string DefaultValue
+        {
+            get { return defaultValue_; }
+        }
+
+        public const int OptionsFieldNumber = 8;
+        private bool hasOptions;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions options_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance;
+
+        public bool HasOptions
+        {
+            get { return hasOptions; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions Options
+        {
+            get { return options_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                if (HasOptions)
+                {
+                    if (!Options.IsInitialized) return false;
+                }
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasName)
+            {
+                output.WriteString(1, Name);
+            }
+            if (HasExtendee)
+            {
+                output.WriteString(2, Extendee);
+            }
+            if (HasNumber)
+            {
+                output.WriteInt32(3, Number);
+            }
+            if (HasLabel)
+            {
+                output.WriteEnum(4, (int) Label);
+            }
+            if (HasType)
+            {
+                output.WriteEnum(5, (int) Type);
+            }
+            if (HasTypeName)
+            {
+                output.WriteString(6, TypeName);
+            }
+            if (HasDefaultValue)
+            {
+                output.WriteString(7, DefaultValue);
+            }
+            if (HasOptions)
+            {
+                output.WriteMessage(8, Options);
+            }
+            UnknownFields.WriteTo(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 (HasNumber)
+                {
+                    size += pb::CodedOutputStream.ComputeInt32Size(3, Number);
+                }
+                if (HasLabel)
+                {
+                    size += pb::CodedOutputStream.ComputeEnumSize(4, (int) Label);
+                }
+                if (HasType)
+                {
+                    size += pb::CodedOutputStream.ComputeEnumSize(5, (int) Type);
+                }
+                if (HasTypeName)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(6, TypeName);
+                }
+                if (HasExtendee)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(2, Extendee);
+                }
+                if (HasDefaultValue)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(7, DefaultValue);
+                }
+                if (HasOptions)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(8, Options);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static FieldDescriptorProto ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static FieldDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static FieldDescriptorProto ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static FieldDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static FieldDescriptorProto ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static FieldDescriptorProto ParseFrom(global::System.IO.Stream input,
+                                                     pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static FieldDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static FieldDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input,
+                                                              pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static FieldDescriptorProto ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static FieldDescriptorProto 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(FieldDescriptorProto prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<FieldDescriptorProto, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private FieldDescriptorProto result = new FieldDescriptorProto();
+
+            protected override FieldDescriptorProto MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new FieldDescriptorProto();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Descriptor; }
+            }
+
+            public override FieldDescriptorProto DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.DefaultInstance; }
+            }
+
+            public override FieldDescriptorProto BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                FieldDescriptorProto returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is FieldDescriptorProto)
+                {
+                    return MergeFrom((FieldDescriptorProto) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(FieldDescriptorProto other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.DefaultInstance)
+                    return this;
+                if (other.HasName)
+                {
+                    Name = other.Name;
+                }
+                if (other.HasNumber)
+                {
+                    Number = other.Number;
+                }
+                if (other.HasLabel)
+                {
+                    Label = other.Label;
+                }
+                if (other.HasType)
+                {
+                    Type = other.Type;
+                }
+                if (other.HasTypeName)
+                {
+                    TypeName = other.TypeName;
+                }
+                if (other.HasExtendee)
+                {
+                    Extendee = other.Extendee;
+                }
+                if (other.HasDefaultValue)
+                {
+                    DefaultValue = other.DefaultValue;
+                }
+                if (other.HasOptions)
+                {
+                    MergeOptions(other.Options);
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                Name = input.ReadString();
+                                break;
+                            }
+                        case 18:
+                            {
+                                Extendee = input.ReadString();
+                                break;
+                            }
+                        case 24:
+                            {
+                                Number = input.ReadInt32();
+                                break;
+                            }
+                        case 32:
+                            {
+                                int rawValue = input.ReadEnum();
+                                if (
+                                    !global::System.Enum.IsDefined(
+                                        typeof (
+                                            global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.
+                                            Label), rawValue))
+                                {
+                                    if (unknownFields == null)
+                                    {
+                                        unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                    }
+                                    unknownFields.MergeVarintField(4, (ulong) rawValue);
+                                }
+                                else
+                                {
+                                    Label =
+                                        (
+                                        global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label
+                                        ) rawValue;
+                                }
+                                break;
+                            }
+                        case 40:
+                            {
+                                int rawValue = input.ReadEnum();
+                                if (
+                                    !global::System.Enum.IsDefined(
+                                        typeof (
+                                            global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.
+                                            Type), rawValue))
+                                {
+                                    if (unknownFields == null)
+                                    {
+                                        unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                    }
+                                    unknownFields.MergeVarintField(5, (ulong) rawValue);
+                                }
+                                else
+                                {
+                                    Type =
+                                        (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type
+                                        ) rawValue;
+                                }
+                                break;
+                            }
+                        case 50:
+                            {
+                                TypeName = input.ReadString();
+                                break;
+                            }
+                        case 58:
+                            {
+                                DefaultValue = input.ReadString();
+                                break;
+                            }
+                        case 66:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.CreateBuilder();
+                                if (HasOptions)
+                                {
+                                    subBuilder.MergeFrom(Options);
+                                }
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                Options = subBuilder.BuildPartial();
+                                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 HasNumber
+            {
+                get { return result.HasNumber; }
+            }
+
+            public int Number
+            {
+                get { return result.Number; }
+                set { SetNumber(value); }
+            }
+
+            public Builder SetNumber(int value)
+            {
+                result.hasNumber = true;
+                result.number_ = value;
+                return this;
+            }
+
+            public Builder ClearNumber()
+            {
+                result.hasNumber = false;
+                result.number_ = 0;
+                return this;
+            }
+
+            public bool HasLabel
+            {
+                get { return result.HasLabel; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label Label
+            {
+                get { return result.Label; }
+                set { SetLabel(value); }
+            }
+
+            public Builder SetLabel(
+                global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label value)
+            {
+                result.hasLabel = true;
+                result.label_ = value;
+                return this;
+            }
+
+            public Builder ClearLabel()
+            {
+                result.hasLabel = false;
+                result.label_ =
+                    global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL;
+                return this;
+            }
+
+            public bool HasType
+            {
+                get { return result.HasType; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type Type
+            {
+                get { return result.Type; }
+                set { SetType(value); }
+            }
+
+            public Builder SetType(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type value)
+            {
+                result.hasType = true;
+                result.type_ = value;
+                return this;
+            }
+
+            public Builder ClearType()
+            {
+                result.hasType = false;
+                result.type_ =
+                    global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type.TYPE_DOUBLE;
+                return this;
+            }
+
+            public bool HasTypeName
+            {
+                get { return result.HasTypeName; }
+            }
+
+            public string TypeName
+            {
+                get { return result.TypeName; }
+                set { SetTypeName(value); }
+            }
+
+            public Builder SetTypeName(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasTypeName = true;
+                result.typeName_ = value;
+                return this;
+            }
+
+            public Builder ClearTypeName()
+            {
+                result.hasTypeName = false;
+                result.typeName_ = "";
+                return this;
+            }
+
+            public bool HasExtendee
+            {
+                get { return result.HasExtendee; }
+            }
+
+            public string Extendee
+            {
+                get { return result.Extendee; }
+                set { SetExtendee(value); }
+            }
+
+            public Builder SetExtendee(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasExtendee = true;
+                result.extendee_ = value;
+                return this;
+            }
+
+            public Builder ClearExtendee()
+            {
+                result.hasExtendee = false;
+                result.extendee_ = "";
+                return this;
+            }
+
+            public bool HasDefaultValue
+            {
+                get { return result.HasDefaultValue; }
+            }
+
+            public string DefaultValue
+            {
+                get { return result.DefaultValue; }
+                set { SetDefaultValue(value); }
+            }
+
+            public Builder SetDefaultValue(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasDefaultValue = true;
+                result.defaultValue_ = value;
+                return this;
+            }
+
+            public Builder ClearDefaultValue()
+            {
+                result.hasDefaultValue = false;
+                result.defaultValue_ = "";
+                return this;
+            }
+
+            public bool HasOptions
+            {
+                get { return result.HasOptions; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions Options
+            {
+                get { return result.Options; }
+                set { SetOptions(value); }
+            }
+
+            public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOptions = true;
+                result.options_ = value;
+                return this;
+            }
+
+            public Builder SetOptions(
+                global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.hasOptions = true;
+                result.options_ = builderForValue.Build();
+                return this;
+            }
+
+            public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                if (result.HasOptions &&
+                    result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance)
+                {
+                    result.options_ =
+                        global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.CreateBuilder(result.options_).
+                            MergeFrom(value).BuildPartial();
+                }
+                else
+                {
+                    result.options_ = value;
+                }
+                result.hasOptions = true;
+                return this;
+            }
+
+            public Builder ClearOptions()
+            {
+                result.hasOptions = false;
+                result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance;
+                return this;
+            }
+        }
+
+        static FieldDescriptorProto()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    public static MethodOptions ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+
+    public sealed partial class EnumDescriptorProto :
+        pb::GeneratedMessage<EnumDescriptorProto, EnumDescriptorProto.Builder>
+    {
+        private static readonly EnumDescriptorProto defaultInstance = new Builder().BuildPartial();
+
+        public static EnumDescriptorProto DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override EnumDescriptorProto DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override EnumDescriptorProto ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_EnumDescriptorProto__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<EnumDescriptorProto, EnumDescriptorProto.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable;
+            }
+        }
+
+        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 ValueFieldNumber = 2;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto> value_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto> ValueList
+        {
+            get { return value_; }
+        }
+
+        public int ValueCount
+        {
+            get { return value_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto GetValue(int index)
+        {
+            return value_[index];
+        }
+
+        public const int OptionsFieldNumber = 3;
+        private bool hasOptions;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions options_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance;
+
+        public bool HasOptions
+        {
+            get { return hasOptions; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions Options
+        {
+            get { return options_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto element in ValueList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (HasOptions)
+                {
+                    if (!Options.IsInitialized) return false;
+                }
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasName)
+            {
+                output.WriteString(1, Name);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto element in ValueList)
+            {
+                output.WriteMessage(2, element);
+            }
+            if (HasOptions)
+            {
+                output.WriteMessage(3, Options);
+            }
+            UnknownFields.WriteTo(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);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto element in ValueList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(2, element);
+                }
+                if (HasOptions)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(3, Options);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static EnumDescriptorProto ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static EnumDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumDescriptorProto ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static EnumDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumDescriptorProto ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static EnumDescriptorProto ParseFrom(global::System.IO.Stream input,
+                                                    pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static EnumDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input,
+                                                             pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static EnumDescriptorProto ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static EnumDescriptorProto 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(EnumDescriptorProto prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<EnumDescriptorProto, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private EnumDescriptorProto result = new EnumDescriptorProto();
+
+            protected override EnumDescriptorProto MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new EnumDescriptorProto();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Descriptor; }
+            }
+
+            public override EnumDescriptorProto DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.DefaultInstance; }
+            }
+
+            public override EnumDescriptorProto BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.value_.MakeReadOnly();
+                EnumDescriptorProto returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is EnumDescriptorProto)
+                {
+                    return MergeFrom((EnumDescriptorProto) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(EnumDescriptorProto other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.DefaultInstance)
+                    return this;
+                if (other.HasName)
+                {
+                    Name = other.Name;
+                }
+                if (other.value_.Count != 0)
+                {
+                    base.AddRange(other.value_, result.value_);
+                }
+                if (other.HasOptions)
+                {
+                    MergeOptions(other.Options);
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                Name = input.ReadString();
+                                break;
+                            }
+                        case 18:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder
+                                    subBuilder =
+                                        global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.
+                                            CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddValue(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 26:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.CreateBuilder();
+                                if (HasOptions)
+                                {
+                                    subBuilder.MergeFrom(Options);
+                                }
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                Options = subBuilder.BuildPartial();
+                                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 pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto>
+                ValueList
+            {
+                get { return result.value_; }
+            }
+
+            public int ValueCount
+            {
+                get { return result.ValueCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto GetValue(int index)
+            {
+                return result.GetValue(index);
+            }
+
+            public Builder SetValue(int index,
+                                    global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.value_[index] = value;
+                return this;
+            }
+
+            public Builder SetValue(int index,
+                                    global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder
+                                        builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.value_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddValue(global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.value_.Add(value);
+                return this;
+            }
+
+            public Builder AddValue(
+                global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.value_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeValue(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto> values)
+            {
+                base.AddRange(values, result.value_);
+                return this;
+            }
+
+            public Builder ClearValue()
+            {
+                result.value_.Clear();
+                return this;
+            }
+
+            public bool HasOptions
+            {
+                get { return result.HasOptions; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions Options
+            {
+                get { return result.Options; }
+                set { SetOptions(value); }
+            }
+
+            public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOptions = true;
+                result.options_ = value;
+                return this;
+            }
+
+            public Builder SetOptions(
+                global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.hasOptions = true;
+                result.options_ = builderForValue.Build();
+                return this;
+            }
+
+            public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                if (result.HasOptions &&
+                    result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance)
+                {
+                    result.options_ =
+                        global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.CreateBuilder(result.options_).
+                            MergeFrom(value).BuildPartial();
+                }
+                else
+                {
+                    result.options_ = value;
+                }
+                result.hasOptions = true;
+                return this;
+            }
+
+            public Builder ClearOptions()
+            {
+                result.hasOptions = false;
+                result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance;
+                return this;
+            }
+        }
+
+        static EnumDescriptorProto()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    public static MethodOptions ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+
+    public sealed partial class EnumValueDescriptorProto :
+        pb::GeneratedMessage<EnumValueDescriptorProto, EnumValueDescriptorProto.Builder>
+    {
+        private static readonly EnumValueDescriptorProto defaultInstance = new Builder().BuildPartial();
+
+        public static EnumValueDescriptorProto DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override EnumValueDescriptorProto DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override EnumValueDescriptorProto ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor;
+            }
+        }
+
+        protected override
+            pb::FieldAccess.FieldAccessorTable<EnumValueDescriptorProto, EnumValueDescriptorProto.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable;
+            }
+        }
+
+        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 NumberFieldNumber = 2;
+        private bool hasNumber;
+        private int number_ = 0;
+
+        public bool HasNumber
+        {
+            get { return hasNumber; }
+        }
+
+        public int Number
+        {
+            get { return number_; }
+        }
+
+        public const int OptionsFieldNumber = 3;
+        private bool hasOptions;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions options_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance;
+
+        public bool HasOptions
+        {
+            get { return hasOptions; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions Options
+        {
+            get { return options_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                if (HasOptions)
+                {
+                    if (!Options.IsInitialized) return false;
+                }
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasName)
+            {
+                output.WriteString(1, Name);
+            }
+            if (HasNumber)
+            {
+                output.WriteInt32(2, Number);
+            }
+            if (HasOptions)
+            {
+                output.WriteMessage(3, Options);
+            }
+            UnknownFields.WriteTo(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 (HasNumber)
+                {
+                    size += pb::CodedOutputStream.ComputeInt32Size(2, Number);
+                }
+                if (HasOptions)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(3, Options);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static EnumValueDescriptorProto ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto ParseFrom(global::System.IO.Stream input,
+                                                         pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input,
+                                                                  pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static EnumValueDescriptorProto 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(EnumValueDescriptorProto prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<EnumValueDescriptorProto, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private EnumValueDescriptorProto result = new EnumValueDescriptorProto();
+
+            protected override EnumValueDescriptorProto MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new EnumValueDescriptorProto();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Descriptor; }
+            }
+
+            public override EnumValueDescriptorProto DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.DefaultInstance; }
+            }
+
+            public override EnumValueDescriptorProto BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                EnumValueDescriptorProto returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is EnumValueDescriptorProto)
+                {
+                    return MergeFrom((EnumValueDescriptorProto) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(EnumValueDescriptorProto other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.DefaultInstance)
+                    return this;
+                if (other.HasName)
+                {
+                    Name = other.Name;
+                }
+                if (other.HasNumber)
+                {
+                    Number = other.Number;
+                }
+                if (other.HasOptions)
+                {
+                    MergeOptions(other.Options);
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                Name = input.ReadString();
+                                break;
+                            }
+                        case 16:
+                            {
+                                Number = input.ReadInt32();
+                                break;
+                            }
+                        case 26:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.CreateBuilder();
+                                if (HasOptions)
+                                {
+                                    subBuilder.MergeFrom(Options);
+                                }
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                Options = subBuilder.BuildPartial();
+                                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 HasNumber
+            {
+                get { return result.HasNumber; }
+            }
+
+            public int Number
+            {
+                get { return result.Number; }
+                set { SetNumber(value); }
+            }
+
+            public Builder SetNumber(int value)
+            {
+                result.hasNumber = true;
+                result.number_ = value;
+                return this;
+            }
+
+            public Builder ClearNumber()
+            {
+                result.hasNumber = false;
+                result.number_ = 0;
+                return this;
+            }
+
+            public bool HasOptions
+            {
+                get { return result.HasOptions; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions Options
+            {
+                get { return result.Options; }
+                set { SetOptions(value); }
+            }
+
+            public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOptions = true;
+                result.options_ = value;
+                return this;
+            }
+
+            public Builder SetOptions(
+                global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.hasOptions = true;
+                result.options_ = builderForValue.Build();
+                return this;
+            }
+
+            public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                if (result.HasOptions &&
+                    result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance)
+                {
+                    result.options_ =
+                        global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.CreateBuilder(result.options_).
+                            MergeFrom(value).BuildPartial();
+                }
+                else
+                {
+                    result.options_ = value;
+                }
+                result.hasOptions = true;
+                return this;
+            }
+
+            public Builder ClearOptions()
+            {
+                result.hasOptions = false;
+                result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance;
+                return this;
+            }
+        }
+
+        static EnumValueDescriptorProto()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    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(MethodOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+
+    public sealed partial class ServiceDescriptorProto :
+        pb::GeneratedMessage<ServiceDescriptorProto, ServiceDescriptorProto.Builder>
+    {
+        private static readonly ServiceDescriptorProto defaultInstance = new Builder().BuildPartial();
+
+        public static ServiceDescriptorProto DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override ServiceDescriptorProto DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override ServiceDescriptorProto ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_ServiceDescriptorProto__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<ServiceDescriptorProto, ServiceDescriptorProto.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable;
+            }
+        }
+
+        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 MethodFieldNumber = 2;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto> method_ =
+            new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto> MethodList
+        {
+            get { return method_; }
+        }
+
+        public int MethodCount
+        {
+            get { return method_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto GetMethod(int index)
+        {
+            return method_[index];
+        }
+
+        public const int OptionsFieldNumber = 3;
+        private bool hasOptions;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions options_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance;
+
+        public bool HasOptions
+        {
+            get { return hasOptions; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions Options
+        {
+            get { return options_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto element in MethodList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (HasOptions)
+                {
+                    if (!Options.IsInitialized) return false;
+                }
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasName)
+            {
+                output.WriteString(1, Name);
+            }
+            foreach (global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto element in MethodList)
+            {
+                output.WriteMessage(2, element);
+            }
+            if (HasOptions)
+            {
+                output.WriteMessage(3, Options);
+            }
+            UnknownFields.WriteTo(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);
+                }
+                foreach (global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto element in MethodList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(2, element);
+                }
+                if (HasOptions)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(3, Options);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static ServiceDescriptorProto ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto ParseFrom(global::System.IO.Stream input,
+                                                       pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input,
+                                                                pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static ServiceDescriptorProto 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(ServiceDescriptorProto prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<ServiceDescriptorProto, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private ServiceDescriptorProto result = new ServiceDescriptorProto();
+
+            protected override ServiceDescriptorProto MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new ServiceDescriptorProto();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Descriptor; }
+            }
+
+            public override ServiceDescriptorProto DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.DefaultInstance; }
+            }
+
+            public override ServiceDescriptorProto BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.method_.MakeReadOnly();
+                ServiceDescriptorProto returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is ServiceDescriptorProto)
+                {
+                    return MergeFrom((ServiceDescriptorProto) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(ServiceDescriptorProto other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.DefaultInstance)
+                    return this;
+                if (other.HasName)
+                {
+                    Name = other.Name;
+                }
+                if (other.method_.Count != 0)
+                {
+                    base.AddRange(other.method_, result.method_);
+                }
+                if (other.HasOptions)
+                {
+                    MergeOptions(other.Options);
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                Name = input.ReadString();
+                                break;
+                            }
+                        case 18:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder subBuilder
+                                    =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddMethod(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 26:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.CreateBuilder();
+                                if (HasOptions)
+                                {
+                                    subBuilder.MergeFrom(Options);
+                                }
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                Options = subBuilder.BuildPartial();
+                                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 pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto> MethodList
+            {
+                get { return result.method_; }
+            }
+
+            public int MethodCount
+            {
+                get { return result.MethodCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto GetMethod(int index)
+            {
+                return result.GetMethod(index);
+            }
+
+            public Builder SetMethod(int index,
+                                     global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.method_[index] = value;
+                return this;
+            }
+
+            public Builder SetMethod(int index,
+                                     global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder
+                                         builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.method_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddMethod(global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.method_.Add(value);
+                return this;
+            }
+
+            public Builder AddMethod(
+                global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.method_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeMethod(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto> values)
+            {
+                base.AddRange(values, result.method_);
+                return this;
+            }
+
+            public Builder ClearMethod()
+            {
+                result.method_.Clear();
+                return this;
+            }
+
+            public bool HasOptions
+            {
+                get { return result.HasOptions; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions Options
+            {
+                get { return result.Options; }
+                set { SetOptions(value); }
+            }
+
+            public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOptions = true;
+                result.options_ = value;
+                return this;
+            }
+
+            public Builder SetOptions(
+                global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.hasOptions = true;
+                result.options_ = builderForValue.Build();
+                return this;
+            }
+
+            public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                if (result.HasOptions &&
+                    result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance)
+                {
+                    result.options_ =
+                        global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.CreateBuilder(result.options_).
+                            MergeFrom(value).BuildPartial();
+                }
+                else
+                {
+                    result.options_ = value;
+                }
+                result.hasOptions = true;
+                return this;
+            }
+
+            public Builder ClearOptions()
+            {
+                result.hasOptions = false;
+                result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance;
+                return this;
+            }
+        }
+
+        static ServiceDescriptorProto()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    
-    public sealed partial class Builder : pb::ExtendableBuilder<MethodOptions, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      MethodOptions result = new MethodOptions();
-      
-      protected override MethodOptions MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new MethodOptions();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Descriptor; }
-      }
-      
-      public override MethodOptions DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance; }
-      }
-      
-      public override MethodOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.uninterpretedOption_.MakeReadOnly();
-        MethodOptions returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is MethodOptions) {
-          return MergeFrom((MethodOptions) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(MethodOptions other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance) return this;
-        if (other.uninterpretedOption_.Count != 0) {
-          base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
-        }
-          this.MergeExtensionFields(other);
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 7994: {
-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddUninterpretedOption(subBuilder.BuildPartial());
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList {
-        get { return result.uninterpretedOption_; }
-      }
-      public int UninterpretedOptionCount {
-        get { return result.UninterpretedOptionCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index) {
-        return result.GetUninterpretedOption(index);
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_[index] = value;
-        return this;
-      }
-      public Builder SetUninterpretedOption(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.uninterpretedOption_.Add(value);
-        return this;
-      }
-      public Builder AddUninterpretedOption(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.uninterpretedOption_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeUninterpretedOption(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values) {
-        base.AddRange(values, result.uninterpretedOption_);
-        return this;
-      }
-      public Builder ClearUninterpretedOption() {
-        result.uninterpretedOption_.Clear();
-        return this;
-      }
+
+    public sealed partial class MethodDescriptorProto :
+        pb::GeneratedMessage<MethodDescriptorProto, MethodDescriptorProto.Builder>
+    {
+        private static readonly MethodDescriptorProto defaultInstance = new Builder().BuildPartial();
+
+        public static MethodDescriptorProto DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override MethodDescriptorProto DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override MethodDescriptorProto ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_MethodDescriptorProto__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<MethodDescriptorProto, MethodDescriptorProto.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable;
+            }
+        }
+
+        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 InputTypeFieldNumber = 2;
+        private bool hasInputType;
+        private string inputType_ = "";
+
+        public bool HasInputType
+        {
+            get { return hasInputType; }
+        }
+
+        public string InputType
+        {
+            get { return inputType_; }
+        }
+
+        public const int OutputTypeFieldNumber = 3;
+        private bool hasOutputType;
+        private string outputType_ = "";
+
+        public bool HasOutputType
+        {
+            get { return hasOutputType; }
+        }
+
+        public string OutputType
+        {
+            get { return outputType_; }
+        }
+
+        public const int OptionsFieldNumber = 4;
+        private bool hasOptions;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions options_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance;
+
+        public bool HasOptions
+        {
+            get { return hasOptions; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions Options
+        {
+            get { return options_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                if (HasOptions)
+                {
+                    if (!Options.IsInitialized) return false;
+                }
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            if (HasName)
+            {
+                output.WriteString(1, Name);
+            }
+            if (HasInputType)
+            {
+                output.WriteString(2, InputType);
+            }
+            if (HasOutputType)
+            {
+                output.WriteString(3, OutputType);
+            }
+            if (HasOptions)
+            {
+                output.WriteMessage(4, Options);
+            }
+            UnknownFields.WriteTo(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 (HasInputType)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(2, InputType);
+                }
+                if (HasOutputType)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(3, OutputType);
+                }
+                if (HasOptions)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(4, Options);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static MethodDescriptorProto ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static MethodDescriptorProto ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static MethodDescriptorProto ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static MethodDescriptorProto ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static MethodDescriptorProto ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static MethodDescriptorProto ParseFrom(global::System.IO.Stream input,
+                                                      pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static MethodDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static MethodDescriptorProto ParseDelimitedFrom(global::System.IO.Stream input,
+                                                               pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static MethodDescriptorProto ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static MethodDescriptorProto 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(MethodDescriptorProto prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<MethodDescriptorProto, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private MethodDescriptorProto result = new MethodDescriptorProto();
+
+            protected override MethodDescriptorProto MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new MethodDescriptorProto();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Descriptor; }
+            }
+
+            public override MethodDescriptorProto DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.DefaultInstance; }
+            }
+
+            public override MethodDescriptorProto BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                MethodDescriptorProto returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is MethodDescriptorProto)
+                {
+                    return MergeFrom((MethodDescriptorProto) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(MethodDescriptorProto other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.DefaultInstance)
+                    return this;
+                if (other.HasName)
+                {
+                    Name = other.Name;
+                }
+                if (other.HasInputType)
+                {
+                    InputType = other.InputType;
+                }
+                if (other.HasOutputType)
+                {
+                    OutputType = other.OutputType;
+                }
+                if (other.HasOptions)
+                {
+                    MergeOptions(other.Options);
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                Name = input.ReadString();
+                                break;
+                            }
+                        case 18:
+                            {
+                                InputType = input.ReadString();
+                                break;
+                            }
+                        case 26:
+                            {
+                                OutputType = input.ReadString();
+                                break;
+                            }
+                        case 34:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.CreateBuilder();
+                                if (HasOptions)
+                                {
+                                    subBuilder.MergeFrom(Options);
+                                }
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                Options = subBuilder.BuildPartial();
+                                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 HasInputType
+            {
+                get { return result.HasInputType; }
+            }
+
+            public string InputType
+            {
+                get { return result.InputType; }
+                set { SetInputType(value); }
+            }
+
+            public Builder SetInputType(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasInputType = true;
+                result.inputType_ = value;
+                return this;
+            }
+
+            public Builder ClearInputType()
+            {
+                result.hasInputType = false;
+                result.inputType_ = "";
+                return this;
+            }
+
+            public bool HasOutputType
+            {
+                get { return result.HasOutputType; }
+            }
+
+            public string OutputType
+            {
+                get { return result.OutputType; }
+                set { SetOutputType(value); }
+            }
+
+            public Builder SetOutputType(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOutputType = true;
+                result.outputType_ = value;
+                return this;
+            }
+
+            public Builder ClearOutputType()
+            {
+                result.hasOutputType = false;
+                result.outputType_ = "";
+                return this;
+            }
+
+            public bool HasOptions
+            {
+                get { return result.HasOptions; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions Options
+            {
+                get { return result.Options; }
+                set { SetOptions(value); }
+            }
+
+            public Builder SetOptions(global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasOptions = true;
+                result.options_ = value;
+                return this;
+            }
+
+            public Builder SetOptions(
+                global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.hasOptions = true;
+                result.options_ = builderForValue.Build();
+                return this;
+            }
+
+            public Builder MergeOptions(global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                if (result.HasOptions &&
+                    result.options_ != global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance)
+                {
+                    result.options_ =
+                        global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.CreateBuilder(result.options_).
+                            MergeFrom(value).BuildPartial();
+                }
+                else
+                {
+                    result.options_ = value;
+                }
+                result.hasOptions = true;
+                return this;
+            }
+
+            public Builder ClearOptions()
+            {
+                result.hasOptions = false;
+                result.options_ = global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance;
+                return this;
+            }
+        }
+
+        static MethodDescriptorProto()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    static MethodOptions() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+
+    public sealed partial class FileOptions : pb::ExtendableMessage<FileOptions, FileOptions.Builder>
+    {
+        private static readonly FileOptions defaultInstance = new Builder().BuildPartial();
+
+        public static FileOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override FileOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override FileOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FileOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<FileOptions, FileOptions.Builder> InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FileOptions__FieldAccessorTable;
+            }
+        }
+
+        #region Nested types
+
+        public static class Types
+        {
+            public enum OptimizeMode
+            {
+                SPEED = 1,
+                CODE_SIZE = 2,
+                LITE_RUNTIME = 3,
+            }
+        }
+
+        #endregion
+
+        public const int JavaPackageFieldNumber = 1;
+        private bool hasJavaPackage;
+        private string javaPackage_ = "";
+
+        public bool HasJavaPackage
+        {
+            get { return hasJavaPackage; }
+        }
+
+        public string JavaPackage
+        {
+            get { return javaPackage_; }
+        }
+
+        public const int JavaOuterClassnameFieldNumber = 8;
+        private bool hasJavaOuterClassname;
+        private string javaOuterClassname_ = "";
+
+        public bool HasJavaOuterClassname
+        {
+            get { return hasJavaOuterClassname; }
+        }
+
+        public string JavaOuterClassname
+        {
+            get { return javaOuterClassname_; }
+        }
+
+        public const int JavaMultipleFilesFieldNumber = 10;
+        private bool hasJavaMultipleFiles;
+        private bool javaMultipleFiles_ = false;
+
+        public bool HasJavaMultipleFiles
+        {
+            get { return hasJavaMultipleFiles; }
+        }
+
+        public bool JavaMultipleFiles
+        {
+            get { return javaMultipleFiles_; }
+        }
+
+        public const int OptimizeForFieldNumber = 9;
+        private bool hasOptimizeFor;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode optimizeFor_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED;
+
+        public bool HasOptimizeFor
+        {
+            get { return hasOptimizeFor; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode OptimizeFor
+        {
+            get { return optimizeFor_; }
+        }
+
+        public const int CcGenericServicesFieldNumber = 16;
+        private bool hasCcGenericServices;
+        private bool ccGenericServices_ = true;
+
+        public bool HasCcGenericServices
+        {
+            get { return hasCcGenericServices; }
+        }
+
+        public bool CcGenericServices
+        {
+            get { return ccGenericServices_; }
+        }
+
+        public const int JavaGenericServicesFieldNumber = 17;
+        private bool hasJavaGenericServices;
+        private bool javaGenericServices_ = true;
+
+        public bool HasJavaGenericServices
+        {
+            get { return hasJavaGenericServices; }
+        }
+
+        public bool JavaGenericServices
+        {
+            get { return javaGenericServices_; }
+        }
+
+        public const int PyGenericServicesFieldNumber = 18;
+        private bool hasPyGenericServices;
+        private bool pyGenericServices_ = true;
+
+        public bool HasPyGenericServices
+        {
+            get { return hasPyGenericServices; }
+        }
+
+        public bool PyGenericServices
+        {
+            get { return pyGenericServices_; }
+        }
+
+        public const int UninterpretedOptionFieldNumber = 999;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+            uninterpretedOption_ =
+                new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList
+        {
+            get { return uninterpretedOption_; }
+        }
+
+        public int UninterpretedOptionCount
+        {
+            get { return uninterpretedOption_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+        {
+            return uninterpretedOption_[index];
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (!ExtensionsAreInitialized) return false;
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            pb::ExtendableMessage<FileOptions, FileOptions.Builder>.ExtensionWriter extensionWriter =
+                CreateExtensionWriter(this);
+            if (HasJavaPackage)
+            {
+                output.WriteString(1, JavaPackage);
+            }
+            if (HasJavaOuterClassname)
+            {
+                output.WriteString(8, JavaOuterClassname);
+            }
+            if (HasOptimizeFor)
+            {
+                output.WriteEnum(9, (int) OptimizeFor);
+            }
+            if (HasJavaMultipleFiles)
+            {
+                output.WriteBool(10, JavaMultipleFiles);
+            }
+            if (HasCcGenericServices)
+            {
+                output.WriteBool(16, CcGenericServices);
+            }
+            if (HasJavaGenericServices)
+            {
+                output.WriteBool(17, JavaGenericServices);
+            }
+            if (HasPyGenericServices)
+            {
+                output.WriteBool(18, PyGenericServices);
+            }
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList)
+            {
+                output.WriteMessage(999, element);
+            }
+            extensionWriter.WriteUntil(536870912, output);
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                if (HasJavaPackage)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(1, JavaPackage);
+                }
+                if (HasJavaOuterClassname)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(8, JavaOuterClassname);
+                }
+                if (HasJavaMultipleFiles)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(10, JavaMultipleFiles);
+                }
+                if (HasOptimizeFor)
+                {
+                    size += pb::CodedOutputStream.ComputeEnumSize(9, (int) OptimizeFor);
+                }
+                if (HasCcGenericServices)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(16, CcGenericServices);
+                }
+                if (HasJavaGenericServices)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(17, JavaGenericServices);
+                }
+                if (HasPyGenericServices)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(18, PyGenericServices);
+                }
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(999, element);
+                }
+                size += ExtensionsSerializedSize;
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static FileOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static FileOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static FileOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static FileOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static FileOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static FileOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static FileOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static FileOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                     pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static FileOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static FileOptions 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(FileOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::ExtendableBuilder<FileOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private FileOptions result = new FileOptions();
+
+            protected override FileOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new FileOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Descriptor; }
+            }
+
+            public override FileOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance; }
+            }
+
+            public override FileOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.uninterpretedOption_.MakeReadOnly();
+                FileOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is FileOptions)
+                {
+                    return MergeFrom((FileOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(FileOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.DefaultInstance) return this;
+                if (other.HasJavaPackage)
+                {
+                    JavaPackage = other.JavaPackage;
+                }
+                if (other.HasJavaOuterClassname)
+                {
+                    JavaOuterClassname = other.JavaOuterClassname;
+                }
+                if (other.HasJavaMultipleFiles)
+                {
+                    JavaMultipleFiles = other.JavaMultipleFiles;
+                }
+                if (other.HasOptimizeFor)
+                {
+                    OptimizeFor = other.OptimizeFor;
+                }
+                if (other.HasCcGenericServices)
+                {
+                    CcGenericServices = other.CcGenericServices;
+                }
+                if (other.HasJavaGenericServices)
+                {
+                    JavaGenericServices = other.JavaGenericServices;
+                }
+                if (other.HasPyGenericServices)
+                {
+                    PyGenericServices = other.PyGenericServices;
+                }
+                if (other.uninterpretedOption_.Count != 0)
+                {
+                    base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
+                }
+                this.MergeExtensionFields(other);
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 10:
+                            {
+                                JavaPackage = input.ReadString();
+                                break;
+                            }
+                        case 66:
+                            {
+                                JavaOuterClassname = input.ReadString();
+                                break;
+                            }
+                        case 72:
+                            {
+                                int rawValue = input.ReadEnum();
+                                if (
+                                    !global::System.Enum.IsDefined(
+                                        typeof (
+                                            global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.
+                                            OptimizeMode), rawValue))
+                                {
+                                    if (unknownFields == null)
+                                    {
+                                        unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                    }
+                                    unknownFields.MergeVarintField(9, (ulong) rawValue);
+                                }
+                                else
+                                {
+                                    OptimizeFor =
+                                        (global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode)
+                                        rawValue;
+                                }
+                                break;
+                            }
+                        case 80:
+                            {
+                                JavaMultipleFiles = input.ReadBool();
+                                break;
+                            }
+                        case 128:
+                            {
+                                CcGenericServices = input.ReadBool();
+                                break;
+                            }
+                        case 136:
+                            {
+                                JavaGenericServices = input.ReadBool();
+                                break;
+                            }
+                        case 144:
+                            {
+                                PyGenericServices = input.ReadBool();
+                                break;
+                            }
+                        case 7994:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddUninterpretedOption(subBuilder.BuildPartial());
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public bool HasJavaPackage
+            {
+                get { return result.HasJavaPackage; }
+            }
+
+            public string JavaPackage
+            {
+                get { return result.JavaPackage; }
+                set { SetJavaPackage(value); }
+            }
+
+            public Builder SetJavaPackage(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasJavaPackage = true;
+                result.javaPackage_ = value;
+                return this;
+            }
+
+            public Builder ClearJavaPackage()
+            {
+                result.hasJavaPackage = false;
+                result.javaPackage_ = "";
+                return this;
+            }
+
+            public bool HasJavaOuterClassname
+            {
+                get { return result.HasJavaOuterClassname; }
+            }
+
+            public string JavaOuterClassname
+            {
+                get { return result.JavaOuterClassname; }
+                set { SetJavaOuterClassname(value); }
+            }
+
+            public Builder SetJavaOuterClassname(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasJavaOuterClassname = true;
+                result.javaOuterClassname_ = value;
+                return this;
+            }
+
+            public Builder ClearJavaOuterClassname()
+            {
+                result.hasJavaOuterClassname = false;
+                result.javaOuterClassname_ = "";
+                return this;
+            }
+
+            public bool HasJavaMultipleFiles
+            {
+                get { return result.HasJavaMultipleFiles; }
+            }
+
+            public bool JavaMultipleFiles
+            {
+                get { return result.JavaMultipleFiles; }
+                set { SetJavaMultipleFiles(value); }
+            }
+
+            public Builder SetJavaMultipleFiles(bool value)
+            {
+                result.hasJavaMultipleFiles = true;
+                result.javaMultipleFiles_ = value;
+                return this;
+            }
+
+            public Builder ClearJavaMultipleFiles()
+            {
+                result.hasJavaMultipleFiles = false;
+                result.javaMultipleFiles_ = false;
+                return this;
+            }
+
+            public bool HasOptimizeFor
+            {
+                get { return result.HasOptimizeFor; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode OptimizeFor
+            {
+                get { return result.OptimizeFor; }
+                set { SetOptimizeFor(value); }
+            }
+
+            public Builder SetOptimizeFor(
+                global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode value)
+            {
+                result.hasOptimizeFor = true;
+                result.optimizeFor_ = value;
+                return this;
+            }
+
+            public Builder ClearOptimizeFor()
+            {
+                result.hasOptimizeFor = false;
+                result.optimizeFor_ =
+                    global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED;
+                return this;
+            }
+
+            public bool HasCcGenericServices
+            {
+                get { return result.HasCcGenericServices; }
+            }
+
+            public bool CcGenericServices
+            {
+                get { return result.CcGenericServices; }
+                set { SetCcGenericServices(value); }
+            }
+
+            public Builder SetCcGenericServices(bool value)
+            {
+                result.hasCcGenericServices = true;
+                result.ccGenericServices_ = value;
+                return this;
+            }
+
+            public Builder ClearCcGenericServices()
+            {
+                result.hasCcGenericServices = false;
+                result.ccGenericServices_ = true;
+                return this;
+            }
+
+            public bool HasJavaGenericServices
+            {
+                get { return result.HasJavaGenericServices; }
+            }
+
+            public bool JavaGenericServices
+            {
+                get { return result.JavaGenericServices; }
+                set { SetJavaGenericServices(value); }
+            }
+
+            public Builder SetJavaGenericServices(bool value)
+            {
+                result.hasJavaGenericServices = true;
+                result.javaGenericServices_ = value;
+                return this;
+            }
+
+            public Builder ClearJavaGenericServices()
+            {
+                result.hasJavaGenericServices = false;
+                result.javaGenericServices_ = true;
+                return this;
+            }
+
+            public bool HasPyGenericServices
+            {
+                get { return result.HasPyGenericServices; }
+            }
+
+            public bool PyGenericServices
+            {
+                get { return result.PyGenericServices; }
+                set { SetPyGenericServices(value); }
+            }
+
+            public Builder SetPyGenericServices(bool value)
+            {
+                result.hasPyGenericServices = true;
+                result.pyGenericServices_ = value;
+                return this;
+            }
+
+            public Builder ClearPyGenericServices()
+            {
+                result.hasPyGenericServices = false;
+                result.pyGenericServices_ = true;
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+                UninterpretedOptionList
+            {
+                get { return result.uninterpretedOption_; }
+            }
+
+            public int UninterpretedOptionCount
+            {
+                get { return result.UninterpretedOptionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+            {
+                return result.GetUninterpretedOption(index);
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption
+                                                      value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_[index] = value;
+                return this;
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.
+                                                      Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_.Add(value);
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeUninterpretedOption(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values)
+            {
+                base.AddRange(values, result.uninterpretedOption_);
+                return this;
+            }
+
+            public Builder ClearUninterpretedOption()
+            {
+                result.uninterpretedOption_.Clear();
+                return this;
+            }
+        }
+
+        static FileOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-  }
-  
-  public sealed partial class UninterpretedOption : pb::GeneratedMessage<UninterpretedOption, UninterpretedOption.Builder> {
-    private static readonly UninterpretedOption defaultInstance = new Builder().BuildPartial();
-    public static UninterpretedOption DefaultInstance {
-      get { return defaultInstance; }
+
+    public sealed partial class MessageOptions : pb::ExtendableMessage<MessageOptions, MessageOptions.Builder>
+    {
+        private static readonly MessageOptions defaultInstance = new Builder().BuildPartial();
+
+        public static MessageOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override MessageOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override MessageOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_MessageOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<MessageOptions, MessageOptions.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_MessageOptions__FieldAccessorTable;
+            }
+        }
+
+        public const int MessageSetWireFormatFieldNumber = 1;
+        private bool hasMessageSetWireFormat;
+        private bool messageSetWireFormat_ = false;
+
+        public bool HasMessageSetWireFormat
+        {
+            get { return hasMessageSetWireFormat; }
+        }
+
+        public bool MessageSetWireFormat
+        {
+            get { return messageSetWireFormat_; }
+        }
+
+        public const int NoStandardDescriptorAccessorFieldNumber = 2;
+        private bool hasNoStandardDescriptorAccessor;
+        private bool noStandardDescriptorAccessor_ = false;
+
+        public bool HasNoStandardDescriptorAccessor
+        {
+            get { return hasNoStandardDescriptorAccessor; }
+        }
+
+        public bool NoStandardDescriptorAccessor
+        {
+            get { return noStandardDescriptorAccessor_; }
+        }
+
+        public const int UninterpretedOptionFieldNumber = 999;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+            uninterpretedOption_ =
+                new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList
+        {
+            get { return uninterpretedOption_; }
+        }
+
+        public int UninterpretedOptionCount
+        {
+            get { return uninterpretedOption_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+        {
+            return uninterpretedOption_[index];
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (!ExtensionsAreInitialized) return false;
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            pb::ExtendableMessage<MessageOptions, MessageOptions.Builder>.ExtensionWriter extensionWriter =
+                CreateExtensionWriter(this);
+            if (HasMessageSetWireFormat)
+            {
+                output.WriteBool(1, MessageSetWireFormat);
+            }
+            if (HasNoStandardDescriptorAccessor)
+            {
+                output.WriteBool(2, NoStandardDescriptorAccessor);
+            }
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList)
+            {
+                output.WriteMessage(999, element);
+            }
+            extensionWriter.WriteUntil(536870912, output);
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                if (HasMessageSetWireFormat)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(1, MessageSetWireFormat);
+                }
+                if (HasNoStandardDescriptorAccessor)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(2, NoStandardDescriptorAccessor);
+                }
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(999, element);
+                }
+                size += ExtensionsSerializedSize;
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static MessageOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static MessageOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static MessageOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static MessageOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static MessageOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static MessageOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static MessageOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static MessageOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                        pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static MessageOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static MessageOptions 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(MessageOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::ExtendableBuilder<MessageOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private MessageOptions result = new MessageOptions();
+
+            protected override MessageOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new MessageOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.Descriptor; }
+            }
+
+            public override MessageOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance; }
+            }
+
+            public override MessageOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.uninterpretedOption_.MakeReadOnly();
+                MessageOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is MessageOptions)
+                {
+                    return MergeFrom((MessageOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(MessageOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.MessageOptions.DefaultInstance)
+                    return this;
+                if (other.HasMessageSetWireFormat)
+                {
+                    MessageSetWireFormat = other.MessageSetWireFormat;
+                }
+                if (other.HasNoStandardDescriptorAccessor)
+                {
+                    NoStandardDescriptorAccessor = other.NoStandardDescriptorAccessor;
+                }
+                if (other.uninterpretedOption_.Count != 0)
+                {
+                    base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
+                }
+                this.MergeExtensionFields(other);
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 8:
+                            {
+                                MessageSetWireFormat = input.ReadBool();
+                                break;
+                            }
+                        case 16:
+                            {
+                                NoStandardDescriptorAccessor = input.ReadBool();
+                                break;
+                            }
+                        case 7994:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddUninterpretedOption(subBuilder.BuildPartial());
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public bool HasMessageSetWireFormat
+            {
+                get { return result.HasMessageSetWireFormat; }
+            }
+
+            public bool MessageSetWireFormat
+            {
+                get { return result.MessageSetWireFormat; }
+                set { SetMessageSetWireFormat(value); }
+            }
+
+            public Builder SetMessageSetWireFormat(bool value)
+            {
+                result.hasMessageSetWireFormat = true;
+                result.messageSetWireFormat_ = value;
+                return this;
+            }
+
+            public Builder ClearMessageSetWireFormat()
+            {
+                result.hasMessageSetWireFormat = false;
+                result.messageSetWireFormat_ = false;
+                return this;
+            }
+
+            public bool HasNoStandardDescriptorAccessor
+            {
+                get { return result.HasNoStandardDescriptorAccessor; }
+            }
+
+            public bool NoStandardDescriptorAccessor
+            {
+                get { return result.NoStandardDescriptorAccessor; }
+                set { SetNoStandardDescriptorAccessor(value); }
+            }
+
+            public Builder SetNoStandardDescriptorAccessor(bool value)
+            {
+                result.hasNoStandardDescriptorAccessor = true;
+                result.noStandardDescriptorAccessor_ = value;
+                return this;
+            }
+
+            public Builder ClearNoStandardDescriptorAccessor()
+            {
+                result.hasNoStandardDescriptorAccessor = false;
+                result.noStandardDescriptorAccessor_ = false;
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+                UninterpretedOptionList
+            {
+                get { return result.uninterpretedOption_; }
+            }
+
+            public int UninterpretedOptionCount
+            {
+                get { return result.UninterpretedOptionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+            {
+                return result.GetUninterpretedOption(index);
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption
+                                                      value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_[index] = value;
+                return this;
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.
+                                                      Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_.Add(value);
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeUninterpretedOption(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values)
+            {
+                base.AddRange(values, result.uninterpretedOption_);
+                return this;
+            }
+
+            public Builder ClearUninterpretedOption()
+            {
+                result.uninterpretedOption_.Clear();
+                return this;
+            }
+        }
+
+        static MessageOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    
-    public override UninterpretedOption DefaultInstanceForType {
-      get { return defaultInstance; }
+
+    public sealed partial class FieldOptions : pb::ExtendableMessage<FieldOptions, FieldOptions.Builder>
+    {
+        private static readonly FieldOptions defaultInstance = new Builder().BuildPartial();
+
+        public static FieldOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override FieldOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override FieldOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FieldOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<FieldOptions, FieldOptions.Builder> InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_FieldOptions__FieldAccessorTable;
+            }
+        }
+
+        #region Nested types
+
+        public static class Types
+        {
+            public enum CType
+            {
+                STRING = 0,
+                CORD = 1,
+                STRING_PIECE = 2,
+            }
+        }
+
+        #endregion
+
+        public const int CtypeFieldNumber = 1;
+        private bool hasCtype;
+
+        private global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType ctype_ =
+            global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType.STRING;
+
+        public bool HasCtype
+        {
+            get { return hasCtype; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType Ctype
+        {
+            get { return ctype_; }
+        }
+
+        public const int PackedFieldNumber = 2;
+        private bool hasPacked;
+        private bool packed_ = false;
+
+        public bool HasPacked
+        {
+            get { return hasPacked; }
+        }
+
+        public bool Packed
+        {
+            get { return packed_; }
+        }
+
+        public const int DeprecatedFieldNumber = 3;
+        private bool hasDeprecated;
+        private bool deprecated_ = false;
+
+        public bool HasDeprecated
+        {
+            get { return hasDeprecated; }
+        }
+
+        public bool Deprecated
+        {
+            get { return deprecated_; }
+        }
+
+        public const int ExperimentalMapKeyFieldNumber = 9;
+        private bool hasExperimentalMapKey;
+        private string experimentalMapKey_ = "";
+
+        public bool HasExperimentalMapKey
+        {
+            get { return hasExperimentalMapKey; }
+        }
+
+        public string ExperimentalMapKey
+        {
+            get { return experimentalMapKey_; }
+        }
+
+        public const int UninterpretedOptionFieldNumber = 999;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+            uninterpretedOption_ =
+                new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList
+        {
+            get { return uninterpretedOption_; }
+        }
+
+        public int UninterpretedOptionCount
+        {
+            get { return uninterpretedOption_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+        {
+            return uninterpretedOption_[index];
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (!ExtensionsAreInitialized) return false;
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            pb::ExtendableMessage<FieldOptions, FieldOptions.Builder>.ExtensionWriter extensionWriter =
+                CreateExtensionWriter(this);
+            if (HasCtype)
+            {
+                output.WriteEnum(1, (int) Ctype);
+            }
+            if (HasPacked)
+            {
+                output.WriteBool(2, Packed);
+            }
+            if (HasDeprecated)
+            {
+                output.WriteBool(3, Deprecated);
+            }
+            if (HasExperimentalMapKey)
+            {
+                output.WriteString(9, ExperimentalMapKey);
+            }
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList)
+            {
+                output.WriteMessage(999, element);
+            }
+            extensionWriter.WriteUntil(536870912, output);
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                if (HasCtype)
+                {
+                    size += pb::CodedOutputStream.ComputeEnumSize(1, (int) Ctype);
+                }
+                if (HasPacked)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(2, Packed);
+                }
+                if (HasDeprecated)
+                {
+                    size += pb::CodedOutputStream.ComputeBoolSize(3, Deprecated);
+                }
+                if (HasExperimentalMapKey)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(9, ExperimentalMapKey);
+                }
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(999, element);
+                }
+                size += ExtensionsSerializedSize;
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static FieldOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static FieldOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static FieldOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static FieldOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static FieldOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static FieldOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static FieldOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static FieldOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                      pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static FieldOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static FieldOptions 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(FieldOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::ExtendableBuilder<FieldOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private FieldOptions result = new FieldOptions();
+
+            protected override FieldOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new FieldOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Descriptor; }
+            }
+
+            public override FieldOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance; }
+            }
+
+            public override FieldOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.uninterpretedOption_.MakeReadOnly();
+                FieldOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is FieldOptions)
+                {
+                    return MergeFrom((FieldOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(FieldOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.DefaultInstance) return this;
+                if (other.HasCtype)
+                {
+                    Ctype = other.Ctype;
+                }
+                if (other.HasPacked)
+                {
+                    Packed = other.Packed;
+                }
+                if (other.HasDeprecated)
+                {
+                    Deprecated = other.Deprecated;
+                }
+                if (other.HasExperimentalMapKey)
+                {
+                    ExperimentalMapKey = other.ExperimentalMapKey;
+                }
+                if (other.uninterpretedOption_.Count != 0)
+                {
+                    base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
+                }
+                this.MergeExtensionFields(other);
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 8:
+                            {
+                                int rawValue = input.ReadEnum();
+                                if (
+                                    !global::System.Enum.IsDefined(
+                                        typeof (global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType
+                                            ), rawValue))
+                                {
+                                    if (unknownFields == null)
+                                    {
+                                        unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                    }
+                                    unknownFields.MergeVarintField(1, (ulong) rawValue);
+                                }
+                                else
+                                {
+                                    Ctype =
+                                        (global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType)
+                                        rawValue;
+                                }
+                                break;
+                            }
+                        case 16:
+                            {
+                                Packed = input.ReadBool();
+                                break;
+                            }
+                        case 24:
+                            {
+                                Deprecated = input.ReadBool();
+                                break;
+                            }
+                        case 74:
+                            {
+                                ExperimentalMapKey = input.ReadString();
+                                break;
+                            }
+                        case 7994:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddUninterpretedOption(subBuilder.BuildPartial());
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public bool HasCtype
+            {
+                get { return result.HasCtype; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType Ctype
+            {
+                get { return result.Ctype; }
+                set { SetCtype(value); }
+            }
+
+            public Builder SetCtype(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType value)
+            {
+                result.hasCtype = true;
+                result.ctype_ = value;
+                return this;
+            }
+
+            public Builder ClearCtype()
+            {
+                result.hasCtype = false;
+                result.ctype_ = global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType.STRING;
+                return this;
+            }
+
+            public bool HasPacked
+            {
+                get { return result.HasPacked; }
+            }
+
+            public bool Packed
+            {
+                get { return result.Packed; }
+                set { SetPacked(value); }
+            }
+
+            public Builder SetPacked(bool value)
+            {
+                result.hasPacked = true;
+                result.packed_ = value;
+                return this;
+            }
+
+            public Builder ClearPacked()
+            {
+                result.hasPacked = false;
+                result.packed_ = false;
+                return this;
+            }
+
+            public bool HasDeprecated
+            {
+                get { return result.HasDeprecated; }
+            }
+
+            public bool Deprecated
+            {
+                get { return result.Deprecated; }
+                set { SetDeprecated(value); }
+            }
+
+            public Builder SetDeprecated(bool value)
+            {
+                result.hasDeprecated = true;
+                result.deprecated_ = value;
+                return this;
+            }
+
+            public Builder ClearDeprecated()
+            {
+                result.hasDeprecated = false;
+                result.deprecated_ = false;
+                return this;
+            }
+
+            public bool HasExperimentalMapKey
+            {
+                get { return result.HasExperimentalMapKey; }
+            }
+
+            public string ExperimentalMapKey
+            {
+                get { return result.ExperimentalMapKey; }
+                set { SetExperimentalMapKey(value); }
+            }
+
+            public Builder SetExperimentalMapKey(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasExperimentalMapKey = true;
+                result.experimentalMapKey_ = value;
+                return this;
+            }
+
+            public Builder ClearExperimentalMapKey()
+            {
+                result.hasExperimentalMapKey = false;
+                result.experimentalMapKey_ = "";
+                return this;
+            }
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+                UninterpretedOptionList
+            {
+                get { return result.uninterpretedOption_; }
+            }
+
+            public int UninterpretedOptionCount
+            {
+                get { return result.UninterpretedOptionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+            {
+                return result.GetUninterpretedOption(index);
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption
+                                                      value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_[index] = value;
+                return this;
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.
+                                                      Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_.Add(value);
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeUninterpretedOption(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values)
+            {
+                base.AddRange(values, result.uninterpretedOption_);
+                return this;
+            }
+
+            public Builder ClearUninterpretedOption()
+            {
+                result.uninterpretedOption_.Clear();
+                return this;
+            }
+        }
+
+        static FieldOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    
-    protected override UninterpretedOption ThisMessage {
-      get { return this; }
+
+    public sealed partial class EnumOptions : pb::ExtendableMessage<EnumOptions, EnumOptions.Builder>
+    {
+        private static readonly EnumOptions defaultInstance = new Builder().BuildPartial();
+
+        public static EnumOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override EnumOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override EnumOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_EnumOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<EnumOptions, EnumOptions.Builder> InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_EnumOptions__FieldAccessorTable;
+            }
+        }
+
+        public const int UninterpretedOptionFieldNumber = 999;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+            uninterpretedOption_ =
+                new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList
+        {
+            get { return uninterpretedOption_; }
+        }
+
+        public int UninterpretedOptionCount
+        {
+            get { return uninterpretedOption_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+        {
+            return uninterpretedOption_[index];
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (!ExtensionsAreInitialized) return false;
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            pb::ExtendableMessage<EnumOptions, EnumOptions.Builder>.ExtensionWriter extensionWriter =
+                CreateExtensionWriter(this);
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList)
+            {
+                output.WriteMessage(999, element);
+            }
+            extensionWriter.WriteUntil(536870912, output);
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(999, element);
+                }
+                size += ExtensionsSerializedSize;
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static EnumOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static EnumOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static EnumOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static EnumOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static EnumOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                     pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static EnumOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static EnumOptions 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(EnumOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::ExtendableBuilder<EnumOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private EnumOptions result = new EnumOptions();
+
+            protected override EnumOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new EnumOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.Descriptor; }
+            }
+
+            public override EnumOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance; }
+            }
+
+            public override EnumOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.uninterpretedOption_.MakeReadOnly();
+                EnumOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is EnumOptions)
+                {
+                    return MergeFrom((EnumOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(EnumOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.EnumOptions.DefaultInstance) return this;
+                if (other.uninterpretedOption_.Count != 0)
+                {
+                    base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
+                }
+                this.MergeExtensionFields(other);
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 7994:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddUninterpretedOption(subBuilder.BuildPartial());
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+                UninterpretedOptionList
+            {
+                get { return result.uninterpretedOption_; }
+            }
+
+            public int UninterpretedOptionCount
+            {
+                get { return result.UninterpretedOptionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+            {
+                return result.GetUninterpretedOption(index);
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption
+                                                      value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_[index] = value;
+                return this;
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.
+                                                      Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_.Add(value);
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeUninterpretedOption(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values)
+            {
+                base.AddRange(values, result.uninterpretedOption_);
+                return this;
+            }
+
+            public Builder ClearUninterpretedOption()
+            {
+                result.uninterpretedOption_.Clear();
+                return this;
+            }
+        }
+
+        static EnumOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_UninterpretedOption__Descriptor; }
+
+    public sealed partial class EnumValueOptions : pb::ExtendableMessage<EnumValueOptions, EnumValueOptions.Builder>
+    {
+        private static readonly EnumValueOptions defaultInstance = new Builder().BuildPartial();
+
+        public static EnumValueOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override EnumValueOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override EnumValueOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_EnumValueOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<EnumValueOptions, EnumValueOptions.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable;
+            }
+        }
+
+        public const int UninterpretedOptionFieldNumber = 999;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+            uninterpretedOption_ =
+                new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList
+        {
+            get { return uninterpretedOption_; }
+        }
+
+        public int UninterpretedOptionCount
+        {
+            get { return uninterpretedOption_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+        {
+            return uninterpretedOption_[index];
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (!ExtensionsAreInitialized) return false;
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            pb::ExtendableMessage<EnumValueOptions, EnumValueOptions.Builder>.ExtensionWriter extensionWriter =
+                CreateExtensionWriter(this);
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList)
+            {
+                output.WriteMessage(999, element);
+            }
+            extensionWriter.WriteUntil(536870912, output);
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(999, element);
+                }
+                size += ExtensionsSerializedSize;
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static EnumValueOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static EnumValueOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumValueOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static EnumValueOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumValueOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static EnumValueOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static EnumValueOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static EnumValueOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                          pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static EnumValueOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static EnumValueOptions 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(EnumValueOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::ExtendableBuilder<EnumValueOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private EnumValueOptions result = new EnumValueOptions();
+
+            protected override EnumValueOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new EnumValueOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.Descriptor; }
+            }
+
+            public override EnumValueOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance; }
+            }
+
+            public override EnumValueOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.uninterpretedOption_.MakeReadOnly();
+                EnumValueOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is EnumValueOptions)
+                {
+                    return MergeFrom((EnumValueOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(EnumValueOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.EnumValueOptions.DefaultInstance)
+                    return this;
+                if (other.uninterpretedOption_.Count != 0)
+                {
+                    base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
+                }
+                this.MergeExtensionFields(other);
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 7994:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddUninterpretedOption(subBuilder.BuildPartial());
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+                UninterpretedOptionList
+            {
+                get { return result.uninterpretedOption_; }
+            }
+
+            public int UninterpretedOptionCount
+            {
+                get { return result.UninterpretedOptionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+            {
+                return result.GetUninterpretedOption(index);
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption
+                                                      value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_[index] = value;
+                return this;
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.
+                                                      Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_.Add(value);
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeUninterpretedOption(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values)
+            {
+                base.AddRange(values, result.uninterpretedOption_);
+                return this;
+            }
+
+            public Builder ClearUninterpretedOption()
+            {
+                result.uninterpretedOption_.Clear();
+                return this;
+            }
+        }
+
+        static EnumValueOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    
-    protected override pb::FieldAccess.FieldAccessorTable<UninterpretedOption, UninterpretedOption.Builder> InternalFieldAccessors {
-      get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable; }
+
+    public sealed partial class ServiceOptions : pb::ExtendableMessage<ServiceOptions, ServiceOptions.Builder>
+    {
+        private static readonly ServiceOptions defaultInstance = new Builder().BuildPartial();
+
+        public static ServiceOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override ServiceOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override ServiceOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_ServiceOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<ServiceOptions, ServiceOptions.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_ServiceOptions__FieldAccessorTable;
+            }
+        }
+
+        public const int UninterpretedOptionFieldNumber = 999;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+            uninterpretedOption_ =
+                new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList
+        {
+            get { return uninterpretedOption_; }
+        }
+
+        public int UninterpretedOptionCount
+        {
+            get { return uninterpretedOption_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+        {
+            return uninterpretedOption_[index];
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (!ExtensionsAreInitialized) return false;
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            pb::ExtendableMessage<ServiceOptions, ServiceOptions.Builder>.ExtensionWriter extensionWriter =
+                CreateExtensionWriter(this);
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList)
+            {
+                output.WriteMessage(999, element);
+            }
+            extensionWriter.WriteUntil(536870912, output);
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(999, element);
+                }
+                size += ExtensionsSerializedSize;
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static ServiceOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static ServiceOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static ServiceOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static ServiceOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static ServiceOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static ServiceOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static ServiceOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static ServiceOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                        pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static ServiceOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static ServiceOptions 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(ServiceOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::ExtendableBuilder<ServiceOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private ServiceOptions result = new ServiceOptions();
+
+            protected override ServiceOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new ServiceOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.Descriptor; }
+            }
+
+            public override ServiceOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance; }
+            }
+
+            public override ServiceOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.uninterpretedOption_.MakeReadOnly();
+                ServiceOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is ServiceOptions)
+                {
+                    return MergeFrom((ServiceOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(ServiceOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.ServiceOptions.DefaultInstance)
+                    return this;
+                if (other.uninterpretedOption_.Count != 0)
+                {
+                    base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
+                }
+                this.MergeExtensionFields(other);
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 7994:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddUninterpretedOption(subBuilder.BuildPartial());
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+                UninterpretedOptionList
+            {
+                get { return result.uninterpretedOption_; }
+            }
+
+            public int UninterpretedOptionCount
+            {
+                get { return result.UninterpretedOptionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+            {
+                return result.GetUninterpretedOption(index);
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption
+                                                      value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_[index] = value;
+                return this;
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.
+                                                      Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_.Add(value);
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeUninterpretedOption(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values)
+            {
+                base.AddRange(values, result.uninterpretedOption_);
+                return this;
+            }
+
+            public Builder ClearUninterpretedOption()
+            {
+                result.uninterpretedOption_.Clear();
+                return this;
+            }
+        }
+
+        static ServiceOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
-    
-    #region Nested types
-    public static class Types {
-      public sealed partial class NamePart : pb::GeneratedMessage<NamePart, NamePart.Builder> {
-        private static readonly NamePart defaultInstance = new Builder().BuildPartial();
-        public static NamePart DefaultInstance {
-          get { return defaultInstance; }
-        }
-        
-        public override NamePart DefaultInstanceForType {
-          get { return defaultInstance; }
-        }
-        
-        protected override NamePart ThisMessage {
-          get { return this; }
-        }
-        
-        public static pbd::MessageDescriptor Descriptor {
-          get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor; }
-        }
-        
-        protected override pb::FieldAccess.FieldAccessorTable<NamePart, NamePart.Builder> InternalFieldAccessors {
-          get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_UninterpretedOption_NamePart__FieldAccessorTable; }
-        }
-        
-        public const int NamePart_FieldNumber = 1;
-        private bool hasNamePart_;
-        private string namePart_ = "";
-        public bool HasNamePart_ {
-          get { return hasNamePart_; }
-        }
-        public string NamePart_ {
-          get { return namePart_; }
-        }
-        
-        public const int IsExtensionFieldNumber = 2;
-        private bool hasIsExtension;
-        private bool isExtension_ = false;
-        public bool HasIsExtension {
-          get { return hasIsExtension; }
-        }
-        public bool IsExtension {
-          get { return isExtension_; }
-        }
-        
-        public override bool IsInitialized {
-          get {
-            if (!hasNamePart_) return false;
-            if (!hasIsExtension) return false;
-            return true;
-          }
-        }
-        
-        public override void WriteTo(pb::CodedOutputStream output) {
-          int size = SerializedSize;
-          if (HasNamePart_) {
-            output.WriteString(1, NamePart_);
-          }
-          if (HasIsExtension) {
-            output.WriteBool(2, IsExtension);
-          }
-          UnknownFields.WriteTo(output);
-        }
-        
+
+    public sealed partial class MethodOptions : pb::ExtendableMessage<MethodOptions, MethodOptions.Builder>
+    {
+        private static readonly MethodOptions defaultInstance = new Builder().BuildPartial();
+
+        public static MethodOptions DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override MethodOptions DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override MethodOptions ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_MethodOptions__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<MethodOptions, MethodOptions.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_MethodOptions__FieldAccessorTable;
+            }
+        }
+
+        public const int UninterpretedOptionFieldNumber = 999;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+            uninterpretedOption_ =
+                new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> UninterpretedOptionList
+        {
+            get { return uninterpretedOption_; }
+        }
+
+        public int UninterpretedOptionCount
+        {
+            get { return uninterpretedOption_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+        {
+            return uninterpretedOption_[index];
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                if (!ExtensionsAreInitialized) return false;
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            pb::ExtendableMessage<MethodOptions, MethodOptions.Builder>.ExtensionWriter extensionWriter =
+                CreateExtensionWriter(this);
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in UninterpretedOptionList)
+            {
+                output.WriteMessage(999, element);
+            }
+            extensionWriter.WriteUntil(536870912, output);
+            UnknownFields.WriteTo(output);
+        }
+
         private int memoizedSerializedSize = -1;
-        public override int SerializedSize {
-          get {
-            int size = memoizedSerializedSize;
-            if (size != -1) return size;
-            
-            size = 0;
-            if (HasNamePart_) {
-              size += pb::CodedOutputStream.ComputeStringSize(1, NamePart_);
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption element in
+                        UninterpretedOptionList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(999, element);
+                }
+                size += ExtensionsSerializedSize;
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
+            }
+        }
+
+        public static MethodOptions ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static MethodOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static MethodOptions ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static MethodOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static MethodOptions ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static MethodOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+        }
+
+        public static MethodOptions ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+        }
+
+        public static MethodOptions ParseDelimitedFrom(global::System.IO.Stream input,
+                                                       pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+        }
+
+        public static MethodOptions ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+        }
+
+        public static MethodOptions 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(MethodOptions prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
+        }
+
+        public sealed partial class Builder : pb::ExtendableBuilder<MethodOptions, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private MethodOptions result = new MethodOptions();
+
+            protected override MethodOptions MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new MethodOptions();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.Descriptor; }
+            }
+
+            public override MethodOptions DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance; }
+            }
+
+            public override MethodOptions BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.uninterpretedOption_.MakeReadOnly();
+                MethodOptions returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is MethodOptions)
+                {
+                    return MergeFrom((MethodOptions) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(MethodOptions other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.MethodOptions.DefaultInstance) return this;
+                if (other.uninterpretedOption_.Count != 0)
+                {
+                    base.AddRange(other.uninterpretedOption_, result.uninterpretedOption_);
+                }
+                this.MergeExtensionFields(other);
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 7994:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder =
+                                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddUninterpretedOption(subBuilder.BuildPartial());
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption>
+                UninterpretedOptionList
+            {
+                get { return result.uninterpretedOption_; }
+            }
+
+            public int UninterpretedOptionCount
+            {
+                get { return result.UninterpretedOptionCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption GetUninterpretedOption(int index)
+            {
+                return result.GetUninterpretedOption(index);
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption
+                                                      value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_[index] = value;
+                return this;
+            }
+
+            public Builder SetUninterpretedOption(int index,
+                                                  global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.
+                                                      Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.uninterpretedOption_.Add(value);
+                return this;
+            }
+
+            public Builder AddUninterpretedOption(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.uninterpretedOption_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeUninterpretedOption(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption> values)
+            {
+                base.AddRange(values, result.uninterpretedOption_);
+                return this;
+            }
+
+            public Builder ClearUninterpretedOption()
+            {
+                result.uninterpretedOption_.Clear();
+                return this;
+            }
+        }
+
+        static MethodOptions()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
+    }
+
+    public sealed partial class UninterpretedOption :
+        pb::GeneratedMessage<UninterpretedOption, UninterpretedOption.Builder>
+    {
+        private static readonly UninterpretedOption defaultInstance = new Builder().BuildPartial();
+
+        public static UninterpretedOption DefaultInstance
+        {
+            get { return defaultInstance; }
+        }
+
+        public override UninterpretedOption DefaultInstanceForType
+        {
+            get { return defaultInstance; }
+        }
+
+        protected override UninterpretedOption ThisMessage
+        {
+            get { return this; }
+        }
+
+        public static pbd::MessageDescriptor Descriptor
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_UninterpretedOption__Descriptor;
+            }
+        }
+
+        protected override pb::FieldAccess.FieldAccessorTable<UninterpretedOption, UninterpretedOption.Builder>
+            InternalFieldAccessors
+        {
+            get
+            {
+                return
+                    global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                        internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable;
+            }
+        }
+
+        #region Nested types
+
+        public static class Types
+        {
+            public sealed partial class NamePart : pb::GeneratedMessage<NamePart, NamePart.Builder>
+            {
+                private static readonly NamePart defaultInstance = new Builder().BuildPartial();
+
+                public static NamePart DefaultInstance
+                {
+                    get { return defaultInstance; }
+                }
+
+                public override NamePart DefaultInstanceForType
+                {
+                    get { return defaultInstance; }
+                }
+
+                protected override NamePart ThisMessage
+                {
+                    get { return this; }
+                }
+
+                public static pbd::MessageDescriptor Descriptor
+                {
+                    get
+                    {
+                        return
+                            global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                                internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor;
+                    }
+                }
+
+                protected override pb::FieldAccess.FieldAccessorTable<NamePart, NamePart.Builder> InternalFieldAccessors
+                {
+                    get
+                    {
+                        return
+                            global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.
+                                internal__static_google_protobuf_UninterpretedOption_NamePart__FieldAccessorTable;
+                    }
+                }
+
+                public const int NamePart_FieldNumber = 1;
+                private bool hasNamePart_;
+                private string namePart_ = "";
+
+                public bool HasNamePart_
+                {
+                    get { return hasNamePart_; }
+                }
+
+                public string NamePart_
+                {
+                    get { return namePart_; }
+                }
+
+                public const int IsExtensionFieldNumber = 2;
+                private bool hasIsExtension;
+                private bool isExtension_ = false;
+
+                public bool HasIsExtension
+                {
+                    get { return hasIsExtension; }
+                }
+
+                public bool IsExtension
+                {
+                    get { return isExtension_; }
+                }
+
+                public override bool IsInitialized
+                {
+                    get
+                    {
+                        if (!hasNamePart_) return false;
+                        if (!hasIsExtension) return false;
+                        return true;
+                    }
+                }
+
+                public override void WriteTo(pb::CodedOutputStream output)
+                {
+                    int size = SerializedSize;
+                    if (HasNamePart_)
+                    {
+                        output.WriteString(1, NamePart_);
+                    }
+                    if (HasIsExtension)
+                    {
+                        output.WriteBool(2, IsExtension);
+                    }
+                    UnknownFields.WriteTo(output);
+                }
+
+                private int memoizedSerializedSize = -1;
+
+                public override int SerializedSize
+                {
+                    get
+                    {
+                        int size = memoizedSerializedSize;
+                        if (size != -1) return size;
+
+                        size = 0;
+                        if (HasNamePart_)
+                        {
+                            size += pb::CodedOutputStream.ComputeStringSize(1, NamePart_);
+                        }
+                        if (HasIsExtension)
+                        {
+                            size += pb::CodedOutputStream.ComputeBoolSize(2, IsExtension);
+                        }
+                        size += UnknownFields.SerializedSize;
+                        memoizedSerializedSize = size;
+                        return size;
+                    }
+                }
+
+                public static NamePart ParseFrom(pb::ByteString data)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+                }
+
+                public static NamePart ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+                }
+
+                public static NamePart ParseFrom(byte[] data)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+                }
+
+                public static NamePart ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+                }
+
+                public static NamePart ParseFrom(global::System.IO.Stream input)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+                }
+
+                public static NamePart ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+                }
+
+                public static NamePart ParseDelimitedFrom(global::System.IO.Stream input)
+                {
+                    return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+                }
+
+                public static NamePart ParseDelimitedFrom(global::System.IO.Stream input,
+                                                          pb::ExtensionRegistry extensionRegistry)
+                {
+                    return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+                }
+
+                public static NamePart ParseFrom(pb::CodedInputStream input)
+                {
+                    return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+                }
+
+                public static NamePart 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(NamePart prototype)
+                {
+                    return (Builder) new Builder().MergeFrom(prototype);
+                }
+
+                public sealed partial class Builder : pb::GeneratedBuilder<NamePart, Builder>
+                {
+                    protected override Builder ThisBuilder
+                    {
+                        get { return this; }
+                    }
+
+                    public Builder()
+                    {
+                    }
+
+                    private NamePart result = new NamePart();
+
+                    protected override NamePart MessageBeingBuilt
+                    {
+                        get { return result; }
+                    }
+
+                    public override Builder Clear()
+                    {
+                        result = new NamePart();
+                        return this;
+                    }
+
+                    public override Builder Clone()
+                    {
+                        return new Builder().MergeFrom(result);
+                    }
+
+                    public override pbd::MessageDescriptor DescriptorForType
+                    {
+                        get
+                        {
+                            return
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.
+                                    Descriptor;
+                        }
+                    }
+
+                    public override NamePart DefaultInstanceForType
+                    {
+                        get
+                        {
+                            return
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.
+                                    DefaultInstance;
+                        }
+                    }
+
+                    public override NamePart BuildPartial()
+                    {
+                        if (result == null)
+                        {
+                            throw new global::System.InvalidOperationException(
+                                "build() has already been called on this Builder");
+                        }
+                        NamePart returnMe = result;
+                        result = null;
+                        return returnMe;
+                    }
+
+                    public override Builder MergeFrom(pb::IMessage other)
+                    {
+                        if (other is NamePart)
+                        {
+                            return MergeFrom((NamePart) other);
+                        }
+                        else
+                        {
+                            base.MergeFrom(other);
+                            return this;
+                        }
+                    }
+
+                    public override Builder MergeFrom(NamePart other)
+                    {
+                        if (other ==
+                            global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.
+                                DefaultInstance) return this;
+                        if (other.HasNamePart_)
+                        {
+                            NamePart_ = other.NamePart_;
+                        }
+                        if (other.HasIsExtension)
+                        {
+                            IsExtension = other.IsExtension;
+                        }
+                        this.MergeUnknownFields(other.UnknownFields);
+                        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)
+                    {
+                        pb::UnknownFieldSet.Builder unknownFields = null;
+                        while (true)
+                        {
+                            uint tag = input.ReadTag();
+                            switch (tag)
+                            {
+                                case 0:
+                                    {
+                                        if (unknownFields != null)
+                                        {
+                                            this.UnknownFields = unknownFields.Build();
+                                        }
+                                        return this;
+                                    }
+                                default:
+                                    {
+                                        if (pb::WireFormat.IsEndGroupTag(tag))
+                                        {
+                                            if (unknownFields != null)
+                                            {
+                                                this.UnknownFields = unknownFields.Build();
+                                            }
+                                            return this;
+                                        }
+                                        if (unknownFields == null)
+                                        {
+                                            unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                        }
+                                        ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                        break;
+                                    }
+                                case 10:
+                                    {
+                                        NamePart_ = input.ReadString();
+                                        break;
+                                    }
+                                case 16:
+                                    {
+                                        IsExtension = input.ReadBool();
+                                        break;
+                                    }
+                            }
+                        }
+                    }
+
+
+                    public bool HasNamePart_
+                    {
+                        get { return result.HasNamePart_; }
+                    }
+
+                    public string NamePart_
+                    {
+                        get { return result.NamePart_; }
+                        set { SetNamePart_(value); }
+                    }
+
+                    public Builder SetNamePart_(string value)
+                    {
+                        pb::ThrowHelper.ThrowIfNull(value, "value");
+                        result.hasNamePart_ = true;
+                        result.namePart_ = value;
+                        return this;
+                    }
+
+                    public Builder ClearNamePart_()
+                    {
+                        result.hasNamePart_ = false;
+                        result.namePart_ = "";
+                        return this;
+                    }
+
+                    public bool HasIsExtension
+                    {
+                        get { return result.HasIsExtension; }
+                    }
+
+                    public bool IsExtension
+                    {
+                        get { return result.IsExtension; }
+                        set { SetIsExtension(value); }
+                    }
+
+                    public Builder SetIsExtension(bool value)
+                    {
+                        result.hasIsExtension = true;
+                        result.isExtension_ = value;
+                        return this;
+                    }
+
+                    public Builder ClearIsExtension()
+                    {
+                        result.hasIsExtension = false;
+                        result.isExtension_ = false;
+                        return this;
+                    }
+                }
+
+                static NamePart()
+                {
+                    object.ReferenceEquals(
+                        global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+                }
+            }
+        }
+
+        #endregion
+
+        public const int NameFieldNumber = 2;
+
+        private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart>
+            name_ =
+                new pbc::PopsicleList
+                    <global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart>();
+
+        public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart> NameList
+        {
+            get { return name_; }
+        }
+
+        public int NameCount
+        {
+            get { return name_.Count; }
+        }
+
+        public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart GetName(int index)
+        {
+            return name_[index];
+        }
+
+        public const int IdentifierValueFieldNumber = 3;
+        private bool hasIdentifierValue;
+        private string identifierValue_ = "";
+
+        public bool HasIdentifierValue
+        {
+            get { return hasIdentifierValue; }
+        }
+
+        public string IdentifierValue
+        {
+            get { return identifierValue_; }
+        }
+
+        public const int PositiveIntValueFieldNumber = 4;
+        private bool hasPositiveIntValue;
+        private ulong positiveIntValue_ = 0UL;
+
+        public bool HasPositiveIntValue
+        {
+            get { return hasPositiveIntValue; }
+        }
+
+        [global::System.CLSCompliant(false)]
+        public ulong PositiveIntValue
+        {
+            get { return positiveIntValue_; }
+        }
+
+        public const int NegativeIntValueFieldNumber = 5;
+        private bool hasNegativeIntValue;
+        private long negativeIntValue_ = 0L;
+
+        public bool HasNegativeIntValue
+        {
+            get { return hasNegativeIntValue; }
+        }
+
+        public long NegativeIntValue
+        {
+            get { return negativeIntValue_; }
+        }
+
+        public const int DoubleValueFieldNumber = 6;
+        private bool hasDoubleValue;
+        private double doubleValue_ = 0D;
+
+        public bool HasDoubleValue
+        {
+            get { return hasDoubleValue; }
+        }
+
+        public double DoubleValue
+        {
+            get { return doubleValue_; }
+        }
+
+        public const int StringValueFieldNumber = 7;
+        private bool hasStringValue;
+        private pb::ByteString stringValue_ = pb::ByteString.Empty;
+
+        public bool HasStringValue
+        {
+            get { return hasStringValue; }
+        }
+
+        public pb::ByteString StringValue
+        {
+            get { return stringValue_; }
+        }
+
+        public override bool IsInitialized
+        {
+            get
+            {
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart element in
+                        NameList)
+                {
+                    if (!element.IsInitialized) return false;
+                }
+                return true;
+            }
+        }
+
+        public override void WriteTo(pb::CodedOutputStream output)
+        {
+            int size = SerializedSize;
+            foreach (
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart element in NameList)
+            {
+                output.WriteMessage(2, element);
+            }
+            if (HasIdentifierValue)
+            {
+                output.WriteString(3, IdentifierValue);
+            }
+            if (HasPositiveIntValue)
+            {
+                output.WriteUInt64(4, PositiveIntValue);
+            }
+            if (HasNegativeIntValue)
+            {
+                output.WriteInt64(5, NegativeIntValue);
             }
-            if (HasIsExtension) {
-              size += pb::CodedOutputStream.ComputeBoolSize(2, IsExtension);
+            if (HasDoubleValue)
+            {
+                output.WriteDouble(6, DoubleValue);
+            }
+            if (HasStringValue)
+            {
+                output.WriteBytes(7, StringValue);
+            }
+            UnknownFields.WriteTo(output);
+        }
+
+        private int memoizedSerializedSize = -1;
+
+        public override int SerializedSize
+        {
+            get
+            {
+                int size = memoizedSerializedSize;
+                if (size != -1) return size;
+
+                size = 0;
+                foreach (
+                    global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart element in
+                        NameList)
+                {
+                    size += pb::CodedOutputStream.ComputeMessageSize(2, element);
+                }
+                if (HasIdentifierValue)
+                {
+                    size += pb::CodedOutputStream.ComputeStringSize(3, IdentifierValue);
+                }
+                if (HasPositiveIntValue)
+                {
+                    size += pb::CodedOutputStream.ComputeUInt64Size(4, PositiveIntValue);
+                }
+                if (HasNegativeIntValue)
+                {
+                    size += pb::CodedOutputStream.ComputeInt64Size(5, NegativeIntValue);
+                }
+                if (HasDoubleValue)
+                {
+                    size += pb::CodedOutputStream.ComputeDoubleSize(6, DoubleValue);
+                }
+                if (HasStringValue)
+                {
+                    size += pb::CodedOutputStream.ComputeBytesSize(7, StringValue);
+                }
+                size += UnknownFields.SerializedSize;
+                memoizedSerializedSize = size;
+                return size;
             }
-            size += UnknownFields.SerializedSize;
-            memoizedSerializedSize = size;
-            return size;
-          }
         }
-        
-        public static NamePart ParseFrom(pb::ByteString data) {
-          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+
+        public static UninterpretedOption ParseFrom(pb::ByteString data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static UninterpretedOption ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+        }
+
+        public static UninterpretedOption ParseFrom(byte[] data)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+        }
+
+        public static UninterpretedOption ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
         }
-        public static NamePart ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+
+        public static UninterpretedOption ParseFrom(global::System.IO.Stream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
         }
-        public static NamePart ParseFrom(byte[] data) {
-          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+
+        public static UninterpretedOption ParseFrom(global::System.IO.Stream input,
+                                                    pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
-        public static NamePart ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+
+        public static UninterpretedOption ParseDelimitedFrom(global::System.IO.Stream input)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
         }
-        public static NamePart ParseFrom(global::System.IO.Stream input) {
-          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+
+        public static UninterpretedOption ParseDelimitedFrom(global::System.IO.Stream input,
+                                                             pb::ExtensionRegistry extensionRegistry)
+        {
+            return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
         }
-        public static NamePart ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+
+        public static UninterpretedOption ParseFrom(pb::CodedInputStream input)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
         }
-        public static NamePart ParseDelimitedFrom(global::System.IO.Stream input) {
-          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+
+        public static UninterpretedOption ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry)
+        {
+            return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
-        public static NamePart ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+
+        public static Builder CreateBuilder()
+        {
+            return new Builder();
         }
-        public static NamePart ParseFrom(pb::CodedInputStream input) {
-          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+
+        public override Builder ToBuilder()
+        {
+            return CreateBuilder(this);
         }
-        public static NamePart ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+
+        public override Builder CreateBuilderForType()
+        {
+            return new Builder();
         }
-        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(NamePart prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
+
+        public static Builder CreateBuilder(UninterpretedOption prototype)
+        {
+            return (Builder) new Builder().MergeFrom(prototype);
         }
-        
-        public sealed partial class Builder : pb::GeneratedBuilder<NamePart, Builder> {
-          protected override Builder ThisBuilder {
-            get { return this; }
-          }
-          public Builder() {}
-          
-          NamePart result = new NamePart();
-          
-          protected override NamePart MessageBeingBuilt {
-            get { return result; }
-          }
-          
-          public override Builder Clear() {
-            result = new NamePart();
-            return this;
-          }
-          
-          public override Builder Clone() {
-            return new Builder().MergeFrom(result);
-          }
-          
-          public override pbd::MessageDescriptor DescriptorForType {
-            get { return global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Descriptor; }
-          }
-          
-          public override NamePart DefaultInstanceForType {
-            get { return global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.DefaultInstance; }
-          }
-          
-          public override NamePart BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-            }
-            NamePart returnMe = result;
-            result = null;
-            return returnMe;
-          }
-          
-          public override Builder MergeFrom(pb::IMessage other) {
-            if (other is NamePart) {
-              return MergeFrom((NamePart) other);
-            } else {
-              base.MergeFrom(other);
-              return this;
-            }
-          }
-          
-          public override Builder MergeFrom(NamePart other) {
-            if (other == global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.DefaultInstance) return this;
-            if (other.HasNamePart_) {
-              NamePart_ = other.NamePart_;
-            }
-            if (other.HasIsExtension) {
-              IsExtension = other.IsExtension;
-            }
-            this.MergeUnknownFields(other.UnknownFields);
-            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) {
-            pb::UnknownFieldSet.Builder unknownFields = null;
-            while (true) {
-              uint tag = input.ReadTag();
-              switch (tag) {
-                case 0: {
-                  if (unknownFields != null) {
-                    this.UnknownFields = unknownFields.Build();
-                  }
-                  return this;
-                }
-                default: {
-                  if (pb::WireFormat.IsEndGroupTag(tag)) {
-                    if (unknownFields != null) {
-                      this.UnknownFields = unknownFields.Build();
-                    }
+
+        public sealed partial class Builder : pb::GeneratedBuilder<UninterpretedOption, Builder>
+        {
+            protected override Builder ThisBuilder
+            {
+                get { return this; }
+            }
+
+            public Builder()
+            {
+            }
+
+            private UninterpretedOption result = new UninterpretedOption();
+
+            protected override UninterpretedOption MessageBeingBuilt
+            {
+                get { return result; }
+            }
+
+            public override Builder Clear()
+            {
+                result = new UninterpretedOption();
+                return this;
+            }
+
+            public override Builder Clone()
+            {
+                return new Builder().MergeFrom(result);
+            }
+
+            public override pbd::MessageDescriptor DescriptorForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Descriptor; }
+            }
+
+            public override UninterpretedOption DefaultInstanceForType
+            {
+                get { return global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance; }
+            }
+
+            public override UninterpretedOption BuildPartial()
+            {
+                if (result == null)
+                {
+                    throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+                }
+                result.name_.MakeReadOnly();
+                UninterpretedOption returnMe = result;
+                result = null;
+                return returnMe;
+            }
+
+            public override Builder MergeFrom(pb::IMessage other)
+            {
+                if (other is UninterpretedOption)
+                {
+                    return MergeFrom((UninterpretedOption) other);
+                }
+                else
+                {
+                    base.MergeFrom(other);
+                    return this;
+                }
+            }
+
+            public override Builder MergeFrom(UninterpretedOption other)
+            {
+                if (other == global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance)
                     return this;
-                  }
-                  if (unknownFields == null) {
-                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                  }
-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-                  break;
-                }
-                case 10: {
-                  NamePart_ = input.ReadString();
-                  break;
-                }
-                case 16: {
-                  IsExtension = input.ReadBool();
-                  break;
-                }
-              }
-            }
-          }
-          
-          
-          public bool HasNamePart_ {
-            get { return result.HasNamePart_; }
-          }
-          public string NamePart_ {
-            get { return result.NamePart_; }
-            set { SetNamePart_(value); }
-          }
-          public Builder SetNamePart_(string value) {
-            pb::ThrowHelper.ThrowIfNull(value, "value");
-            result.hasNamePart_ = true;
-            result.namePart_ = value;
-            return this;
-          }
-          public Builder ClearNamePart_() {
-            result.hasNamePart_ = false;
-            result.namePart_ = "";
-            return this;
-          }
-          
-          public bool HasIsExtension {
-            get { return result.HasIsExtension; }
-          }
-          public bool IsExtension {
-            get { return result.IsExtension; }
-            set { SetIsExtension(value); }
-          }
-          public Builder SetIsExtension(bool value) {
-            result.hasIsExtension = true;
-            result.isExtension_ = value;
-            return this;
-          }
-          public Builder ClearIsExtension() {
-            result.hasIsExtension = false;
-            result.isExtension_ = false;
-            return this;
-          }
-        }
-        static NamePart() {
-          object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-        }
-      }
-      
+                if (other.name_.Count != 0)
+                {
+                    base.AddRange(other.name_, result.name_);
+                }
+                if (other.HasIdentifierValue)
+                {
+                    IdentifierValue = other.IdentifierValue;
+                }
+                if (other.HasPositiveIntValue)
+                {
+                    PositiveIntValue = other.PositiveIntValue;
+                }
+                if (other.HasNegativeIntValue)
+                {
+                    NegativeIntValue = other.NegativeIntValue;
+                }
+                if (other.HasDoubleValue)
+                {
+                    DoubleValue = other.DoubleValue;
+                }
+                if (other.HasStringValue)
+                {
+                    StringValue = other.StringValue;
+                }
+                this.MergeUnknownFields(other.UnknownFields);
+                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)
+            {
+                pb::UnknownFieldSet.Builder unknownFields = null;
+                while (true)
+                {
+                    uint tag = input.ReadTag();
+                    switch (tag)
+                    {
+                        case 0:
+                            {
+                                if (unknownFields != null)
+                                {
+                                    this.UnknownFields = unknownFields.Build();
+                                }
+                                return this;
+                            }
+                        default:
+                            {
+                                if (pb::WireFormat.IsEndGroupTag(tag))
+                                {
+                                    if (unknownFields != null)
+                                    {
+                                        this.UnknownFields = unknownFields.Build();
+                                    }
+                                    return this;
+                                }
+                                if (unknownFields == null)
+                                {
+                                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                                }
+                                ParseUnknownField(input, unknownFields, extensionRegistry, tag);
+                                break;
+                            }
+                        case 18:
+                            {
+                                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.
+                                    Builder subBuilder =
+                                        global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.
+                                            NamePart.CreateBuilder();
+                                input.ReadMessage(subBuilder, extensionRegistry);
+                                AddName(subBuilder.BuildPartial());
+                                break;
+                            }
+                        case 26:
+                            {
+                                IdentifierValue = input.ReadString();
+                                break;
+                            }
+                        case 32:
+                            {
+                                PositiveIntValue = input.ReadUInt64();
+                                break;
+                            }
+                        case 40:
+                            {
+                                NegativeIntValue = input.ReadInt64();
+                                break;
+                            }
+                        case 49:
+                            {
+                                DoubleValue = input.ReadDouble();
+                                break;
+                            }
+                        case 58:
+                            {
+                                StringValue = input.ReadBytes();
+                                break;
+                            }
+                    }
+                }
+            }
+
+
+            public
+                pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart>
+                NameList
+            {
+                get { return result.name_; }
+            }
+
+            public int NameCount
+            {
+                get { return result.NameCount; }
+            }
+
+            public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart GetName(int index)
+            {
+                return result.GetName(index);
+            }
+
+            public Builder SetName(int index,
+                                   global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart
+                                       value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.name_[index] = value;
+                return this;
+            }
+
+            public Builder SetName(int index,
+                                   global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.
+                                       Builder builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.name_[index] = builderForValue.Build();
+                return this;
+            }
+
+            public Builder AddName(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.name_.Add(value);
+                return this;
+            }
+
+            public Builder AddName(
+                global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Builder
+                    builderForValue)
+            {
+                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+                result.name_.Add(builderForValue.Build());
+                return this;
+            }
+
+            public Builder AddRangeName(
+                scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart>
+                    values)
+            {
+                base.AddRange(values, result.name_);
+                return this;
+            }
+
+            public Builder ClearName()
+            {
+                result.name_.Clear();
+                return this;
+            }
+
+            public bool HasIdentifierValue
+            {
+                get { return result.HasIdentifierValue; }
+            }
+
+            public string IdentifierValue
+            {
+                get { return result.IdentifierValue; }
+                set { SetIdentifierValue(value); }
+            }
+
+            public Builder SetIdentifierValue(string value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasIdentifierValue = true;
+                result.identifierValue_ = value;
+                return this;
+            }
+
+            public Builder ClearIdentifierValue()
+            {
+                result.hasIdentifierValue = false;
+                result.identifierValue_ = "";
+                return this;
+            }
+
+            public bool HasPositiveIntValue
+            {
+                get { return result.HasPositiveIntValue; }
+            }
+
+            [global::System.CLSCompliant(false)]
+            public ulong PositiveIntValue
+            {
+                get { return result.PositiveIntValue; }
+                set { SetPositiveIntValue(value); }
+            }
+
+            [global::System.CLSCompliant(false)]
+            public Builder SetPositiveIntValue(ulong value)
+            {
+                result.hasPositiveIntValue = true;
+                result.positiveIntValue_ = value;
+                return this;
+            }
+
+            public Builder ClearPositiveIntValue()
+            {
+                result.hasPositiveIntValue = false;
+                result.positiveIntValue_ = 0UL;
+                return this;
+            }
+
+            public bool HasNegativeIntValue
+            {
+                get { return result.HasNegativeIntValue; }
+            }
+
+            public long NegativeIntValue
+            {
+                get { return result.NegativeIntValue; }
+                set { SetNegativeIntValue(value); }
+            }
+
+            public Builder SetNegativeIntValue(long value)
+            {
+                result.hasNegativeIntValue = true;
+                result.negativeIntValue_ = value;
+                return this;
+            }
+
+            public Builder ClearNegativeIntValue()
+            {
+                result.hasNegativeIntValue = false;
+                result.negativeIntValue_ = 0L;
+                return this;
+            }
+
+            public bool HasDoubleValue
+            {
+                get { return result.HasDoubleValue; }
+            }
+
+            public double DoubleValue
+            {
+                get { return result.DoubleValue; }
+                set { SetDoubleValue(value); }
+            }
+
+            public Builder SetDoubleValue(double value)
+            {
+                result.hasDoubleValue = true;
+                result.doubleValue_ = value;
+                return this;
+            }
+
+            public Builder ClearDoubleValue()
+            {
+                result.hasDoubleValue = false;
+                result.doubleValue_ = 0D;
+                return this;
+            }
+
+            public bool HasStringValue
+            {
+                get { return result.HasStringValue; }
+            }
+
+            public pb::ByteString StringValue
+            {
+                get { return result.StringValue; }
+                set { SetStringValue(value); }
+            }
+
+            public Builder SetStringValue(pb::ByteString value)
+            {
+                pb::ThrowHelper.ThrowIfNull(value, "value");
+                result.hasStringValue = true;
+                result.stringValue_ = value;
+                return this;
+            }
+
+            public Builder ClearStringValue()
+            {
+                result.hasStringValue = false;
+                result.stringValue_ = pb::ByteString.Empty;
+                return this;
+            }
+        }
+
+        static UninterpretedOption()
+        {
+            object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
+        }
     }
+
     #endregion
-    
-    public const int NameFieldNumber = 2;
-    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart> name_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart>();
-    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart> NameList {
-      get { return name_; }
-    }
-    public int NameCount {
-      get { return name_.Count; }
-    }
-    public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart GetName(int index) {
-      return name_[index];
-    }
-    
-    public const int IdentifierValueFieldNumber = 3;
-    private bool hasIdentifierValue;
-    private string identifierValue_ = "";
-    public bool HasIdentifierValue {
-      get { return hasIdentifierValue; }
-    }
-    public string IdentifierValue {
-      get { return identifierValue_; }
-    }
-    
-    public const int PositiveIntValueFieldNumber = 4;
-    private bool hasPositiveIntValue;
-    private ulong positiveIntValue_ = 0UL;
-    public bool HasPositiveIntValue {
-      get { return hasPositiveIntValue; }
-    }
-    [global::System.CLSCompliant(false)]
-    public ulong PositiveIntValue {
-      get { return positiveIntValue_; }
-    }
-    
-    public const int NegativeIntValueFieldNumber = 5;
-    private bool hasNegativeIntValue;
-    private long negativeIntValue_ = 0L;
-    public bool HasNegativeIntValue {
-      get { return hasNegativeIntValue; }
-    }
-    public long NegativeIntValue {
-      get { return negativeIntValue_; }
-    }
-    
-    public const int DoubleValueFieldNumber = 6;
-    private bool hasDoubleValue;
-    private double doubleValue_ = 0D;
-    public bool HasDoubleValue {
-      get { return hasDoubleValue; }
-    }
-    public double DoubleValue {
-      get { return doubleValue_; }
-    }
-    
-    public const int StringValueFieldNumber = 7;
-    private bool hasStringValue;
-    private pb::ByteString stringValue_ = pb::ByteString.Empty;
-    public bool HasStringValue {
-      get { return hasStringValue; }
-    }
-    public pb::ByteString StringValue {
-      get { return stringValue_; }
-    }
-    
-    public override bool IsInitialized {
-      get {
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart element in NameList) {
-          if (!element.IsInitialized) return false;
-        }
-        return true;
-      }
-    }
-    
-    public override void WriteTo(pb::CodedOutputStream output) {
-      int size = SerializedSize;
-      foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart element in NameList) {
-        output.WriteMessage(2, element);
-      }
-      if (HasIdentifierValue) {
-        output.WriteString(3, IdentifierValue);
-      }
-      if (HasPositiveIntValue) {
-        output.WriteUInt64(4, PositiveIntValue);
-      }
-      if (HasNegativeIntValue) {
-        output.WriteInt64(5, NegativeIntValue);
-      }
-      if (HasDoubleValue) {
-        output.WriteDouble(6, DoubleValue);
-      }
-      if (HasStringValue) {
-        output.WriteBytes(7, StringValue);
-      }
-      UnknownFields.WriteTo(output);
-    }
-    
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        
-        size = 0;
-        foreach (global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart element in NameList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(2, element);
-        }
-        if (HasIdentifierValue) {
-          size += pb::CodedOutputStream.ComputeStringSize(3, IdentifierValue);
-        }
-        if (HasPositiveIntValue) {
-          size += pb::CodedOutputStream.ComputeUInt64Size(4, PositiveIntValue);
-        }
-        if (HasNegativeIntValue) {
-          size += pb::CodedOutputStream.ComputeInt64Size(5, NegativeIntValue);
-        }
-        if (HasDoubleValue) {
-          size += pb::CodedOutputStream.ComputeDoubleSize(6, DoubleValue);
-        }
-        if (HasStringValue) {
-          size += pb::CodedOutputStream.ComputeBytesSize(7, StringValue);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
-      }
-    }
-    
-    public static UninterpretedOption ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static UninterpretedOption ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static UninterpretedOption ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static UninterpretedOption ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static UninterpretedOption ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static UninterpretedOption ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static UninterpretedOption ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static UninterpretedOption ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static UninterpretedOption ParseFrom(pb::CodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static UninterpretedOption 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(UninterpretedOption prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
-    }
-    
-    public sealed partial class Builder : pb::GeneratedBuilder<UninterpretedOption, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {}
-      
-      UninterpretedOption result = new UninterpretedOption();
-      
-      protected override UninterpretedOption MessageBeingBuilt {
-        get { return result; }
-      }
-      
-      public override Builder Clear() {
-        result = new UninterpretedOption();
-        return this;
-      }
-      
-      public override Builder Clone() {
-        return new Builder().MergeFrom(result);
-      }
-      
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Descriptor; }
-      }
-      
-      public override UninterpretedOption DefaultInstanceForType {
-        get { return global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance; }
-      }
-      
-      public override UninterpretedOption BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
-        }
-        result.name_.MakeReadOnly();
-        UninterpretedOption returnMe = result;
-        result = null;
-        return returnMe;
-      }
-      
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is UninterpretedOption) {
-          return MergeFrom((UninterpretedOption) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-      
-      public override Builder MergeFrom(UninterpretedOption other) {
-        if (other == global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance) return this;
-        if (other.name_.Count != 0) {
-          base.AddRange(other.name_, result.name_);
-        }
-        if (other.HasIdentifierValue) {
-          IdentifierValue = other.IdentifierValue;
-        }
-        if (other.HasPositiveIntValue) {
-          PositiveIntValue = other.PositiveIntValue;
-        }
-        if (other.HasNegativeIntValue) {
-          NegativeIntValue = other.NegativeIntValue;
-        }
-        if (other.HasDoubleValue) {
-          DoubleValue = other.DoubleValue;
-        }
-        if (other.HasStringValue) {
-          StringValue = other.StringValue;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        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) {
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        while (true) {
-          uint tag = input.ReadTag();
-          switch (tag) {
-            case 0: {
-              if (unknownFields != null) {
-                this.UnknownFields = unknownFields.Build();
-              }
-              return this;
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
-              break;
-            }
-            case 18: {
-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.CreateBuilder();
-              input.ReadMessage(subBuilder, extensionRegistry);
-              AddName(subBuilder.BuildPartial());
-              break;
-            }
-            case 26: {
-              IdentifierValue = input.ReadString();
-              break;
-            }
-            case 32: {
-              PositiveIntValue = input.ReadUInt64();
-              break;
-            }
-            case 40: {
-              NegativeIntValue = input.ReadInt64();
-              break;
-            }
-            case 49: {
-              DoubleValue = input.ReadDouble();
-              break;
-            }
-            case 58: {
-              StringValue = input.ReadBytes();
-              break;
-            }
-          }
-        }
-      }
-      
-      
-      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart> NameList {
-        get { return result.name_; }
-      }
-      public int NameCount {
-        get { return result.NameCount; }
-      }
-      public global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart GetName(int index) {
-        return result.GetName(index);
-      }
-      public Builder SetName(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.name_[index] = value;
-        return this;
-      }
-      public Builder SetName(int index, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.name_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddName(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.name_.Add(value);
-        return this;
-      }
-      public Builder AddName(global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        result.name_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeName(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart> values) {
-        base.AddRange(values, result.name_);
-        return this;
-      }
-      public Builder ClearName() {
-        result.name_.Clear();
-        return this;
-      }
-      
-      public bool HasIdentifierValue {
-        get { return result.HasIdentifierValue; }
-      }
-      public string IdentifierValue {
-        get { return result.IdentifierValue; }
-        set { SetIdentifierValue(value); }
-      }
-      public Builder SetIdentifierValue(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasIdentifierValue = true;
-        result.identifierValue_ = value;
-        return this;
-      }
-      public Builder ClearIdentifierValue() {
-        result.hasIdentifierValue = false;
-        result.identifierValue_ = "";
-        return this;
-      }
-      
-      public bool HasPositiveIntValue {
-        get { return result.HasPositiveIntValue; }
-      }
-      [global::System.CLSCompliant(false)]
-      public ulong PositiveIntValue {
-        get { return result.PositiveIntValue; }
-        set { SetPositiveIntValue(value); }
-      }
-      [global::System.CLSCompliant(false)]
-      public Builder SetPositiveIntValue(ulong value) {
-        result.hasPositiveIntValue = true;
-        result.positiveIntValue_ = value;
-        return this;
-      }
-      public Builder ClearPositiveIntValue() {
-        result.hasPositiveIntValue = false;
-        result.positiveIntValue_ = 0UL;
-        return this;
-      }
-      
-      public bool HasNegativeIntValue {
-        get { return result.HasNegativeIntValue; }
-      }
-      public long NegativeIntValue {
-        get { return result.NegativeIntValue; }
-        set { SetNegativeIntValue(value); }
-      }
-      public Builder SetNegativeIntValue(long value) {
-        result.hasNegativeIntValue = true;
-        result.negativeIntValue_ = value;
-        return this;
-      }
-      public Builder ClearNegativeIntValue() {
-        result.hasNegativeIntValue = false;
-        result.negativeIntValue_ = 0L;
-        return this;
-      }
-      
-      public bool HasDoubleValue {
-        get { return result.HasDoubleValue; }
-      }
-      public double DoubleValue {
-        get { return result.DoubleValue; }
-        set { SetDoubleValue(value); }
-      }
-      public Builder SetDoubleValue(double value) {
-        result.hasDoubleValue = true;
-        result.doubleValue_ = value;
-        return this;
-      }
-      public Builder ClearDoubleValue() {
-        result.hasDoubleValue = false;
-        result.doubleValue_ = 0D;
-        return this;
-      }
-      
-      public bool HasStringValue {
-        get { return result.HasStringValue; }
-      }
-      public pb::ByteString StringValue {
-        get { return result.StringValue; }
-        set { SetStringValue(value); }
-      }
-      public Builder SetStringValue(pb::ByteString value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        result.hasStringValue = true;
-        result.stringValue_ = value;
-        return this;
-      }
-      public Builder ClearStringValue() {
-        result.hasStringValue = false;
-        result.stringValue_ = pb::ByteString.Empty;
-        return this;
-      }
-    }
-    static UninterpretedOption() {
-      object.ReferenceEquals(global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, null);
-    }
-  }
-  
-  #endregion
-  
-}
+}

+ 52 - 52
src/ProtocolBuffers/DescriptorProtos/IDescriptorProto.cs

@@ -1,52 +1,52 @@
-// 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.
-namespace Google.ProtocolBuffers.DescriptorProtos {
-
-  /// <summary>
-  /// Interface implemented by all DescriptorProtos. The generator doesn't
-  /// emit the interface implementation claim, so PartialClasses.cs contains
-  /// partial class declarations for each of them.
-  /// </summary>
-  /// <typeparam name="TOptions">The associated options protocol buffer type</typeparam>
-  public interface IDescriptorProto<TOptions> {
-
-    /// <summary>
-    /// The brief name of the descriptor's target.
-    /// </summary>
-    string Name { get; }
-
-    /// <summary>
-    /// The options for this descriptor.
-    /// </summary>
-    TOptions Options { get; }
-  }
-}
+// 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.
+namespace Google.ProtocolBuffers.DescriptorProtos
+{
+    /// <summary>
+    /// Interface implemented by all DescriptorProtos. The generator doesn't
+    /// emit the interface implementation claim, so PartialClasses.cs contains
+    /// partial class declarations for each of them.
+    /// </summary>
+    /// <typeparam name="TOptions">The associated options protocol buffer type</typeparam>
+    public interface IDescriptorProto<TOptions>
+    {
+        /// <summary>
+        /// The brief name of the descriptor's target.
+        /// </summary>
+        string Name { get; }
+
+        /// <summary>
+        /// The options for this descriptor.
+        /// </summary>
+        TOptions Options { get; }
+    }
+}

+ 65 - 45
src/ProtocolBuffers/DescriptorProtos/PartialClasses.cs

@@ -1,45 +1,65 @@
-// 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.
-
-// This file just contains partial classes for each of the
-// autogenerated classes, so that they implement
-// IDescriptorProto
-namespace Google.ProtocolBuffers.DescriptorProtos {
-
-  public partial class DescriptorProto : IDescriptorProto<MessageOptions> { }
-  public partial class EnumDescriptorProto : IDescriptorProto<EnumOptions> { }
-  public partial class EnumValueDescriptorProto : IDescriptorProto<EnumValueOptions> { }
-  public partial class FieldDescriptorProto : IDescriptorProto<FieldOptions> { }
-  public partial class FileDescriptorProto : IDescriptorProto<FileOptions> { }
-  public partial class MethodDescriptorProto : IDescriptorProto<MethodOptions> { }
-  public partial class ServiceDescriptorProto : IDescriptorProto<ServiceOptions> { }
-}
+// 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.
+
+// This file just contains partial classes for each of the
+// autogenerated classes, so that they implement
+// IDescriptorProto
+namespace Google.ProtocolBuffers.DescriptorProtos
+{
+    public partial class DescriptorProto : IDescriptorProto<MessageOptions>
+    {
+    }
+
+    public partial class EnumDescriptorProto : IDescriptorProto<EnumOptions>
+    {
+    }
+
+    public partial class EnumValueDescriptorProto : IDescriptorProto<EnumValueOptions>
+    {
+    }
+
+    public partial class FieldDescriptorProto : IDescriptorProto<FieldOptions>
+    {
+    }
+
+    public partial class FileDescriptorProto : IDescriptorProto<FileOptions>
+    {
+    }
+
+    public partial class MethodDescriptorProto : IDescriptorProto<MethodOptions>
+    {
+    }
+
+    public partial class ServiceDescriptorProto : IDescriptorProto<ServiceOptions>
+    {
+    }
+}

+ 115 - 103
src/ProtocolBuffers/Descriptors/DescriptorBase.cs

@@ -1,103 +1,115 @@
-// 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.
-using Google.ProtocolBuffers.DescriptorProtos;
-
-namespace Google.ProtocolBuffers.Descriptors {
-  /// <summary>
-  /// Base class for nearly all descriptors, providing common functionality.
-  /// </summary>
-  /// <typeparam name="TProto">Type of the protocol buffer form of this descriptor</typeparam>
-  /// <typeparam name="TOptions">Type of the options protocol buffer for this descriptor</typeparam>
-  public abstract class DescriptorBase<TProto, TOptions> : IDescriptor<TProto>
-      where TProto : IMessage, IDescriptorProto<TOptions> {
-
-    private TProto proto;
-    private readonly FileDescriptor file;
-    private readonly string fullName;
-
-    protected DescriptorBase(TProto proto, FileDescriptor file, string fullName) {
-      this.proto = proto;
-      this.file = file;
-      this.fullName = fullName;
-    }
-
-    internal virtual void ReplaceProto(TProto newProto) {
-      this.proto = newProto;
-    }
-
-    protected static string ComputeFullName(FileDescriptor file, MessageDescriptor parent, string name) {
-      if (parent != null) {
-        return parent.FullName + "." + name;
-      }
-      if (file.Package.Length > 0) {
-        return file.Package + "." + name;
-      }
-      return name;
-    }
-
-    IMessage IDescriptor.Proto {
-      get { return proto; }
-    }
-
-    /// <summary>
-    /// Returns the protocol buffer form of this descriptor.
-    /// </summary>
-    public TProto Proto {
-      get { return proto; }
-    }
-
-    public TOptions Options {
-      get { return proto.Options; }
-    }
-
-    /// <summary>
-    /// The fully qualified name of the descriptor's target.
-    /// </summary>
-    public string FullName {
-      get { return fullName; }
-    }
-
-    /// <summary>
-    /// The brief name of the descriptor's target.
-    /// </summary>
-    public string Name {
-      get { return proto.Name; }
-    }
-
-    /// <value>
-    /// The file this descriptor was declared in.
-    /// </value>
-    public FileDescriptor File {
-      get { return file; }
-    }
-  }
-}
+// 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.
+using Google.ProtocolBuffers.DescriptorProtos;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Base class for nearly all descriptors, providing common functionality.
+    /// </summary>
+    /// <typeparam name="TProto">Type of the protocol buffer form of this descriptor</typeparam>
+    /// <typeparam name="TOptions">Type of the options protocol buffer for this descriptor</typeparam>
+    public abstract class DescriptorBase<TProto, TOptions> : IDescriptor<TProto>
+        where TProto : IMessage, IDescriptorProto<TOptions>
+    {
+        private TProto proto;
+        private readonly FileDescriptor file;
+        private readonly string fullName;
+
+        protected DescriptorBase(TProto proto, FileDescriptor file, string fullName)
+        {
+            this.proto = proto;
+            this.file = file;
+            this.fullName = fullName;
+        }
+
+        internal virtual void ReplaceProto(TProto newProto)
+        {
+            this.proto = newProto;
+        }
+
+        protected static string ComputeFullName(FileDescriptor file, MessageDescriptor parent, string name)
+        {
+            if (parent != null)
+            {
+                return parent.FullName + "." + name;
+            }
+            if (file.Package.Length > 0)
+            {
+                return file.Package + "." + name;
+            }
+            return name;
+        }
+
+        IMessage IDescriptor.Proto
+        {
+            get { return proto; }
+        }
+
+        /// <summary>
+        /// Returns the protocol buffer form of this descriptor.
+        /// </summary>
+        public TProto Proto
+        {
+            get { return proto; }
+        }
+
+        public TOptions Options
+        {
+            get { return proto.Options; }
+        }
+
+        /// <summary>
+        /// The fully qualified name of the descriptor's target.
+        /// </summary>
+        public string FullName
+        {
+            get { return fullName; }
+        }
+
+        /// <summary>
+        /// The brief name of the descriptor's target.
+        /// </summary>
+        public string Name
+        {
+            get { return proto.Name; }
+        }
+
+        /// <value>
+        /// The file this descriptor was declared in.
+        /// </value>
+        public FileDescriptor File
+        {
+            get { return file; }
+        }
+    }
+}

+ 352 - 296
src/ProtocolBuffers/Descriptors/DescriptorPool.cs

@@ -1,296 +1,352 @@
-// 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.
-using System.Collections.Generic;
-using System;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace Google.ProtocolBuffers.Descriptors {
-  /// <summary>
-  /// Contains lookup tables containing all the descriptors defined in a particular file.
-  /// </summary>
-  internal sealed class DescriptorPool {
-
-    private readonly IDictionary<string, IDescriptor> descriptorsByName =
-        new Dictionary<string, IDescriptor>();
-    private readonly IDictionary<DescriptorIntPair, FieldDescriptor> fieldsByNumber =
-        new Dictionary<DescriptorIntPair, FieldDescriptor>();
-    private readonly IDictionary<DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber =
-        new Dictionary<DescriptorIntPair, EnumValueDescriptor>();
-    private readonly DescriptorPool[] dependencies;
-
-    internal DescriptorPool(FileDescriptor[] dependencyFiles) {
-      dependencies = new DescriptorPool[dependencyFiles.Length];
-      for (int i = 0; i < dependencyFiles.Length; i++) {
-        dependencies[i] = dependencyFiles[i].DescriptorPool;
-      }
-
-      foreach (FileDescriptor dependency in dependencyFiles) {
-        AddPackage(dependency.Package, dependency);
-      }
-    }
-
-    /// <summary>
-    /// Finds a symbol of the given name within the pool.
-    /// </summary>
-    /// <typeparam name="T">The type of symbol to look for</typeparam>
-    /// <param name="fullName">Fully-qualified name to look up</param>
-    /// <returns>The symbol with the given name and type,
-    /// or null if the symbol doesn't exist or has the wrong type</returns>
-    internal T FindSymbol<T>(string fullName) where T : class, IDescriptor {
-      IDescriptor result;
-      descriptorsByName.TryGetValue(fullName, out result);
-      T descriptor = result as T;
-      if (descriptor != null) {
-        return descriptor;
-      }
-
-      foreach (DescriptorPool dependency in dependencies) {
-        dependency.descriptorsByName.TryGetValue(fullName, out result);
-        descriptor = result as T;
-        if (descriptor != null) {
-          return descriptor;
-        }
-      }
-
-      return null;
-    }
-
-    /// <summary>
-    /// Adds a package to the symbol tables. If a package by the same name
-    /// already exists, that is fine, but if some other kind of symbol
-    /// exists under the same name, an exception is thrown. If the package
-    /// has multiple components, this also adds the parent package(s).
-    /// </summary>
-    internal void AddPackage(string fullName, FileDescriptor file) {
-      int dotpos = fullName.LastIndexOf('.');
-      String name;
-      if (dotpos != -1) {
-        AddPackage(fullName.Substring(0, dotpos), file);
-        name = fullName.Substring(dotpos + 1);
-      } else {
-        name = fullName;
-      }
-
-      IDescriptor old;
-      if (descriptorsByName.TryGetValue(fullName, out old)) {
-        if (!(old is PackageDescriptor)) {
-          throw new DescriptorValidationException(file,
-           "\"" + name + "\" is already defined (as something other than a " +
-            "package) in file \"" + old.File.Name + "\".");
-        }
-      }
-      descriptorsByName[fullName] = new PackageDescriptor(name, fullName, file);
-    }
-
-    /// <summary>
-    /// Adds a symbol to the symbol table.
-    /// </summary>
-    /// <exception cref="DescriptorValidationException">The symbol already existed
-    /// in the symbol table.</exception>
-    internal void AddSymbol(IDescriptor descriptor) {
-      ValidateSymbolName(descriptor);
-      String fullName = descriptor.FullName;
-
-      IDescriptor old;
-      if (descriptorsByName.TryGetValue(fullName, out old)) {
-        int dotPos = fullName.LastIndexOf('.');
-        string message;
-        if (descriptor.File == old.File) {
-          if (dotPos == -1) {
-            message = "\"" + fullName + "\" is already defined.";
-          } else {
-            message = "\"" + fullName.Substring(dotPos + 1) + "\" is already defined in \"" + fullName.Substring(0, dotPos) + "\".";
-          }
-        } else {
-          message = "\"" + fullName + "\" is already defined in file \"" + old.File.Name + "\".";
-        }
-        throw new DescriptorValidationException(descriptor, message);
-      }
-      descriptorsByName[fullName] = descriptor;
-    }
-
-    private static readonly Regex ValidationRegex = new Regex("^[_A-Za-z][_A-Za-z0-9]*$", SilverlightCompatibility.CompiledRegexWhereAvailable);
-
-    /// <summary>
-    /// Verifies that the descriptor's name is valid (i.e. it contains
-    /// only letters, digits and underscores, and does not start with a digit).
-    /// </summary>
-    /// <param name="descriptor"></param>
-    private static void ValidateSymbolName(IDescriptor descriptor) {
-      if (descriptor.Name == "") {
-        throw new DescriptorValidationException(descriptor, "Missing name.");
-      }
-      if (!ValidationRegex.IsMatch(descriptor.Name)) {
-        throw new DescriptorValidationException(descriptor,
-            "\"" + descriptor.Name + "\" is not a valid identifier.");
-      }
-    }
-
-    /// <summary>
-    /// Returns the field with the given number in the given descriptor,
-    /// or null if it can't be found.
-    /// </summary>
-    internal FieldDescriptor FindFieldByNumber(MessageDescriptor messageDescriptor, int number) {
-      FieldDescriptor ret;
-      fieldsByNumber.TryGetValue(new DescriptorIntPair(messageDescriptor, number), out ret);
-      return ret;
-    }
-
-    internal EnumValueDescriptor FindEnumValueByNumber(EnumDescriptor enumDescriptor, int number) {
-      EnumValueDescriptor ret;
-      enumValuesByNumber.TryGetValue(new DescriptorIntPair(enumDescriptor, number), out ret);
-      return ret;
-    }
-
-    /// <summary>
-    /// Adds a field to the fieldsByNumber table.
-    /// </summary>
-    /// <exception cref="DescriptorValidationException">A field with the same
-    /// containing type and number already exists.</exception>
-    internal void AddFieldByNumber(FieldDescriptor field) {
-      DescriptorIntPair key = new DescriptorIntPair(field.ContainingType, field.FieldNumber);
-      FieldDescriptor old;
-      if (fieldsByNumber.TryGetValue(key, out old)) {
-        throw new DescriptorValidationException(field, "Field number " + field.FieldNumber +
-          "has already been used in \"" + field.ContainingType.FullName +
-          "\" by field \"" + old.Name + "\".");
-      }
-      fieldsByNumber[key] = field;
-    }
-
-    /// <summary>
-    /// Adds an enum value to the enumValuesByNumber table. If an enum value
-    /// with the same type and number already exists, this method does nothing.
-    /// (This is allowed; the first value defined with the number takes precedence.)
-    /// </summary>
-    internal void AddEnumValueByNumber(EnumValueDescriptor enumValue) {
-      DescriptorIntPair key = new DescriptorIntPair(enumValue.EnumDescriptor, enumValue.Number);
-      if (!enumValuesByNumber.ContainsKey(key)) {
-        enumValuesByNumber[key] = enumValue;
-      }
-    }
-
-    /// <summary>
-    /// Looks up a descriptor by name, relative to some other descriptor.
-    /// The name may be fully-qualified (with a leading '.'), partially-qualified,
-    /// or unqualified. C++-like name lookup semantics are used to search for the
-    /// matching descriptor.
-    /// </summary>
-    public IDescriptor LookupSymbol(string name, IDescriptor relativeTo) {
-      // TODO(jonskeet):  This could be optimized in a number of ways.
-
-      IDescriptor result;
-      if (name.StartsWith(".")) {
-        // Fully-qualified name.
-        result = FindSymbol<IDescriptor>(name.Substring(1));
-      } else {
-        // If "name" is a compound identifier, we want to search for the
-        // first component of it, then search within it for the rest.
-        int firstPartLength = name.IndexOf('.');
-        string firstPart = firstPartLength == -1 ? name : name.Substring(0, firstPartLength);
-
-        // We will search each parent scope of "relativeTo" looking for the
-        // symbol.
-        StringBuilder scopeToTry = new StringBuilder(relativeTo.FullName);
-
-        while (true) {
-          // Chop off the last component of the scope.
-
-          // TODO(jonskeet): Make this more efficient. May not be worth using StringBuilder at all
-          int dotpos = scopeToTry.ToString().LastIndexOf(".");
-          if (dotpos == -1) {
-            result = FindSymbol<IDescriptor>(name);
-            break;
-          } else {
-            scopeToTry.Length = dotpos + 1;
-
-            // Append firstPart and try to find.
-            scopeToTry.Append(firstPart);
-            result = FindSymbol<IDescriptor>(scopeToTry.ToString());
-
-            if (result != null) {
-              if (firstPartLength != -1) {
-                // We only found the first part of the symbol.  Now look for
-                // the whole thing.  If this fails, we *don't* want to keep
-                // searching parent scopes.
-                scopeToTry.Length = dotpos + 1;
-                scopeToTry.Append(name);
-                result = FindSymbol<IDescriptor>(scopeToTry.ToString());
-              }
-              break;
-            }
-
-            // Not found.  Remove the name so we can try again.
-            scopeToTry.Length = dotpos;
-          }
-        }
-      }
-
-      if (result == null) {
-        throw new DescriptorValidationException(relativeTo, "\"" + name + "\" is not defined.");
-      } else {
-        return result;
-      }
-    }
-
-    /// <summary>
-    /// Struct used to hold the keys for the fieldByNumber table.
-    /// </summary>
-    struct DescriptorIntPair : IEquatable<DescriptorIntPair> {
-
-      private readonly int number;
-      private readonly IDescriptor descriptor;
-
-      internal DescriptorIntPair(IDescriptor descriptor, int number) {
-        this.number = number;
-        this.descriptor = descriptor;
-      }
-
-      public bool Equals(DescriptorIntPair other) {
-        return descriptor == other.descriptor
-            && number == other.number;
-      }
-
-      public override bool Equals(object obj) {
-        if (obj is DescriptorIntPair) {
-          return Equals((DescriptorIntPair)obj);
-        }
-        return false;
-      }
-
-      public override int GetHashCode() {
-        return descriptor.GetHashCode() * ((1 << 16) - 1) + number;
-      }
-    }
-  }
-}
+// 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.
+using System.Collections.Generic;
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Contains lookup tables containing all the descriptors defined in a particular file.
+    /// </summary>
+    internal sealed class DescriptorPool
+    {
+        private readonly IDictionary<string, IDescriptor> descriptorsByName =
+            new Dictionary<string, IDescriptor>();
+
+        private readonly IDictionary<DescriptorIntPair, FieldDescriptor> fieldsByNumber =
+            new Dictionary<DescriptorIntPair, FieldDescriptor>();
+
+        private readonly IDictionary<DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber =
+            new Dictionary<DescriptorIntPair, EnumValueDescriptor>();
+
+        private readonly DescriptorPool[] dependencies;
+
+        internal DescriptorPool(FileDescriptor[] dependencyFiles)
+        {
+            dependencies = new DescriptorPool[dependencyFiles.Length];
+            for (int i = 0; i < dependencyFiles.Length; i++)
+            {
+                dependencies[i] = dependencyFiles[i].DescriptorPool;
+            }
+
+            foreach (FileDescriptor dependency in dependencyFiles)
+            {
+                AddPackage(dependency.Package, dependency);
+            }
+        }
+
+        /// <summary>
+        /// Finds a symbol of the given name within the pool.
+        /// </summary>
+        /// <typeparam name="T">The type of symbol to look for</typeparam>
+        /// <param name="fullName">Fully-qualified name to look up</param>
+        /// <returns>The symbol with the given name and type,
+        /// or null if the symbol doesn't exist or has the wrong type</returns>
+        internal T FindSymbol<T>(string fullName) where T : class, IDescriptor
+        {
+            IDescriptor result;
+            descriptorsByName.TryGetValue(fullName, out result);
+            T descriptor = result as T;
+            if (descriptor != null)
+            {
+                return descriptor;
+            }
+
+            foreach (DescriptorPool dependency in dependencies)
+            {
+                dependency.descriptorsByName.TryGetValue(fullName, out result);
+                descriptor = result as T;
+                if (descriptor != null)
+                {
+                    return descriptor;
+                }
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Adds a package to the symbol tables. If a package by the same name
+        /// already exists, that is fine, but if some other kind of symbol
+        /// exists under the same name, an exception is thrown. If the package
+        /// has multiple components, this also adds the parent package(s).
+        /// </summary>
+        internal void AddPackage(string fullName, FileDescriptor file)
+        {
+            int dotpos = fullName.LastIndexOf('.');
+            String name;
+            if (dotpos != -1)
+            {
+                AddPackage(fullName.Substring(0, dotpos), file);
+                name = fullName.Substring(dotpos + 1);
+            }
+            else
+            {
+                name = fullName;
+            }
+
+            IDescriptor old;
+            if (descriptorsByName.TryGetValue(fullName, out old))
+            {
+                if (!(old is PackageDescriptor))
+                {
+                    throw new DescriptorValidationException(file,
+                                                            "\"" + name +
+                                                            "\" is already defined (as something other than a " +
+                                                            "package) in file \"" + old.File.Name + "\".");
+                }
+            }
+            descriptorsByName[fullName] = new PackageDescriptor(name, fullName, file);
+        }
+
+        /// <summary>
+        /// Adds a symbol to the symbol table.
+        /// </summary>
+        /// <exception cref="DescriptorValidationException">The symbol already existed
+        /// in the symbol table.</exception>
+        internal void AddSymbol(IDescriptor descriptor)
+        {
+            ValidateSymbolName(descriptor);
+            String fullName = descriptor.FullName;
+
+            IDescriptor old;
+            if (descriptorsByName.TryGetValue(fullName, out old))
+            {
+                int dotPos = fullName.LastIndexOf('.');
+                string message;
+                if (descriptor.File == old.File)
+                {
+                    if (dotPos == -1)
+                    {
+                        message = "\"" + fullName + "\" is already defined.";
+                    }
+                    else
+                    {
+                        message = "\"" + fullName.Substring(dotPos + 1) + "\" is already defined in \"" +
+                                  fullName.Substring(0, dotPos) + "\".";
+                    }
+                }
+                else
+                {
+                    message = "\"" + fullName + "\" is already defined in file \"" + old.File.Name + "\".";
+                }
+                throw new DescriptorValidationException(descriptor, message);
+            }
+            descriptorsByName[fullName] = descriptor;
+        }
+
+        private static readonly Regex ValidationRegex = new Regex("^[_A-Za-z][_A-Za-z0-9]*$",
+                                                                  SilverlightCompatibility.CompiledRegexWhereAvailable);
+
+        /// <summary>
+        /// Verifies that the descriptor's name is valid (i.e. it contains
+        /// only letters, digits and underscores, and does not start with a digit).
+        /// </summary>
+        /// <param name="descriptor"></param>
+        private static void ValidateSymbolName(IDescriptor descriptor)
+        {
+            if (descriptor.Name == "")
+            {
+                throw new DescriptorValidationException(descriptor, "Missing name.");
+            }
+            if (!ValidationRegex.IsMatch(descriptor.Name))
+            {
+                throw new DescriptorValidationException(descriptor,
+                                                        "\"" + descriptor.Name + "\" is not a valid identifier.");
+            }
+        }
+
+        /// <summary>
+        /// Returns the field with the given number in the given descriptor,
+        /// or null if it can't be found.
+        /// </summary>
+        internal FieldDescriptor FindFieldByNumber(MessageDescriptor messageDescriptor, int number)
+        {
+            FieldDescriptor ret;
+            fieldsByNumber.TryGetValue(new DescriptorIntPair(messageDescriptor, number), out ret);
+            return ret;
+        }
+
+        internal EnumValueDescriptor FindEnumValueByNumber(EnumDescriptor enumDescriptor, int number)
+        {
+            EnumValueDescriptor ret;
+            enumValuesByNumber.TryGetValue(new DescriptorIntPair(enumDescriptor, number), out ret);
+            return ret;
+        }
+
+        /// <summary>
+        /// Adds a field to the fieldsByNumber table.
+        /// </summary>
+        /// <exception cref="DescriptorValidationException">A field with the same
+        /// containing type and number already exists.</exception>
+        internal void AddFieldByNumber(FieldDescriptor field)
+        {
+            DescriptorIntPair key = new DescriptorIntPair(field.ContainingType, field.FieldNumber);
+            FieldDescriptor old;
+            if (fieldsByNumber.TryGetValue(key, out old))
+            {
+                throw new DescriptorValidationException(field, "Field number " + field.FieldNumber +
+                                                               "has already been used in \"" +
+                                                               field.ContainingType.FullName +
+                                                               "\" by field \"" + old.Name + "\".");
+            }
+            fieldsByNumber[key] = field;
+        }
+
+        /// <summary>
+        /// Adds an enum value to the enumValuesByNumber table. If an enum value
+        /// with the same type and number already exists, this method does nothing.
+        /// (This is allowed; the first value defined with the number takes precedence.)
+        /// </summary>
+        internal void AddEnumValueByNumber(EnumValueDescriptor enumValue)
+        {
+            DescriptorIntPair key = new DescriptorIntPair(enumValue.EnumDescriptor, enumValue.Number);
+            if (!enumValuesByNumber.ContainsKey(key))
+            {
+                enumValuesByNumber[key] = enumValue;
+            }
+        }
+
+        /// <summary>
+        /// Looks up a descriptor by name, relative to some other descriptor.
+        /// The name may be fully-qualified (with a leading '.'), partially-qualified,
+        /// or unqualified. C++-like name lookup semantics are used to search for the
+        /// matching descriptor.
+        /// </summary>
+        public IDescriptor LookupSymbol(string name, IDescriptor relativeTo)
+        {
+            // TODO(jonskeet):  This could be optimized in a number of ways.
+
+            IDescriptor result;
+            if (name.StartsWith("."))
+            {
+                // Fully-qualified name.
+                result = FindSymbol<IDescriptor>(name.Substring(1));
+            }
+            else
+            {
+                // If "name" is a compound identifier, we want to search for the
+                // first component of it, then search within it for the rest.
+                int firstPartLength = name.IndexOf('.');
+                string firstPart = firstPartLength == -1 ? name : name.Substring(0, firstPartLength);
+
+                // We will search each parent scope of "relativeTo" looking for the
+                // symbol.
+                StringBuilder scopeToTry = new StringBuilder(relativeTo.FullName);
+
+                while (true)
+                {
+                    // Chop off the last component of the scope.
+
+                    // TODO(jonskeet): Make this more efficient. May not be worth using StringBuilder at all
+                    int dotpos = scopeToTry.ToString().LastIndexOf(".");
+                    if (dotpos == -1)
+                    {
+                        result = FindSymbol<IDescriptor>(name);
+                        break;
+                    }
+                    else
+                    {
+                        scopeToTry.Length = dotpos + 1;
+
+                        // Append firstPart and try to find.
+                        scopeToTry.Append(firstPart);
+                        result = FindSymbol<IDescriptor>(scopeToTry.ToString());
+
+                        if (result != null)
+                        {
+                            if (firstPartLength != -1)
+                            {
+                                // We only found the first part of the symbol.  Now look for
+                                // the whole thing.  If this fails, we *don't* want to keep
+                                // searching parent scopes.
+                                scopeToTry.Length = dotpos + 1;
+                                scopeToTry.Append(name);
+                                result = FindSymbol<IDescriptor>(scopeToTry.ToString());
+                            }
+                            break;
+                        }
+
+                        // Not found.  Remove the name so we can try again.
+                        scopeToTry.Length = dotpos;
+                    }
+                }
+            }
+
+            if (result == null)
+            {
+                throw new DescriptorValidationException(relativeTo, "\"" + name + "\" is not defined.");
+            }
+            else
+            {
+                return result;
+            }
+        }
+
+        /// <summary>
+        /// Struct used to hold the keys for the fieldByNumber table.
+        /// </summary>
+        private struct DescriptorIntPair : IEquatable<DescriptorIntPair>
+        {
+            private readonly int number;
+            private readonly IDescriptor descriptor;
+
+            internal DescriptorIntPair(IDescriptor descriptor, int number)
+            {
+                this.number = number;
+                this.descriptor = descriptor;
+            }
+
+            public bool Equals(DescriptorIntPair other)
+            {
+                return descriptor == other.descriptor
+                       && number == other.number;
+            }
+
+            public override bool Equals(object obj)
+            {
+                if (obj is DescriptorIntPair)
+                {
+                    return Equals((DescriptorIntPair) obj);
+                }
+                return false;
+            }
+
+            public override int GetHashCode()
+            {
+                return descriptor.GetHashCode()*((1 << 16) - 1) + number;
+            }
+        }
+    }
+}

+ 64 - 59
src/ProtocolBuffers/Descriptors/DescriptorUtil.cs

@@ -1,59 +1,64 @@
-// 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.
-using System.Collections.Generic;
-using Google.ProtocolBuffers.Collections;
-
-namespace Google.ProtocolBuffers.Descriptors {
-  /// <summary>
-  /// Internal class containing utility methods when working with descriptors.
-  /// </summary>
-  internal static class DescriptorUtil {
-    /// <summary>
-    /// Equivalent to Func[TInput, int, TOutput] but usable in .NET 2.0. Only used to convert
-    /// arrays.
-    /// </summary>
-    internal delegate TOutput IndexedConverter<TInput, TOutput>(TInput element, int index);
-
-    /// <summary>
-    /// Converts the given array into a read-only list, applying the specified conversion to
-    /// each input element.
-    /// </summary>
-    internal static IList<TOutput> ConvertAndMakeReadOnly<TInput, TOutput>(IList<TInput> input,
-        IndexedConverter<TInput, TOutput> converter) {
-      TOutput[] array = new TOutput[input.Count];
-      for (int i = 0; i < array.Length; i++) {
-        array[i] = converter(input[i], i);
-      }
-      return Lists<TOutput>.AsReadOnly(array);
-    }
-  }
-}
+// 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.
+using System.Collections.Generic;
+using Google.ProtocolBuffers.Collections;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Internal class containing utility methods when working with descriptors.
+    /// </summary>
+    internal static class DescriptorUtil
+    {
+        /// <summary>
+        /// Equivalent to Func[TInput, int, TOutput] but usable in .NET 2.0. Only used to convert
+        /// arrays.
+        /// </summary>
+        internal delegate TOutput IndexedConverter<TInput, TOutput>(TInput element, int index);
+
+        /// <summary>
+        /// Converts the given array into a read-only list, applying the specified conversion to
+        /// each input element.
+        /// </summary>
+        internal static IList<TOutput> ConvertAndMakeReadOnly<TInput, TOutput>(IList<TInput> input,
+                                                                               IndexedConverter<TInput, TOutput>
+                                                                                   converter)
+        {
+            TOutput[] array = new TOutput[input.Count];
+            for (int i = 0; i < array.Length; i++)
+            {
+                array[i] = converter(input[i], i);
+            }
+            return Lists<TOutput>.AsReadOnly(array);
+        }
+    }
+}

+ 90 - 86
src/ProtocolBuffers/Descriptors/DescriptorValidationException.cs

@@ -1,86 +1,90 @@
-// 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.
-using System;
-
-namespace Google.ProtocolBuffers.Descriptors {
-  /// <summary>
-  /// Thrown when building descriptors fails because the source DescriptorProtos
-  /// are not valid.
-  /// </summary>
-  public sealed class DescriptorValidationException : Exception {
-
-    private readonly String name;
-    private readonly IMessage proto;
-    private readonly string description;
-
-    /// <value>
-    /// The full name of the descriptor where the error occurred.
-    /// </value>
-    public String ProblemSymbolName { 
-      get { return name; }
-    }
-
-    /// <value>
-    /// The protocol message representation of the invalid descriptor.
-    /// </value>
-    public IMessage ProblemProto {
-      get { return proto; }
-    }
-
-    /// <value>
-    /// A human-readable description of the error. (The Message property
-    /// is made up of the descriptor's name and this description.)
-    /// </value>
-    public string Description {
-      get { return description; }
-    }
-
-    internal DescriptorValidationException(IDescriptor problemDescriptor, string description) :
-        base(problemDescriptor.FullName + ": " + description) {
-
-      // Note that problemDescriptor may be partially uninitialized, so we
-      // don't want to expose it directly to the user.  So, we only provide
-      // the name and the original proto.
-      name = problemDescriptor.FullName;
-      proto = problemDescriptor.Proto;
-      this.description = description;
-    }
-
-    internal DescriptorValidationException(IDescriptor problemDescriptor, string description, Exception cause) :
-        base(problemDescriptor.FullName + ": " + description, cause) {
-
-      name = problemDescriptor.FullName;
-      proto = problemDescriptor.Proto;
-      this.description = description;
-    }
-  }
-}
+// 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.
+using System;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Thrown when building descriptors fails because the source DescriptorProtos
+    /// are not valid.
+    /// </summary>
+    public sealed class DescriptorValidationException : Exception
+    {
+        private readonly String name;
+        private readonly IMessage proto;
+        private readonly string description;
+
+        /// <value>
+        /// The full name of the descriptor where the error occurred.
+        /// </value>
+        public String ProblemSymbolName
+        {
+            get { return name; }
+        }
+
+        /// <value>
+        /// The protocol message representation of the invalid descriptor.
+        /// </value>
+        public IMessage ProblemProto
+        {
+            get { return proto; }
+        }
+
+        /// <value>
+        /// A human-readable description of the error. (The Message property
+        /// is made up of the descriptor's name and this description.)
+        /// </value>
+        public string Description
+        {
+            get { return description; }
+        }
+
+        internal DescriptorValidationException(IDescriptor problemDescriptor, string description) :
+            base(problemDescriptor.FullName + ": " + description)
+        {
+            // Note that problemDescriptor may be partially uninitialized, so we
+            // don't want to expose it directly to the user.  So, we only provide
+            // the name and the original proto.
+            name = problemDescriptor.FullName;
+            proto = problemDescriptor.Proto;
+            this.description = description;
+        }
+
+        internal DescriptorValidationException(IDescriptor problemDescriptor, string description, Exception cause) :
+            base(problemDescriptor.FullName + ": " + description, cause)
+        {
+            name = problemDescriptor.FullName;
+            proto = problemDescriptor.Proto;
+            this.description = description;
+        }
+    }
+}

+ 121 - 109
src/ProtocolBuffers/Descriptors/EnumDescriptor.cs

@@ -1,109 +1,121 @@
-// 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.
-using System.Collections.Generic;
-using Google.ProtocolBuffers.DescriptorProtos;
-
-namespace Google.ProtocolBuffers.Descriptors {
-
-  /// <summary>
-  /// Descriptor for an enum type in a .proto file.
-  /// </summary>
-  public sealed class EnumDescriptor : IndexedDescriptorBase<EnumDescriptorProto, EnumOptions>, IEnumLiteMap<EnumValueDescriptor> {
-
-    private readonly MessageDescriptor containingType;
-    private readonly IList<EnumValueDescriptor> values;
-
-    internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index)
-        : base(proto, file, ComputeFullName(file, parent, proto.Name), index) {
-      containingType = parent;
-
-      if (proto.ValueCount == 0) {
-        // We cannot allow enums with no values because this would mean there
-        // would be no valid default value for fields of this type.
-        throw new DescriptorValidationException(this, "Enums must contain at least one value.");
-      }
-      
-      values = DescriptorUtil.ConvertAndMakeReadOnly(proto.ValueList,
-          (value, i) => new EnumValueDescriptor(value, file, this, i));
-
-      File.DescriptorPool.AddSymbol(this);
-    }
-
-    /// <value>
-    /// If this is a nested type, get the outer descriptor, otherwise null.
-    /// </value>
-    public MessageDescriptor ContainingType {
-      get { return containingType; }
-    }
-
-    /// <value>
-    /// An unmodifiable list of defined value descriptors for this enum.
-    /// </value>
-    public IList<EnumValueDescriptor> Values {
-      get { return values; }
-    }
-
-    /// <summary>
-    /// Logic moved from FieldSet to continue current behavior
-    /// </summary>
-    public bool IsValidValue(IEnumLite value) {
-      return value is EnumValueDescriptor && ((EnumValueDescriptor)value).EnumDescriptor == this;
-    }
-
-    /// <summary>
-    /// Finds an enum value by number. If multiple enum values have the
-    /// same number, this returns the first defined value with that number.
-    /// </summary>
-    public EnumValueDescriptor FindValueByNumber(int number) {
-      return File.DescriptorPool.FindEnumValueByNumber(this, number);
-    }
-
-    IEnumLite IEnumLiteMap.FindValueByNumber(int number) {
-      return FindValueByNumber(number);
-    }
-    /// <summary>
-    /// Finds an enum value by name.
-    /// </summary>
-    /// <param name="name">The unqualified name of the value (e.g. "FOO").</param>
-    /// <returns>The value's descriptor, or null if not found.</returns>
-    public EnumValueDescriptor FindValueByName(string name) {
-      return File.DescriptorPool.FindSymbol<EnumValueDescriptor>(FullName + "." + name);
-    }
-
-    internal override void ReplaceProto(EnumDescriptorProto newProto) {
-      base.ReplaceProto(newProto);
-      for (int i = 0; i < values.Count; i++) {
-        values[i].ReplaceProto(newProto.GetValue(i));
-      }
-    }
-  }
-}
+// 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.
+using System.Collections.Generic;
+using Google.ProtocolBuffers.DescriptorProtos;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Descriptor for an enum type in a .proto file.
+    /// </summary>
+    public sealed class EnumDescriptor : IndexedDescriptorBase<EnumDescriptorProto, EnumOptions>,
+                                         IEnumLiteMap<EnumValueDescriptor>
+    {
+        private readonly MessageDescriptor containingType;
+        private readonly IList<EnumValueDescriptor> values;
+
+        internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index)
+            : base(proto, file, ComputeFullName(file, parent, proto.Name), index)
+        {
+            containingType = parent;
+
+            if (proto.ValueCount == 0)
+            {
+                // We cannot allow enums with no values because this would mean there
+                // would be no valid default value for fields of this type.
+                throw new DescriptorValidationException(this, "Enums must contain at least one value.");
+            }
+
+            values = DescriptorUtil.ConvertAndMakeReadOnly(proto.ValueList,
+                                                           (value, i) => new EnumValueDescriptor(value, file, this, i));
+
+            File.DescriptorPool.AddSymbol(this);
+        }
+
+        /// <value>
+        /// If this is a nested type, get the outer descriptor, otherwise null.
+        /// </value>
+        public MessageDescriptor ContainingType
+        {
+            get { return containingType; }
+        }
+
+        /// <value>
+        /// An unmodifiable list of defined value descriptors for this enum.
+        /// </value>
+        public IList<EnumValueDescriptor> Values
+        {
+            get { return values; }
+        }
+
+        /// <summary>
+        /// Logic moved from FieldSet to continue current behavior
+        /// </summary>
+        public bool IsValidValue(IEnumLite value)
+        {
+            return value is EnumValueDescriptor && ((EnumValueDescriptor) value).EnumDescriptor == this;
+        }
+
+        /// <summary>
+        /// Finds an enum value by number. If multiple enum values have the
+        /// same number, this returns the first defined value with that number.
+        /// </summary>
+        public EnumValueDescriptor FindValueByNumber(int number)
+        {
+            return File.DescriptorPool.FindEnumValueByNumber(this, number);
+        }
+
+        IEnumLite IEnumLiteMap.FindValueByNumber(int number)
+        {
+            return FindValueByNumber(number);
+        }
+
+        /// <summary>
+        /// Finds an enum value by name.
+        /// </summary>
+        /// <param name="name">The unqualified name of the value (e.g. "FOO").</param>
+        /// <returns>The value's descriptor, or null if not found.</returns>
+        public EnumValueDescriptor FindValueByName(string name)
+        {
+            return File.DescriptorPool.FindSymbol<EnumValueDescriptor>(FullName + "." + name);
+        }
+
+        internal override void ReplaceProto(EnumDescriptorProto newProto)
+        {
+            base.ReplaceProto(newProto);
+            for (int i = 0; i < values.Count; i++)
+            {
+                values[i].ReplaceProto(newProto.GetValue(i));
+            }
+        }
+    }
+}

+ 63 - 59
src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs

@@ -1,59 +1,63 @@
-// 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.
-using Google.ProtocolBuffers.DescriptorProtos;
-
-namespace Google.ProtocolBuffers.Descriptors {
-  
-  /// <summary>
-  /// Descriptor for a single enum value within an enum in a .proto file.
-  /// </summary>
-  public sealed class EnumValueDescriptor : IndexedDescriptorBase<EnumValueDescriptorProto, EnumValueOptions>, IEnumLite {
-
-    private readonly EnumDescriptor enumDescriptor;
-
-    internal EnumValueDescriptor(EnumValueDescriptorProto proto, FileDescriptor file,
-        EnumDescriptor parent, int index) 
-        : base (proto, file, parent.FullName + "." + proto.Name, index) {
-      enumDescriptor = parent;
-      file.DescriptorPool.AddSymbol(this);
-      file.DescriptorPool.AddEnumValueByNumber(this);
-    }
-
-    public int Number {
-      get { return Proto.Number; }
-    }
-
-    public EnumDescriptor EnumDescriptor {
-      get { return enumDescriptor; }
-    }
-  }
-}
+// 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.
+using Google.ProtocolBuffers.DescriptorProtos;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Descriptor for a single enum value within an enum in a .proto file.
+    /// </summary>
+    public sealed class EnumValueDescriptor : IndexedDescriptorBase<EnumValueDescriptorProto, EnumValueOptions>,
+                                              IEnumLite
+    {
+        private readonly EnumDescriptor enumDescriptor;
+
+        internal EnumValueDescriptor(EnumValueDescriptorProto proto, FileDescriptor file,
+                                     EnumDescriptor parent, int index)
+            : base(proto, file, parent.FullName + "." + proto.Name, index)
+        {
+            enumDescriptor = parent;
+            file.DescriptorPool.AddSymbol(this);
+            file.DescriptorPool.AddEnumValueByNumber(this);
+        }
+
+        public int Number
+        {
+            get { return Proto.Number; }
+        }
+
+        public EnumDescriptor EnumDescriptor
+        {
+            get { return enumDescriptor; }
+        }
+    }
+}

+ 666 - 521
src/ProtocolBuffers/Descriptors/FieldDescriptor.cs

@@ -1,521 +1,666 @@
-// 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.
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using Google.ProtocolBuffers.Collections;
-using Google.ProtocolBuffers.DescriptorProtos;
-
-namespace Google.ProtocolBuffers.Descriptors {
-  
-  /// <summary>
-  /// Descriptor for a field or extension within a message in a .proto file.
-  /// </summary>
-  public sealed class FieldDescriptor : IndexedDescriptorBase<FieldDescriptorProto, FieldOptions>, IComparable<FieldDescriptor>, IFieldDescriptorLite {
-
-    private readonly MessageDescriptor extensionScope;
-    private EnumDescriptor enumType;
-    private MessageDescriptor messageType;
-    private MessageDescriptor containingType;
-    private object defaultValue;
-    private FieldType fieldType;
-    private MappedType mappedType;
-
-    private CSharpFieldOptions csharpFieldOptions;
-    private readonly object optionsLock = new object();
-
-    internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file,
-        MessageDescriptor parent, int index, bool isExtension) 
-        : base(proto, file, ComputeFullName(file, parent, proto.Name), index) {
-      
-      if (proto.HasType) {
-        fieldType = GetFieldTypeFromProtoType(proto.Type);
-        mappedType = FieldTypeToMappedTypeMap[fieldType];
-      }
-      
-      if (FieldNumber <= 0) {
-        throw new DescriptorValidationException(this,
-          "Field numbers must be positive integers.");
-      }
-
-      if (isExtension) {
-        if (!proto.HasExtendee) {
-          throw new DescriptorValidationException(this,
-              "FieldDescriptorProto.Extendee not set for extension field.");
-        }
-        containingType = null;  // Will be filled in when cross-linking
-        if (parent != null) {
-          extensionScope = parent;
-        } else {
-          extensionScope = null;
-        }
-      } else {
-        if (proto.HasExtendee) {
-          throw new DescriptorValidationException(this,
-              "FieldDescriptorProto.Extendee set for non-extension field.");
-        }
-        containingType = parent;
-        extensionScope = null;
-      }
-
-      file.DescriptorPool.AddSymbol(this);
-    }
-
-    private CSharpFieldOptions BuildOrFakeCSharpOptions() {
-      // TODO(jonskeet): Check if we could use FileDescriptorProto.Descriptor.Name - interesting bootstrap issues
-      if (File.Proto.Name == "google/protobuf/csharp_options.proto") {
-        if (Name=="csharp_field_options") {
-          return new CSharpFieldOptions.Builder { PropertyName = "CSharpFieldOptions" }.Build();
-        }
-        if (Name=="csharp_file_options") {
-          return new CSharpFieldOptions.Builder { PropertyName = "CSharpFileOptions" }.Build();
-        }
-      }
-      CSharpFieldOptions.Builder builder = CSharpFieldOptions.CreateBuilder();
-      if (Proto.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFieldOptions)) {
-        builder.MergeFrom(Proto.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFieldOptions));
-      }
-      if (!builder.HasPropertyName) {
-        string fieldName = FieldType == FieldType.Group ? MessageType.Name : Name;
-        string propertyName = NameHelpers.UnderscoresToPascalCase(fieldName);
-        if (propertyName == ContainingType.Name) {
-          propertyName += "_";
-        }
-        builder.PropertyName = propertyName;
-      }
-      return builder.Build();
-    }
-
-    /// <summary>
-    /// Maps a field type as included in the .proto file to a FieldType.
-    /// </summary>
-    private static FieldType GetFieldTypeFromProtoType(FieldDescriptorProto.Types.Type type) {
-      switch (type) {
-        case FieldDescriptorProto.Types.Type.TYPE_DOUBLE:   return FieldType.Double;
-        case FieldDescriptorProto.Types.Type.TYPE_FLOAT:    return FieldType.Float;
-        case FieldDescriptorProto.Types.Type.TYPE_INT64:    return FieldType.Int64;
-        case FieldDescriptorProto.Types.Type.TYPE_UINT64:   return FieldType.UInt64;
-        case FieldDescriptorProto.Types.Type.TYPE_INT32:    return FieldType.Int32;
-        case FieldDescriptorProto.Types.Type.TYPE_FIXED64:  return FieldType.Fixed64;
-        case FieldDescriptorProto.Types.Type.TYPE_FIXED32:  return FieldType.Fixed32;
-        case FieldDescriptorProto.Types.Type.TYPE_BOOL:     return FieldType.Bool;
-        case FieldDescriptorProto.Types.Type.TYPE_STRING:   return FieldType.String;
-        case FieldDescriptorProto.Types.Type.TYPE_GROUP:    return FieldType.Group;
-        case FieldDescriptorProto.Types.Type.TYPE_MESSAGE:  return FieldType.Message;
-        case FieldDescriptorProto.Types.Type.TYPE_BYTES:    return FieldType.Bytes;
-        case FieldDescriptorProto.Types.Type.TYPE_UINT32:   return FieldType.UInt32;
-        case FieldDescriptorProto.Types.Type.TYPE_ENUM:     return FieldType.Enum;
-        case FieldDescriptorProto.Types.Type.TYPE_SFIXED32: return FieldType.SFixed32;
-        case FieldDescriptorProto.Types.Type.TYPE_SFIXED64: return FieldType.SFixed64;
-        case FieldDescriptorProto.Types.Type.TYPE_SINT32:   return FieldType.SInt32;
-        case FieldDescriptorProto.Types.Type.TYPE_SINT64:   return FieldType.SInt64;
-        default:
-          throw new ArgumentException("Invalid type specified");
-      }
-    }
-
-    /// <summary>
-    /// Returns the default value for a mapped type.
-    /// </summary>
-    private static object GetDefaultValueForMappedType(MappedType type) {
-      switch (type) {
-        case MappedType.Int32: return 0;
-        case MappedType.Int64: return (long) 0;
-        case MappedType.UInt32: return (uint) 0;
-        case MappedType.UInt64: return (ulong) 0;
-        case MappedType.Single: return (float) 0;
-        case MappedType.Double: return (double) 0;
-        case MappedType.Boolean: return false;
-        case MappedType.String: return "";
-        case MappedType.ByteString: return ByteString.Empty;
-        case MappedType.Message: return null;
-        case MappedType.Enum: return null;
-        default:
-            throw new ArgumentException("Invalid type specified");
-      }
-    }
-
-    public bool IsRequired {
-      get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_REQUIRED; }
-    }
-
-    public bool IsOptional {
-      get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_OPTIONAL; }
-    }
-
-    public bool IsRepeated {
-      get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_REPEATED; }
-    }
-
-    public bool IsPacked {
-      get { return Proto.Options.Packed; }
-    }
-
-    /// <valule>
-    /// Indicates whether or not the field had an explicitly-defined default value.
-    /// </value>
-    public bool HasDefaultValue {
-      get { return Proto.HasDefaultValue; }
-    }
-
-    /// <value>
-    /// The field's default value. Valid for all types except messages
-    /// and groups. For all other types, the object returned is of the
-    /// same class that would be returned by IMessage[this].
-    /// For repeated fields this will always be an empty immutable list compatible with IList[object].
-    /// For message fields it will always be null. For singular values, it will depend on the descriptor.
-    /// </value>
-    public object DefaultValue {
-      get {
-        if (MappedType == MappedType.Message) {
-          throw new InvalidOperationException("FieldDescriptor.DefaultValue called on an embedded message field.");
-        }
-        return defaultValue;
-      }
-    }
-
-    /// <value>
-    /// Indicates whether or not this field is an extension.
-    /// </value>
-    public bool IsExtension {
-      get { return Proto.HasExtendee; }
-    }
-
-    /*
-     * Get the field's containing type. For extensions, this is the type being
-     * extended, not the location where the extension was defined.  See
-     * {@link #getExtensionScope()}.
-     */
-    /// <summary>
-    /// Get the field's containing type. For extensions, this is the type being
-    /// extended, not the location where the extension was defined. See
-    /// <see cref="ExtensionScope" />.
-    /// </summary>
-    public MessageDescriptor ContainingType {
-      get { return containingType; }
-    }
-
-    /// <summary>
-    /// Returns the C#-specific options for this field descriptor. This will always be
-    /// completely filled in.
-    /// </summary>
-    public CSharpFieldOptions CSharpOptions {
-      get {
-        lock (optionsLock) {
-          if (csharpFieldOptions == null) {
-            csharpFieldOptions = BuildOrFakeCSharpOptions();
-          }
-        }
-        return csharpFieldOptions;
-      }
-    }
-    
-    /// <summary>
-    /// For extensions defined nested within message types, gets
-    /// the outer type. Not valid for non-extension fields.
-    /// </summary>
-    /// <example>
-    /// <code>
-    /// message Foo {
-    ///   extensions 1000 to max;
-    /// }
-    /// extend Foo {
-    ///   optional int32 baz = 1234;
-    /// }
-    /// message Bar {
-    ///   extend Foo {
-    ///     optional int32 qux = 4321;
-    ///   }
-    /// }
-    /// </code>
-    /// The containing type for both <c>baz</c> and <c>qux</c> is <c>Foo</c>.
-    /// However, the extension scope for <c>baz</c> is <c>null</c> while
-    /// the extension scope for <c>qux</c> is <c>Bar</c>.
-    /// </example>
-    public MessageDescriptor ExtensionScope {
-      get {
-        if (!IsExtension) {
-          throw new InvalidOperationException("This field is not an extension.");
-        }
-        return extensionScope;
-      }
-    }
-
-    public MappedType MappedType {
-      get { return mappedType; }
-    }
-
-    public FieldType FieldType {
-      get { return fieldType; }
-    }
-
-    public bool IsCLSCompliant {
-      get { return mappedType != MappedType.UInt32 && mappedType != MappedType.UInt64; }
-    }
-
-    public int FieldNumber {
-      get { return Proto.Number; }
-    }
-
-    /// <summary>
-    /// Compares this descriptor with another one, ordering in "canonical" order
-    /// which simply means ascending order by field number. <paramref name="other"/>
-    /// must be a field of the same type, i.e. the <see cref="ContainingType"/> of
-    /// both fields must be the same.
-    /// </summary>
-    public int CompareTo(FieldDescriptor other) {
-      if (other.containingType != containingType) {
-        throw new ArgumentException("FieldDescriptors can only be compared to other FieldDescriptors " +
-          "for fields of the same message type.");
-      }
-      return FieldNumber - other.FieldNumber;
-    }
-
-    /// <summary>
-    /// Compares this descriptor with another one, ordering in "canonical" order
-    /// which simply means ascending order by field number. <paramref name="other"/>
-    /// must be a field of the same type, i.e. the <see cref="ContainingType"/> of
-    /// both fields must be the same.
-    /// </summary>
-    public int CompareTo(IFieldDescriptorLite other) {
-      return FieldNumber - other.FieldNumber;
-    }
-
-    IEnumLiteMap IFieldDescriptorLite.EnumType {
-      get { return EnumType; }
-    }
-
-    bool IFieldDescriptorLite.MessageSetWireFormat {
-      get { return ContainingType.Options.MessageSetWireFormat; }
-    }
-
-      /// <summary>
-    /// For enum fields, returns the field's type.
-    /// </summary>
-    public EnumDescriptor EnumType {
-      get {
-        if (MappedType != MappedType.Enum) {
-          throw new InvalidOperationException("EnumType is only valid for enum fields.");
-        }
-        return enumType;
-      }
-    }
-
-    /// <summary>
-    /// For embedded message and group fields, returns the field's type.
-    /// </summary>
-    public MessageDescriptor MessageType {
-      get {
-        if (MappedType != MappedType.Message) {
-          throw new InvalidOperationException("MessageType is only valid for enum fields.");
-        }
-        return messageType;
-      }
-    }
-
-    /// <summary>
-    /// Immutable mapping from field type to mapped type. Built using the attributes on
-    /// FieldType values.
-    /// </summary>
-    public static readonly IDictionary<FieldType, MappedType> FieldTypeToMappedTypeMap = MapFieldTypes();
-
-    private static IDictionary<FieldType, MappedType> MapFieldTypes() {
-      var map = new Dictionary<FieldType, MappedType>();
-      foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public)) {
-        FieldType fieldType = (FieldType)field.GetValue(null);
-        FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0];
-        map[fieldType] = mapping.MappedType;
-      }
-      return Dictionaries.AsReadOnly(map);
-    }
-
-    /// <summary>
-    /// Look up and cross-link all field types etc.
-    /// </summary>
-    internal void CrossLink() {
-      if (Proto.HasExtendee) {
-        IDescriptor extendee = File.DescriptorPool.LookupSymbol(Proto.Extendee, this);
-        if (!(extendee is MessageDescriptor)) {
-          throw new DescriptorValidationException(this, "\"" + Proto.Extendee + "\" is not a message type.");
-        }
-        containingType = (MessageDescriptor) extendee;
-
-        if (!containingType.IsExtensionNumber(FieldNumber)) {
-          throw new DescriptorValidationException(this,
-              "\"" + containingType.FullName + "\" does not declare " + FieldNumber + " as an extension number.");
-        }
-      }
-
-      if (Proto.HasTypeName) {
-        IDescriptor typeDescriptor =
-          File.DescriptorPool.LookupSymbol(Proto.TypeName, this);
-
-        if (!Proto.HasType) {
-          // Choose field type based on symbol.
-          if (typeDescriptor is MessageDescriptor) {
-            fieldType = FieldType.Message;
-            mappedType = MappedType.Message;
-          } else if (typeDescriptor is EnumDescriptor) {
-            fieldType = FieldType.Enum;
-            mappedType = MappedType.Enum;
-          } else {
-            throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a type.");
-          }
-        }
-
-        if (MappedType == MappedType.Message) {
-          if (!(typeDescriptor is MessageDescriptor)) {
-            throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a message type.");
-          }
-          messageType = (MessageDescriptor) typeDescriptor;
-
-          if (Proto.HasDefaultValue) {
-            throw new DescriptorValidationException(this, "Messages can't have default values.");
-          }
-        } else if (MappedType == Descriptors.MappedType.Enum) {
-          if (!(typeDescriptor is EnumDescriptor)) {
-            throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not an enum type.");
-          }
-          enumType = (EnumDescriptor)typeDescriptor;
-        } else {
-          throw new DescriptorValidationException(this, "Field with primitive type has type_name.");
-        }
-      } else {
-        if (MappedType == MappedType.Message || MappedType == MappedType.Enum) {
-          throw new DescriptorValidationException(this, "Field with message or enum type missing type_name.");
-        }
-      }
-
-      // We don't attempt to parse the default value until here because for
-      // enums we need the enum type's descriptor.
-      if (Proto.HasDefaultValue) {
-        if (IsRepeated) {
-          throw new DescriptorValidationException(this, "Repeated fields cannot have default values.");
-        }
-
-        try {
-          switch (FieldType) {
-            case FieldType.Int32:
-            case FieldType.SInt32:
-            case FieldType.SFixed32:
-              defaultValue = TextFormat.ParseInt32(Proto.DefaultValue);
-              break;
-            case FieldType.UInt32:
-            case FieldType.Fixed32:
-              defaultValue = TextFormat.ParseUInt32(Proto.DefaultValue);
-              break;
-            case FieldType.Int64:
-            case FieldType.SInt64:
-            case FieldType.SFixed64:
-              defaultValue = TextFormat.ParseInt64(Proto.DefaultValue);
-              break;
-            case FieldType.UInt64:
-            case FieldType.Fixed64:
-              defaultValue = TextFormat.ParseUInt64(Proto.DefaultValue);
-              break;
-            case FieldType.Float:
-              defaultValue = TextFormat.ParseFloat(Proto.DefaultValue);
-              break;
-            case FieldType.Double:
-              defaultValue = TextFormat.ParseDouble(Proto.DefaultValue);
-              break;
-            case FieldType.Bool:
-              if (Proto.DefaultValue == "true") {
-                defaultValue = true;
-              } else if (Proto.DefaultValue == "false") {
-                defaultValue = false;
-              } else {
-                throw new FormatException("Boolean values must be \"true\" or \"false\"");
-              }
-              break;
-            case FieldType.String:
-              defaultValue = Proto.DefaultValue;
-              break;
-            case FieldType.Bytes:
-              try {
-                defaultValue = TextFormat.UnescapeBytes(Proto.DefaultValue);
-              } catch (FormatException e) {
-                throw new DescriptorValidationException(this, "Couldn't parse default value: " + e.Message);
-              }
-              break;
-            case FieldType.Enum:
-              defaultValue = enumType.FindValueByName(Proto.DefaultValue);
-              if (defaultValue == null) {
-                throw new DescriptorValidationException(this, "Unknown enum default value: \"" + Proto.DefaultValue + "\"");
-              }
-              break;
-            case FieldType.Message:
-            case FieldType.Group:
-              throw new DescriptorValidationException(this, "Message type had default value.");
-          }
-        } catch (FormatException e) {
-          DescriptorValidationException validationException =
-              new DescriptorValidationException(this, "Could not parse default value: \"" + Proto.DefaultValue + "\"", e);
-          throw validationException;
-        }
-      } else {
-        // Determine the default default for this field.
-        if (IsRepeated) {
-          defaultValue = Lists<object>.Empty;
-        } else {
-          switch (MappedType) {
-            case MappedType.Enum:
-              // We guarantee elsewhere that an enum type always has at least
-              // one possible value.
-              defaultValue = enumType.Values[0];
-              break;
-            case MappedType.Message:
-              defaultValue = null;
-              break;
-            default:
-              defaultValue = GetDefaultValueForMappedType(MappedType);
-              break;
-          }
-        }
-      }
-
-      if (!IsExtension) {
-        File.DescriptorPool.AddFieldByNumber(this);
-      }
-
-      if (containingType != null && containingType.Options.MessageSetWireFormat) {
-        if (IsExtension) {
-          if (!IsOptional || FieldType != FieldType.Message) {
-            throw new DescriptorValidationException(this, "Extensions of MessageSets must be optional messages.");
-          }
-        } else {
-          throw new DescriptorValidationException(this, "MessageSets cannot have fields, only extensions.");
-        }
-      }
-    }
-  }
-}
+// 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.
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Google.ProtocolBuffers.Collections;
+using Google.ProtocolBuffers.DescriptorProtos;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Descriptor for a field or extension within a message in a .proto file.
+    /// </summary>
+    public sealed class FieldDescriptor : IndexedDescriptorBase<FieldDescriptorProto, FieldOptions>,
+                                          IComparable<FieldDescriptor>, IFieldDescriptorLite
+    {
+        private readonly MessageDescriptor extensionScope;
+        private EnumDescriptor enumType;
+        private MessageDescriptor messageType;
+        private MessageDescriptor containingType;
+        private object defaultValue;
+        private FieldType fieldType;
+        private MappedType mappedType;
+
+        private CSharpFieldOptions csharpFieldOptions;
+        private readonly object optionsLock = new object();
+
+        internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file,
+                                 MessageDescriptor parent, int index, bool isExtension)
+            : base(proto, file, ComputeFullName(file, parent, proto.Name), index)
+        {
+            if (proto.HasType)
+            {
+                fieldType = GetFieldTypeFromProtoType(proto.Type);
+                mappedType = FieldTypeToMappedTypeMap[fieldType];
+            }
+
+            if (FieldNumber <= 0)
+            {
+                throw new DescriptorValidationException(this,
+                                                        "Field numbers must be positive integers.");
+            }
+
+            if (isExtension)
+            {
+                if (!proto.HasExtendee)
+                {
+                    throw new DescriptorValidationException(this,
+                                                            "FieldDescriptorProto.Extendee not set for extension field.");
+                }
+                containingType = null; // Will be filled in when cross-linking
+                if (parent != null)
+                {
+                    extensionScope = parent;
+                }
+                else
+                {
+                    extensionScope = null;
+                }
+            }
+            else
+            {
+                if (proto.HasExtendee)
+                {
+                    throw new DescriptorValidationException(this,
+                                                            "FieldDescriptorProto.Extendee set for non-extension field.");
+                }
+                containingType = parent;
+                extensionScope = null;
+            }
+
+            file.DescriptorPool.AddSymbol(this);
+        }
+
+        private CSharpFieldOptions BuildOrFakeCSharpOptions()
+        {
+            // TODO(jonskeet): Check if we could use FileDescriptorProto.Descriptor.Name - interesting bootstrap issues
+            if (File.Proto.Name == "google/protobuf/csharp_options.proto")
+            {
+                if (Name == "csharp_field_options")
+                {
+                    return new CSharpFieldOptions.Builder {PropertyName = "CSharpFieldOptions"}.Build();
+                }
+                if (Name == "csharp_file_options")
+                {
+                    return new CSharpFieldOptions.Builder {PropertyName = "CSharpFileOptions"}.Build();
+                }
+            }
+            CSharpFieldOptions.Builder builder = CSharpFieldOptions.CreateBuilder();
+            if (Proto.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFieldOptions))
+            {
+                builder.MergeFrom(Proto.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFieldOptions));
+            }
+            if (!builder.HasPropertyName)
+            {
+                string fieldName = FieldType == FieldType.Group ? MessageType.Name : Name;
+                string propertyName = NameHelpers.UnderscoresToPascalCase(fieldName);
+                if (propertyName == ContainingType.Name)
+                {
+                    propertyName += "_";
+                }
+                builder.PropertyName = propertyName;
+            }
+            return builder.Build();
+        }
+
+        /// <summary>
+        /// Maps a field type as included in the .proto file to a FieldType.
+        /// </summary>
+        private static FieldType GetFieldTypeFromProtoType(FieldDescriptorProto.Types.Type type)
+        {
+            switch (type)
+            {
+                case FieldDescriptorProto.Types.Type.TYPE_DOUBLE:
+                    return FieldType.Double;
+                case FieldDescriptorProto.Types.Type.TYPE_FLOAT:
+                    return FieldType.Float;
+                case FieldDescriptorProto.Types.Type.TYPE_INT64:
+                    return FieldType.Int64;
+                case FieldDescriptorProto.Types.Type.TYPE_UINT64:
+                    return FieldType.UInt64;
+                case FieldDescriptorProto.Types.Type.TYPE_INT32:
+                    return FieldType.Int32;
+                case FieldDescriptorProto.Types.Type.TYPE_FIXED64:
+                    return FieldType.Fixed64;
+                case FieldDescriptorProto.Types.Type.TYPE_FIXED32:
+                    return FieldType.Fixed32;
+                case FieldDescriptorProto.Types.Type.TYPE_BOOL:
+                    return FieldType.Bool;
+                case FieldDescriptorProto.Types.Type.TYPE_STRING:
+                    return FieldType.String;
+                case FieldDescriptorProto.Types.Type.TYPE_GROUP:
+                    return FieldType.Group;
+                case FieldDescriptorProto.Types.Type.TYPE_MESSAGE:
+                    return FieldType.Message;
+                case FieldDescriptorProto.Types.Type.TYPE_BYTES:
+                    return FieldType.Bytes;
+                case FieldDescriptorProto.Types.Type.TYPE_UINT32:
+                    return FieldType.UInt32;
+                case FieldDescriptorProto.Types.Type.TYPE_ENUM:
+                    return FieldType.Enum;
+                case FieldDescriptorProto.Types.Type.TYPE_SFIXED32:
+                    return FieldType.SFixed32;
+                case FieldDescriptorProto.Types.Type.TYPE_SFIXED64:
+                    return FieldType.SFixed64;
+                case FieldDescriptorProto.Types.Type.TYPE_SINT32:
+                    return FieldType.SInt32;
+                case FieldDescriptorProto.Types.Type.TYPE_SINT64:
+                    return FieldType.SInt64;
+                default:
+                    throw new ArgumentException("Invalid type specified");
+            }
+        }
+
+        /// <summary>
+        /// Returns the default value for a mapped type.
+        /// </summary>
+        private static object GetDefaultValueForMappedType(MappedType type)
+        {
+            switch (type)
+            {
+                case MappedType.Int32:
+                    return 0;
+                case MappedType.Int64:
+                    return (long) 0;
+                case MappedType.UInt32:
+                    return (uint) 0;
+                case MappedType.UInt64:
+                    return (ulong) 0;
+                case MappedType.Single:
+                    return (float) 0;
+                case MappedType.Double:
+                    return (double) 0;
+                case MappedType.Boolean:
+                    return false;
+                case MappedType.String:
+                    return "";
+                case MappedType.ByteString:
+                    return ByteString.Empty;
+                case MappedType.Message:
+                    return null;
+                case MappedType.Enum:
+                    return null;
+                default:
+                    throw new ArgumentException("Invalid type specified");
+            }
+        }
+
+        public bool IsRequired
+        {
+            get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_REQUIRED; }
+        }
+
+        public bool IsOptional
+        {
+            get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_OPTIONAL; }
+        }
+
+        public bool IsRepeated
+        {
+            get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_REPEATED; }
+        }
+
+        public bool IsPacked
+        {
+            get { return Proto.Options.Packed; }
+        }
+
+        /// <valule>
+        /// Indicates whether or not the field had an explicitly-defined default value.
+        /// </value>
+        public bool HasDefaultValue
+        {
+            get { return Proto.HasDefaultValue; }
+        }
+
+        /// <value>
+        /// The field's default value. Valid for all types except messages
+        /// and groups. For all other types, the object returned is of the
+        /// same class that would be returned by IMessage[this].
+        /// For repeated fields this will always be an empty immutable list compatible with IList[object].
+        /// For message fields it will always be null. For singular values, it will depend on the descriptor.
+        /// </value>
+        public object DefaultValue
+        {
+            get
+            {
+                if (MappedType == MappedType.Message)
+                {
+                    throw new InvalidOperationException(
+                        "FieldDescriptor.DefaultValue called on an embedded message field.");
+                }
+                return defaultValue;
+            }
+        }
+
+        /// <value>
+        /// Indicates whether or not this field is an extension.
+        /// </value>
+        public bool IsExtension
+        {
+            get { return Proto.HasExtendee; }
+        }
+
+        /*
+     * Get the field's containing type. For extensions, this is the type being
+     * extended, not the location where the extension was defined.  See
+     * {@link #getExtensionScope()}.
+     */
+
+        /// <summary>
+        /// Get the field's containing type. For extensions, this is the type being
+        /// extended, not the location where the extension was defined. See
+        /// <see cref="ExtensionScope" />.
+        /// </summary>
+        public MessageDescriptor ContainingType
+        {
+            get { return containingType; }
+        }
+
+        /// <summary>
+        /// Returns the C#-specific options for this field descriptor. This will always be
+        /// completely filled in.
+        /// </summary>
+        public CSharpFieldOptions CSharpOptions
+        {
+            get
+            {
+                lock (optionsLock)
+                {
+                    if (csharpFieldOptions == null)
+                    {
+                        csharpFieldOptions = BuildOrFakeCSharpOptions();
+                    }
+                }
+                return csharpFieldOptions;
+            }
+        }
+
+        /// <summary>
+        /// For extensions defined nested within message types, gets
+        /// the outer type. Not valid for non-extension fields.
+        /// </summary>
+        /// <example>
+        /// <code>
+        /// message Foo {
+        ///   extensions 1000 to max;
+        /// }
+        /// extend Foo {
+        ///   optional int32 baz = 1234;
+        /// }
+        /// message Bar {
+        ///   extend Foo {
+        ///     optional int32 qux = 4321;
+        ///   }
+        /// }
+        /// </code>
+        /// The containing type for both <c>baz</c> and <c>qux</c> is <c>Foo</c>.
+        /// However, the extension scope for <c>baz</c> is <c>null</c> while
+        /// the extension scope for <c>qux</c> is <c>Bar</c>.
+        /// </example>
+        public MessageDescriptor ExtensionScope
+        {
+            get
+            {
+                if (!IsExtension)
+                {
+                    throw new InvalidOperationException("This field is not an extension.");
+                }
+                return extensionScope;
+            }
+        }
+
+        public MappedType MappedType
+        {
+            get { return mappedType; }
+        }
+
+        public FieldType FieldType
+        {
+            get { return fieldType; }
+        }
+
+        public bool IsCLSCompliant
+        {
+            get { return mappedType != MappedType.UInt32 && mappedType != MappedType.UInt64; }
+        }
+
+        public int FieldNumber
+        {
+            get { return Proto.Number; }
+        }
+
+        /// <summary>
+        /// Compares this descriptor with another one, ordering in "canonical" order
+        /// which simply means ascending order by field number. <paramref name="other"/>
+        /// must be a field of the same type, i.e. the <see cref="ContainingType"/> of
+        /// both fields must be the same.
+        /// </summary>
+        public int CompareTo(FieldDescriptor other)
+        {
+            if (other.containingType != containingType)
+            {
+                throw new ArgumentException("FieldDescriptors can only be compared to other FieldDescriptors " +
+                                            "for fields of the same message type.");
+            }
+            return FieldNumber - other.FieldNumber;
+        }
+
+        /// <summary>
+        /// Compares this descriptor with another one, ordering in "canonical" order
+        /// which simply means ascending order by field number. <paramref name="other"/>
+        /// must be a field of the same type, i.e. the <see cref="ContainingType"/> of
+        /// both fields must be the same.
+        /// </summary>
+        public int CompareTo(IFieldDescriptorLite other)
+        {
+            return FieldNumber - other.FieldNumber;
+        }
+
+        IEnumLiteMap IFieldDescriptorLite.EnumType
+        {
+            get { return EnumType; }
+        }
+
+        bool IFieldDescriptorLite.MessageSetWireFormat
+        {
+            get { return ContainingType.Options.MessageSetWireFormat; }
+        }
+
+        /// <summary>
+        /// For enum fields, returns the field's type.
+        /// </summary>
+        public EnumDescriptor EnumType
+        {
+            get
+            {
+                if (MappedType != MappedType.Enum)
+                {
+                    throw new InvalidOperationException("EnumType is only valid for enum fields.");
+                }
+                return enumType;
+            }
+        }
+
+        /// <summary>
+        /// For embedded message and group fields, returns the field's type.
+        /// </summary>
+        public MessageDescriptor MessageType
+        {
+            get
+            {
+                if (MappedType != MappedType.Message)
+                {
+                    throw new InvalidOperationException("MessageType is only valid for enum fields.");
+                }
+                return messageType;
+            }
+        }
+
+        /// <summary>
+        /// Immutable mapping from field type to mapped type. Built using the attributes on
+        /// FieldType values.
+        /// </summary>
+        public static readonly IDictionary<FieldType, MappedType> FieldTypeToMappedTypeMap = MapFieldTypes();
+
+        private static IDictionary<FieldType, MappedType> MapFieldTypes()
+        {
+            var map = new Dictionary<FieldType, MappedType>();
+            foreach (FieldInfo field in typeof (FieldType).GetFields(BindingFlags.Static | BindingFlags.Public))
+            {
+                FieldType fieldType = (FieldType) field.GetValue(null);
+                FieldMappingAttribute mapping =
+                    (FieldMappingAttribute) field.GetCustomAttributes(typeof (FieldMappingAttribute), false)[0];
+                map[fieldType] = mapping.MappedType;
+            }
+            return Dictionaries.AsReadOnly(map);
+        }
+
+        /// <summary>
+        /// Look up and cross-link all field types etc.
+        /// </summary>
+        internal void CrossLink()
+        {
+            if (Proto.HasExtendee)
+            {
+                IDescriptor extendee = File.DescriptorPool.LookupSymbol(Proto.Extendee, this);
+                if (!(extendee is MessageDescriptor))
+                {
+                    throw new DescriptorValidationException(this, "\"" + Proto.Extendee + "\" is not a message type.");
+                }
+                containingType = (MessageDescriptor) extendee;
+
+                if (!containingType.IsExtensionNumber(FieldNumber))
+                {
+                    throw new DescriptorValidationException(this,
+                                                            "\"" + containingType.FullName + "\" does not declare " +
+                                                            FieldNumber + " as an extension number.");
+                }
+            }
+
+            if (Proto.HasTypeName)
+            {
+                IDescriptor typeDescriptor =
+                    File.DescriptorPool.LookupSymbol(Proto.TypeName, this);
+
+                if (!Proto.HasType)
+                {
+                    // Choose field type based on symbol.
+                    if (typeDescriptor is MessageDescriptor)
+                    {
+                        fieldType = FieldType.Message;
+                        mappedType = MappedType.Message;
+                    }
+                    else if (typeDescriptor is EnumDescriptor)
+                    {
+                        fieldType = FieldType.Enum;
+                        mappedType = MappedType.Enum;
+                    }
+                    else
+                    {
+                        throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a type.");
+                    }
+                }
+
+                if (MappedType == MappedType.Message)
+                {
+                    if (!(typeDescriptor is MessageDescriptor))
+                    {
+                        throw new DescriptorValidationException(this,
+                                                                "\"" + Proto.TypeName + "\" is not a message type.");
+                    }
+                    messageType = (MessageDescriptor) typeDescriptor;
+
+                    if (Proto.HasDefaultValue)
+                    {
+                        throw new DescriptorValidationException(this, "Messages can't have default values.");
+                    }
+                }
+                else if (MappedType == Descriptors.MappedType.Enum)
+                {
+                    if (!(typeDescriptor is EnumDescriptor))
+                    {
+                        throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not an enum type.");
+                    }
+                    enumType = (EnumDescriptor) typeDescriptor;
+                }
+                else
+                {
+                    throw new DescriptorValidationException(this, "Field with primitive type has type_name.");
+                }
+            }
+            else
+            {
+                if (MappedType == MappedType.Message || MappedType == MappedType.Enum)
+                {
+                    throw new DescriptorValidationException(this, "Field with message or enum type missing type_name.");
+                }
+            }
+
+            // We don't attempt to parse the default value until here because for
+            // enums we need the enum type's descriptor.
+            if (Proto.HasDefaultValue)
+            {
+                if (IsRepeated)
+                {
+                    throw new DescriptorValidationException(this, "Repeated fields cannot have default values.");
+                }
+
+                try
+                {
+                    switch (FieldType)
+                    {
+                        case FieldType.Int32:
+                        case FieldType.SInt32:
+                        case FieldType.SFixed32:
+                            defaultValue = TextFormat.ParseInt32(Proto.DefaultValue);
+                            break;
+                        case FieldType.UInt32:
+                        case FieldType.Fixed32:
+                            defaultValue = TextFormat.ParseUInt32(Proto.DefaultValue);
+                            break;
+                        case FieldType.Int64:
+                        case FieldType.SInt64:
+                        case FieldType.SFixed64:
+                            defaultValue = TextFormat.ParseInt64(Proto.DefaultValue);
+                            break;
+                        case FieldType.UInt64:
+                        case FieldType.Fixed64:
+                            defaultValue = TextFormat.ParseUInt64(Proto.DefaultValue);
+                            break;
+                        case FieldType.Float:
+                            defaultValue = TextFormat.ParseFloat(Proto.DefaultValue);
+                            break;
+                        case FieldType.Double:
+                            defaultValue = TextFormat.ParseDouble(Proto.DefaultValue);
+                            break;
+                        case FieldType.Bool:
+                            if (Proto.DefaultValue == "true")
+                            {
+                                defaultValue = true;
+                            }
+                            else if (Proto.DefaultValue == "false")
+                            {
+                                defaultValue = false;
+                            }
+                            else
+                            {
+                                throw new FormatException("Boolean values must be \"true\" or \"false\"");
+                            }
+                            break;
+                        case FieldType.String:
+                            defaultValue = Proto.DefaultValue;
+                            break;
+                        case FieldType.Bytes:
+                            try
+                            {
+                                defaultValue = TextFormat.UnescapeBytes(Proto.DefaultValue);
+                            }
+                            catch (FormatException e)
+                            {
+                                throw new DescriptorValidationException(this,
+                                                                        "Couldn't parse default value: " + e.Message);
+                            }
+                            break;
+                        case FieldType.Enum:
+                            defaultValue = enumType.FindValueByName(Proto.DefaultValue);
+                            if (defaultValue == null)
+                            {
+                                throw new DescriptorValidationException(this,
+                                                                        "Unknown enum default value: \"" +
+                                                                        Proto.DefaultValue + "\"");
+                            }
+                            break;
+                        case FieldType.Message:
+                        case FieldType.Group:
+                            throw new DescriptorValidationException(this, "Message type had default value.");
+                    }
+                }
+                catch (FormatException e)
+                {
+                    DescriptorValidationException validationException =
+                        new DescriptorValidationException(this,
+                                                          "Could not parse default value: \"" + Proto.DefaultValue +
+                                                          "\"", e);
+                    throw validationException;
+                }
+            }
+            else
+            {
+                // Determine the default default for this field.
+                if (IsRepeated)
+                {
+                    defaultValue = Lists<object>.Empty;
+                }
+                else
+                {
+                    switch (MappedType)
+                    {
+                        case MappedType.Enum:
+                            // We guarantee elsewhere that an enum type always has at least
+                            // one possible value.
+                            defaultValue = enumType.Values[0];
+                            break;
+                        case MappedType.Message:
+                            defaultValue = null;
+                            break;
+                        default:
+                            defaultValue = GetDefaultValueForMappedType(MappedType);
+                            break;
+                    }
+                }
+            }
+
+            if (!IsExtension)
+            {
+                File.DescriptorPool.AddFieldByNumber(this);
+            }
+
+            if (containingType != null && containingType.Options.MessageSetWireFormat)
+            {
+                if (IsExtension)
+                {
+                    if (!IsOptional || FieldType != FieldType.Message)
+                    {
+                        throw new DescriptorValidationException(this,
+                                                                "Extensions of MessageSets must be optional messages.");
+                    }
+                }
+                else
+                {
+                    throw new DescriptorValidationException(this, "MessageSets cannot have fields, only extensions.");
+                }
+            }
+        }
+    }
+}

+ 88 - 77
src/ProtocolBuffers/Descriptors/FieldMappingAttribute.cs

@@ -1,77 +1,88 @@
-// 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.
-using System;
-using System.Collections.Generic;
-using Google.ProtocolBuffers.Collections;
-
-namespace Google.ProtocolBuffers.Descriptors {
-
-  /// <summary>
-  /// Defined specifically for the <see cref="FieldType" /> enumeration,
-  /// this allows each field type to specify the mapped type and wire type.
-  /// </summary>
-  [CLSCompliant(false)]
-  [AttributeUsage(AttributeTargets.Field)]
-  public sealed class FieldMappingAttribute : Attribute {
-    public FieldMappingAttribute(MappedType mappedType, WireFormat.WireType wireType) {
-      MappedType = mappedType;
-      WireType = wireType;
-    }
-
-    public MappedType MappedType { get; private set; }
-    public WireFormat.WireType WireType { get; private set; }
-
-
-    /// <summary>
-    /// Immutable mapping from field type to mapped type. Built using the attributes on
-    /// FieldType values.
-    /// </summary>
-    static readonly IDictionary<FieldType, FieldMappingAttribute> FieldTypeToMappedTypeMap = MapFieldTypes();
-
-    private static IDictionary<FieldType, FieldMappingAttribute> MapFieldTypes() {
-      var map = new Dictionary<FieldType, FieldMappingAttribute>();
-      foreach (System.Reflection.FieldInfo field in typeof(FieldType).GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)) {
-        FieldType fieldType = (FieldType)field.GetValue(null);
-        FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0];
-        map[fieldType] = mapping;
-      }
-      return Dictionaries.AsReadOnly(map);
-    }
-
-    internal static MappedType MappedTypeFromFieldType(FieldType type) {
-      return FieldTypeToMappedTypeMap[type].MappedType;
-    }
-    internal static WireFormat.WireType WireTypeFromFieldType(FieldType type, bool packed) {
-      return packed ? WireFormat.WireType.LengthDelimited : FieldTypeToMappedTypeMap[type].WireType;
-    }
-  }
-}
+// 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.
+using System;
+using System.Collections.Generic;
+using Google.ProtocolBuffers.Collections;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Defined specifically for the <see cref="FieldType" /> enumeration,
+    /// this allows each field type to specify the mapped type and wire type.
+    /// </summary>
+    [CLSCompliant(false)]
+    [AttributeUsage(AttributeTargets.Field)]
+    public sealed class FieldMappingAttribute : Attribute
+    {
+        public FieldMappingAttribute(MappedType mappedType, WireFormat.WireType wireType)
+        {
+            MappedType = mappedType;
+            WireType = wireType;
+        }
+
+        public MappedType MappedType { get; private set; }
+        public WireFormat.WireType WireType { get; private set; }
+
+
+        /// <summary>
+        /// Immutable mapping from field type to mapped type. Built using the attributes on
+        /// FieldType values.
+        /// </summary>
+        private static readonly IDictionary<FieldType, FieldMappingAttribute> FieldTypeToMappedTypeMap = MapFieldTypes();
+
+        private static IDictionary<FieldType, FieldMappingAttribute> MapFieldTypes()
+        {
+            var map = new Dictionary<FieldType, FieldMappingAttribute>();
+            foreach (
+                System.Reflection.FieldInfo field in
+                    typeof (FieldType).GetFields(System.Reflection.BindingFlags.Static |
+                                                 System.Reflection.BindingFlags.Public))
+            {
+                FieldType fieldType = (FieldType) field.GetValue(null);
+                FieldMappingAttribute mapping =
+                    (FieldMappingAttribute) field.GetCustomAttributes(typeof (FieldMappingAttribute), false)[0];
+                map[fieldType] = mapping;
+            }
+            return Dictionaries.AsReadOnly(map);
+        }
+
+        internal static MappedType MappedTypeFromFieldType(FieldType type)
+        {
+            return FieldTypeToMappedTypeMap[type].MappedType;
+        }
+
+        internal static WireFormat.WireType WireTypeFromFieldType(FieldType type, bool packed)
+        {
+            return packed ? WireFormat.WireType.LengthDelimited : FieldTypeToMappedTypeMap[type].WireType;
+        }
+    }
+}

+ 60 - 58
src/ProtocolBuffers/Descriptors/FieldType.cs

@@ -1,58 +1,60 @@
-// 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.
-
-namespace Google.ProtocolBuffers.Descriptors {
-  /// <summary>
-  /// Enumeration of all the possible field types. The odd formatting is to make it very clear
-  /// which attribute applies to which value, while maintaining a compact format.
-  /// </summary>
-  public enum FieldType {
-    [FieldMapping(MappedType.Double, WireFormat.WireType.Fixed64)] Double,
-    [FieldMapping(MappedType.Single, WireFormat.WireType.Fixed32)] Float,
-    [FieldMapping(MappedType.Int64, WireFormat.WireType.Varint)] Int64,
-    [FieldMapping(MappedType.UInt64, WireFormat.WireType.Varint)] UInt64,
-    [FieldMapping(MappedType.Int32, WireFormat.WireType.Varint)] Int32,
-    [FieldMapping(MappedType.UInt64, WireFormat.WireType.Fixed64)] Fixed64,
-    [FieldMapping(MappedType.UInt32, WireFormat.WireType.Fixed32)] Fixed32,
-    [FieldMapping(MappedType.Boolean, WireFormat.WireType.Varint)] Bool,
-    [FieldMapping(MappedType.String, WireFormat.WireType.LengthDelimited)] String,
-    [FieldMapping(MappedType.Message, WireFormat.WireType.StartGroup)] Group,
-    [FieldMapping(MappedType.Message, WireFormat.WireType.LengthDelimited)] Message,
-    [FieldMapping(MappedType.ByteString, WireFormat.WireType.LengthDelimited)] Bytes,
-    [FieldMapping(MappedType.UInt32, WireFormat.WireType.Varint)] UInt32,
-    [FieldMapping(MappedType.Int32, WireFormat.WireType.Fixed32)] SFixed32,
-    [FieldMapping(MappedType.Int64, WireFormat.WireType.Fixed64)] SFixed64,
-    [FieldMapping(MappedType.Int32, WireFormat.WireType.Varint)] SInt32,
-    [FieldMapping(MappedType.Int64, WireFormat.WireType.Varint)] SInt64,
-    [FieldMapping(MappedType.Enum, WireFormat.WireType.Varint)] Enum
-  }
-}
+// 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.
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Enumeration of all the possible field types. The odd formatting is to make it very clear
+    /// which attribute applies to which value, while maintaining a compact format.
+    /// </summary>
+    public enum FieldType
+    {
+        [FieldMapping(MappedType.Double, WireFormat.WireType.Fixed64)] Double,
+        [FieldMapping(MappedType.Single, WireFormat.WireType.Fixed32)] Float,
+        [FieldMapping(MappedType.Int64, WireFormat.WireType.Varint)] Int64,
+        [FieldMapping(MappedType.UInt64, WireFormat.WireType.Varint)] UInt64,
+        [FieldMapping(MappedType.Int32, WireFormat.WireType.Varint)] Int32,
+        [FieldMapping(MappedType.UInt64, WireFormat.WireType.Fixed64)] Fixed64,
+        [FieldMapping(MappedType.UInt32, WireFormat.WireType.Fixed32)] Fixed32,
+        [FieldMapping(MappedType.Boolean, WireFormat.WireType.Varint)] Bool,
+        [FieldMapping(MappedType.String, WireFormat.WireType.LengthDelimited)] String,
+        [FieldMapping(MappedType.Message, WireFormat.WireType.StartGroup)] Group,
+        [FieldMapping(MappedType.Message, WireFormat.WireType.LengthDelimited)] Message,
+        [FieldMapping(MappedType.ByteString, WireFormat.WireType.LengthDelimited)] Bytes,
+        [FieldMapping(MappedType.UInt32, WireFormat.WireType.Varint)] UInt32,
+        [FieldMapping(MappedType.Int32, WireFormat.WireType.Fixed32)] SFixed32,
+        [FieldMapping(MappedType.Int64, WireFormat.WireType.Fixed64)] SFixed64,
+        [FieldMapping(MappedType.Int32, WireFormat.WireType.Varint)] SInt32,
+        [FieldMapping(MappedType.Int64, WireFormat.WireType.Varint)] SInt64,
+        [FieldMapping(MappedType.Enum, WireFormat.WireType.Varint)] Enum
+    }
+}

+ 495 - 431
src/ProtocolBuffers/Descriptors/FileDescriptor.cs

@@ -1,432 +1,496 @@
-// 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.
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using Google.ProtocolBuffers.DescriptorProtos;
-using FileOptions = Google.ProtocolBuffers.DescriptorProtos.FileOptions;
-
-namespace Google.ProtocolBuffers.Descriptors {
-  /// <summary>
-  /// Describes a .proto file, including everything defined within.
-  /// IDescriptor is implemented such that the File property returns this descriptor,
-  /// and the FullName is the same as the Name.
-  /// </summary>
-  public sealed class FileDescriptor : IDescriptor<FileDescriptorProto> {
-    private FileDescriptorProto proto;
-    private readonly IList<MessageDescriptor> messageTypes;
-    private readonly IList<EnumDescriptor> enumTypes;
-    private readonly IList<ServiceDescriptor> services;
-    private readonly IList<FieldDescriptor> extensions;
-    private readonly IList<FileDescriptor> dependencies;
-    private readonly DescriptorPool pool;
-    private CSharpFileOptions csharpFileOptions;
-    private readonly object optionsLock = new object();
-
-    private FileDescriptor(FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool) {
-      this.pool = pool;
-      this.proto = proto;
-      this.dependencies = new ReadOnlyCollection<FileDescriptor>((FileDescriptor[]) dependencies.Clone());
-
-      pool.AddPackage(Package, this);
-
-      messageTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.MessageTypeList,
-                                                           (message, index) =>
-                                                           new MessageDescriptor(message, this, null, index));
-
-      enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumTypeList,
-                                                        (enumType, index) =>
-                                                        new EnumDescriptor(enumType, this, null, index));
-
-      services = DescriptorUtil.ConvertAndMakeReadOnly(proto.ServiceList,
-                                                       (service, index) => new ServiceDescriptor(service, this, index));
-
-      extensions = DescriptorUtil.ConvertAndMakeReadOnly(proto.ExtensionList,
-                                                         (field, index) =>
-                                                         new FieldDescriptor(field, this, null, index, true));
-    }
-
-
-    /// <summary>
-    /// Allows a file descriptor to be configured with a set of external options, e.g. from the
-    /// command-line arguments to protogen.
-    /// </summary>
-    public void ConfigureWithDefaultOptions(CSharpFileOptions options) {
-      csharpFileOptions = BuildOrFakeWithDefaultOptions(options);
-    }
-
-    private CSharpFileOptions BuildOrFakeWithDefaultOptions(CSharpFileOptions defaultOptions) {
-      // Fix for being able to relocate these files to any directory structure
-      if (proto.Package == "google.protobuf") {
-        string filename = Path.GetFileName(proto.Name);
-        // TODO(jonskeet): Check if we could use FileDescriptorProto.Descriptor.Name - interesting bootstrap issues)
-        if (filename == "descriptor.proto") {
-          return new CSharpFileOptions.Builder {
-            Namespace = "Google.ProtocolBuffers.DescriptorProtos",
-            UmbrellaClassname = "DescriptorProtoFile",
-            NestClasses = false,
-            MultipleFiles = false,
-            PublicClasses = true,
-            OutputDirectory = defaultOptions.OutputDirectory,
-            IgnoreGoogleProtobuf = defaultOptions.IgnoreGoogleProtobuf
-          }.Build();
-        }
-        if (filename == "csharp_options.proto") {
-          return new CSharpFileOptions.Builder {
-            Namespace = "Google.ProtocolBuffers.DescriptorProtos",
-            UmbrellaClassname = "CSharpOptions",
-            NestClasses = false,
-            MultipleFiles = false,
-            PublicClasses = true,
-            OutputDirectory = defaultOptions.OutputDirectory,
-            IgnoreGoogleProtobuf = defaultOptions.IgnoreGoogleProtobuf
-          }.Build();
-        }
-      }
-      CSharpFileOptions.Builder builder = defaultOptions.ToBuilder();
-      if (proto.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions)) {
-        builder.MergeFrom(proto.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions));
-      }
-      if (!builder.HasNamespace) {
-        builder.Namespace = Package;
-      }
-      if (!builder.HasUmbrellaClassname) {
-        int lastSlash = Name.LastIndexOf('/');
-        string baseName = Name.Substring(lastSlash + 1);
-        builder.UmbrellaClassname = NameHelpers.UnderscoresToPascalCase(NameHelpers.StripProto(baseName));
-      }
-
-      // Auto-fix for name collision by placing umbrella class into a new namespace.  This
-      // still won't fix the collisions with nesting enabled; however, you have to turn that on explicitly anyway.
-      if (!builder.NestClasses && !builder.HasUmbrellaNamespace) {
-        bool collision = false;
-        foreach (IDescriptor d in MessageTypes) {
-          collision |= d.Name == builder.UmbrellaClassname;
-        }
-        foreach (IDescriptor d in Services) {
-          collision |= d.Name == builder.UmbrellaClassname;
-        }
-        foreach (IDescriptor d in EnumTypes) {
-          collision |= d.Name == builder.UmbrellaClassname;
-        }
-        if (collision) {
-          builder.UmbrellaNamespace = "Proto";
-        }
-      }
-
-      return builder.Build();
-    }
-
-    /// <value>
-    /// The descriptor in its protocol message representation.
-    /// </value>
-    public FileDescriptorProto Proto {
-      get { return proto; }
-    }
-
-    /// <value>
-    /// The <see cref="DescriptorProtos.FileOptions" /> defined in <c>descriptor.proto</c>.
-    /// </value>
-    public FileOptions Options {
-      get { return proto.Options; }
-    }
-
-    /// <summary>
-    /// Returns the C#-specific options for this file descriptor. This will always be
-    /// completely filled in.
-    /// </summary>
-    public CSharpFileOptions CSharpOptions {
-      get {
-        lock (optionsLock) {
-          if (csharpFileOptions == null) {
-            csharpFileOptions = BuildOrFakeWithDefaultOptions(CSharpFileOptions.DefaultInstance);
-          }
-        }
-        return csharpFileOptions;
-      }
-    }
-
-    /// <value>
-    /// The file name.
-    /// </value>
-    public string Name {
-      get { return proto.Name; }
-    }
-
-    /// <summary>
-    /// The package as declared in the .proto file. This may or may not
-    /// be equivalent to the .NET namespace of the generated classes.
-    /// </summary>
-    public string Package {
-      get { return proto.Package; }
-    }
-
-    /// <value>
-    /// Unmodifiable list of top-level message types declared in this file.
-    /// </value>
-    public IList<MessageDescriptor> MessageTypes {
-      get { return messageTypes; }
-    }
-
-    /// <value>
-    /// Unmodifiable list of top-level enum types declared in this file.
-    /// </value>
-    public IList<EnumDescriptor> EnumTypes {
-      get { return enumTypes; }
-    }
-
-    /// <value>
-    /// Unmodifiable list of top-level services declared in this file.
-    /// </value>
-    public IList<ServiceDescriptor> Services {
-      get { return services; }
-    }
-
-    /// <value>
-    /// Unmodifiable list of top-level extensions declared in this file.
-    /// </value>
-    public IList<FieldDescriptor> Extensions {
-      get { return extensions; }
-    }
-
-    /// <value>
-    /// Unmodifiable list of this file's dependencies (imports).
-    /// </value>
-    public IList<FileDescriptor> Dependencies {
-      get { return dependencies; }
-    }
-
-    /// <value>
-    /// Implementation of IDescriptor.FullName - just returns the same as Name.
-    /// </value>
-    string IDescriptor.FullName {
-      get { return Name; }
-    }
-
-    /// <value>
-    /// Implementation of IDescriptor.File - just returns this descriptor.
-    /// </value>
-    FileDescriptor IDescriptor.File {
-      get { return this; }
-    }
-
-    /// <value>
-    /// Protocol buffer describing this descriptor.
-    /// </value>
-    IMessage IDescriptor.Proto {
-      get { return Proto; }
-    }
-
-    /// <value>
-    /// Pool containing symbol descriptors.
-    /// </value>
-    internal DescriptorPool DescriptorPool {
-      get { return pool; }
-    }
-
-    /// <summary>
-    /// Finds a type (message, enum, service or extension) in the file by name. Does not find nested types.
-    /// </summary>
-    /// <param name="name">The unqualified type name to look for.</param>
-    /// <typeparam name="T">The type of descriptor to look for (or ITypeDescriptor for any)</typeparam>
-    /// <returns>The type's descriptor, or null if not found.</returns>
-    public T FindTypeByName<T>(String name)
-      where T : class, IDescriptor {
-      // Don't allow looking up nested types.  This will make optimization
-      // easier later.
-      if (name.IndexOf('.') != -1) {
-        return null;
-      }
-      if (Package.Length > 0) {
-        name = Package + "." + name;
-      }
-      T result = pool.FindSymbol<T>(name);
-      if (result != null && result.File == this) {
-        return result;
-      }
-      return null;
-    }
-
-    /// <summary>
-    /// Builds a FileDescriptor from its protocol buffer representation.
-    /// </summary>
-    /// <param name="proto">The protocol message form of the FileDescriptor.</param>
-    /// <param name="dependencies">FileDescriptors corresponding to all of the
-    /// file's dependencies, in the exact order listed in the .proto file. May be null,
-    /// in which case it is treated as an empty array.</param>
-    /// <exception cref="DescriptorValidationException">If <paramref name="proto"/> is not
-    /// a valid descriptor. This can occur for a number of reasons, such as a field
-    /// having an undefined type or because two messages were defined with the same name.</exception>
-    public static FileDescriptor BuildFrom(FileDescriptorProto proto, FileDescriptor[] dependencies) {
-      // Building descriptors involves two steps: translating and linking.
-      // In the translation step (implemented by FileDescriptor's
-      // constructor), we build an object tree mirroring the
-      // FileDescriptorProto's tree and put all of the descriptors into the
-      // DescriptorPool's lookup tables.  In the linking step, we look up all
-      // type references in the DescriptorPool, so that, for example, a
-      // FieldDescriptor for an embedded message contains a pointer directly
-      // to the Descriptor for that message's type.  We also detect undefined
-      // types in the linking step.
-      if (dependencies == null) {
-        dependencies = new FileDescriptor[0];
-      }
-
-      DescriptorPool pool = new DescriptorPool(dependencies);
-      FileDescriptor result = new FileDescriptor(proto, dependencies, pool);
-
-      if (dependencies.Length != proto.DependencyCount) {
-        throw new DescriptorValidationException(result,
-                                                "Dependencies passed to FileDescriptor.BuildFrom() don't match " +
-                                                "those listed in the FileDescriptorProto.");
-      }
-      for (int i = 0; i < proto.DependencyCount; i++) {
-        if (dependencies[i].Name != proto.DependencyList[i]) {
-          throw new DescriptorValidationException(result,
-                                                  "Dependencies passed to FileDescriptor.BuildFrom() don't match " +
-                                                  "those listed in the FileDescriptorProto.");
-        }
-      }
-
-      result.CrossLink();
-      return result;
-    }
-
-    private void CrossLink() {
-      foreach (MessageDescriptor message in messageTypes) {
-        message.CrossLink();
-      }
-
-      foreach (ServiceDescriptor service in services) {
-        service.CrossLink();
-      }
-
-      foreach (FieldDescriptor extension in extensions) {
-        extension.CrossLink();
-      }
-
-      foreach (MessageDescriptor message in messageTypes) {
-        message.CheckRequiredFields();
-      }
-    }
-
-    /// <summary>
-    /// This method is to be called by generated code only.  It is equivalent
-    /// to BuildFrom except that the FileDescriptorProto is encoded in
-    /// protocol buffer wire format. This overload is maintained for backward
-    /// compatibility with source code generated before the custom options were available
-    /// (and working).
-    /// </summary>
-    public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData, FileDescriptor[] dependencies) {
-      return InternalBuildGeneratedFileFrom(descriptorData, dependencies, x => null);
-    }
-
-    /// <summary>
-    /// This delegate should be used by generated code only. When calling
-    /// FileDescriptor.InternalBuildGeneratedFileFrom, the caller can provide
-    /// a callback which assigns the global variables defined in the generated code
-    /// which point at parts of the FileDescriptor. The callback returns an
-    /// Extension Registry which contains any extensions which might be used in
-    /// the descriptor - that is, extensions of the various "Options" messages defined
-    /// in descriptor.proto. The callback may also return null to indicate that
-    /// no extensions are used in the descriptor.
-    /// </summary>
-    /// <param name="descriptor"></param>
-    /// <returns></returns>
-    public delegate ExtensionRegistry InternalDescriptorAssigner(FileDescriptor descriptor);
-
-    public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData,
-                                                                FileDescriptor[] dependencies,
-                                                                InternalDescriptorAssigner descriptorAssigner) {
-      FileDescriptorProto proto;
-      try {
-        proto = FileDescriptorProto.ParseFrom(descriptorData);
-      }
-      catch (InvalidProtocolBufferException e) {
-        throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e);
-      }
-
-      FileDescriptor result;
-      try {
-        result = BuildFrom(proto, dependencies);
-      }
-      catch (DescriptorValidationException e) {
-        throw new ArgumentException("Invalid embedded descriptor for \"" + proto.Name + "\".", e);
-      }
-
-      ExtensionRegistry registry = descriptorAssigner(result);
-
-      if (registry != null) {
-        // We must re-parse the proto using the registry.
-        try {
-          proto = FileDescriptorProto.ParseFrom(descriptorData, registry);
-        }
-        catch (InvalidProtocolBufferException e) {
-          throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e);
-        }
-
-        result.ReplaceProto(proto);
-      }
-      return result;
-    }
-
-    /// <summary>
-    /// Replace our FileDescriptorProto with the given one, which is
-    /// identical except that it might contain extensions that weren't present
-    /// in the original. This method is needed for bootstrapping when a file
-    /// defines custom options. The options may be defined in the file itself,
-    /// so we can't actually parse them until we've constructed the descriptors,
-    /// but to construct the decsriptors we have to have parsed the descriptor
-    /// protos. So, we have to parse the descriptor protos a second time after
-    /// constructing the descriptors.
-    /// </summary>
-    private void ReplaceProto(FileDescriptorProto newProto) {
-      proto = newProto;
-
-      for (int i = 0; i < messageTypes.Count; i++) {
-        messageTypes[i].ReplaceProto(proto.GetMessageType(i));
-      }
-
-      for (int i = 0; i < enumTypes.Count; i++) {
-        enumTypes[i].ReplaceProto(proto.GetEnumType(i));
-      }
-
-      for (int i = 0; i < services.Count; i++) {
-        services[i].ReplaceProto(proto.GetService(i));
-      }
-
-      for (int i = 0; i < extensions.Count; i++) {
-        extensions[i].ReplaceProto(proto.GetExtension(i));
-      }
-    }
-  }
+// 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.
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using Google.ProtocolBuffers.DescriptorProtos;
+using FileOptions = Google.ProtocolBuffers.DescriptorProtos.FileOptions;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Describes a .proto file, including everything defined within.
+    /// IDescriptor is implemented such that the File property returns this descriptor,
+    /// and the FullName is the same as the Name.
+    /// </summary>
+    public sealed class FileDescriptor : IDescriptor<FileDescriptorProto>
+    {
+        private FileDescriptorProto proto;
+        private readonly IList<MessageDescriptor> messageTypes;
+        private readonly IList<EnumDescriptor> enumTypes;
+        private readonly IList<ServiceDescriptor> services;
+        private readonly IList<FieldDescriptor> extensions;
+        private readonly IList<FileDescriptor> dependencies;
+        private readonly DescriptorPool pool;
+        private CSharpFileOptions csharpFileOptions;
+        private readonly object optionsLock = new object();
+
+        private FileDescriptor(FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool)
+        {
+            this.pool = pool;
+            this.proto = proto;
+            this.dependencies = new ReadOnlyCollection<FileDescriptor>((FileDescriptor[]) dependencies.Clone());
+
+            pool.AddPackage(Package, this);
+
+            messageTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.MessageTypeList,
+                                                                 (message, index) =>
+                                                                 new MessageDescriptor(message, this, null, index));
+
+            enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumTypeList,
+                                                              (enumType, index) =>
+                                                              new EnumDescriptor(enumType, this, null, index));
+
+            services = DescriptorUtil.ConvertAndMakeReadOnly(proto.ServiceList,
+                                                             (service, index) =>
+                                                             new ServiceDescriptor(service, this, index));
+
+            extensions = DescriptorUtil.ConvertAndMakeReadOnly(proto.ExtensionList,
+                                                               (field, index) =>
+                                                               new FieldDescriptor(field, this, null, index, true));
+        }
+
+
+        /// <summary>
+        /// Allows a file descriptor to be configured with a set of external options, e.g. from the
+        /// command-line arguments to protogen.
+        /// </summary>
+        public void ConfigureWithDefaultOptions(CSharpFileOptions options)
+        {
+            csharpFileOptions = BuildOrFakeWithDefaultOptions(options);
+        }
+
+        private CSharpFileOptions BuildOrFakeWithDefaultOptions(CSharpFileOptions defaultOptions)
+        {
+            // Fix for being able to relocate these files to any directory structure
+            if (proto.Package == "google.protobuf")
+            {
+                string filename = Path.GetFileName(proto.Name);
+                // TODO(jonskeet): Check if we could use FileDescriptorProto.Descriptor.Name - interesting bootstrap issues)
+                if (filename == "descriptor.proto")
+                {
+                    return new CSharpFileOptions.Builder
+                               {
+                                   Namespace = "Google.ProtocolBuffers.DescriptorProtos",
+                                   UmbrellaClassname = "DescriptorProtoFile",
+                                   NestClasses = false,
+                                   MultipleFiles = false,
+                                   PublicClasses = true,
+                                   OutputDirectory = defaultOptions.OutputDirectory,
+                                   IgnoreGoogleProtobuf = defaultOptions.IgnoreGoogleProtobuf
+                               }.Build();
+                }
+                if (filename == "csharp_options.proto")
+                {
+                    return new CSharpFileOptions.Builder
+                               {
+                                   Namespace = "Google.ProtocolBuffers.DescriptorProtos",
+                                   UmbrellaClassname = "CSharpOptions",
+                                   NestClasses = false,
+                                   MultipleFiles = false,
+                                   PublicClasses = true,
+                                   OutputDirectory = defaultOptions.OutputDirectory,
+                                   IgnoreGoogleProtobuf = defaultOptions.IgnoreGoogleProtobuf
+                               }.Build();
+                }
+            }
+            CSharpFileOptions.Builder builder = defaultOptions.ToBuilder();
+            if (proto.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions))
+            {
+                builder.MergeFrom(proto.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions));
+            }
+            if (!builder.HasNamespace)
+            {
+                builder.Namespace = Package;
+            }
+            if (!builder.HasUmbrellaClassname)
+            {
+                int lastSlash = Name.LastIndexOf('/');
+                string baseName = Name.Substring(lastSlash + 1);
+                builder.UmbrellaClassname = NameHelpers.UnderscoresToPascalCase(NameHelpers.StripProto(baseName));
+            }
+
+            // Auto-fix for name collision by placing umbrella class into a new namespace.  This
+            // still won't fix the collisions with nesting enabled; however, you have to turn that on explicitly anyway.
+            if (!builder.NestClasses && !builder.HasUmbrellaNamespace)
+            {
+                bool collision = false;
+                foreach (IDescriptor d in MessageTypes)
+                {
+                    collision |= d.Name == builder.UmbrellaClassname;
+                }
+                foreach (IDescriptor d in Services)
+                {
+                    collision |= d.Name == builder.UmbrellaClassname;
+                }
+                foreach (IDescriptor d in EnumTypes)
+                {
+                    collision |= d.Name == builder.UmbrellaClassname;
+                }
+                if (collision)
+                {
+                    builder.UmbrellaNamespace = "Proto";
+                }
+            }
+
+            return builder.Build();
+        }
+
+        /// <value>
+        /// The descriptor in its protocol message representation.
+        /// </value>
+        public FileDescriptorProto Proto
+        {
+            get { return proto; }
+        }
+
+        /// <value>
+        /// The <see cref="DescriptorProtos.FileOptions" /> defined in <c>descriptor.proto</c>.
+        /// </value>
+        public FileOptions Options
+        {
+            get { return proto.Options; }
+        }
+
+        /// <summary>
+        /// Returns the C#-specific options for this file descriptor. This will always be
+        /// completely filled in.
+        /// </summary>
+        public CSharpFileOptions CSharpOptions
+        {
+            get
+            {
+                lock (optionsLock)
+                {
+                    if (csharpFileOptions == null)
+                    {
+                        csharpFileOptions = BuildOrFakeWithDefaultOptions(CSharpFileOptions.DefaultInstance);
+                    }
+                }
+                return csharpFileOptions;
+            }
+        }
+
+        /// <value>
+        /// The file name.
+        /// </value>
+        public string Name
+        {
+            get { return proto.Name; }
+        }
+
+        /// <summary>
+        /// The package as declared in the .proto file. This may or may not
+        /// be equivalent to the .NET namespace of the generated classes.
+        /// </summary>
+        public string Package
+        {
+            get { return proto.Package; }
+        }
+
+        /// <value>
+        /// Unmodifiable list of top-level message types declared in this file.
+        /// </value>
+        public IList<MessageDescriptor> MessageTypes
+        {
+            get { return messageTypes; }
+        }
+
+        /// <value>
+        /// Unmodifiable list of top-level enum types declared in this file.
+        /// </value>
+        public IList<EnumDescriptor> EnumTypes
+        {
+            get { return enumTypes; }
+        }
+
+        /// <value>
+        /// Unmodifiable list of top-level services declared in this file.
+        /// </value>
+        public IList<ServiceDescriptor> Services
+        {
+            get { return services; }
+        }
+
+        /// <value>
+        /// Unmodifiable list of top-level extensions declared in this file.
+        /// </value>
+        public IList<FieldDescriptor> Extensions
+        {
+            get { return extensions; }
+        }
+
+        /// <value>
+        /// Unmodifiable list of this file's dependencies (imports).
+        /// </value>
+        public IList<FileDescriptor> Dependencies
+        {
+            get { return dependencies; }
+        }
+
+        /// <value>
+        /// Implementation of IDescriptor.FullName - just returns the same as Name.
+        /// </value>
+        string IDescriptor.FullName
+        {
+            get { return Name; }
+        }
+
+        /// <value>
+        /// Implementation of IDescriptor.File - just returns this descriptor.
+        /// </value>
+        FileDescriptor IDescriptor.File
+        {
+            get { return this; }
+        }
+
+        /// <value>
+        /// Protocol buffer describing this descriptor.
+        /// </value>
+        IMessage IDescriptor.Proto
+        {
+            get { return Proto; }
+        }
+
+        /// <value>
+        /// Pool containing symbol descriptors.
+        /// </value>
+        internal DescriptorPool DescriptorPool
+        {
+            get { return pool; }
+        }
+
+        /// <summary>
+        /// Finds a type (message, enum, service or extension) in the file by name. Does not find nested types.
+        /// </summary>
+        /// <param name="name">The unqualified type name to look for.</param>
+        /// <typeparam name="T">The type of descriptor to look for (or ITypeDescriptor for any)</typeparam>
+        /// <returns>The type's descriptor, or null if not found.</returns>
+        public T FindTypeByName<T>(String name)
+            where T : class, IDescriptor
+        {
+            // Don't allow looking up nested types.  This will make optimization
+            // easier later.
+            if (name.IndexOf('.') != -1)
+            {
+                return null;
+            }
+            if (Package.Length > 0)
+            {
+                name = Package + "." + name;
+            }
+            T result = pool.FindSymbol<T>(name);
+            if (result != null && result.File == this)
+            {
+                return result;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Builds a FileDescriptor from its protocol buffer representation.
+        /// </summary>
+        /// <param name="proto">The protocol message form of the FileDescriptor.</param>
+        /// <param name="dependencies">FileDescriptors corresponding to all of the
+        /// file's dependencies, in the exact order listed in the .proto file. May be null,
+        /// in which case it is treated as an empty array.</param>
+        /// <exception cref="DescriptorValidationException">If <paramref name="proto"/> is not
+        /// a valid descriptor. This can occur for a number of reasons, such as a field
+        /// having an undefined type or because two messages were defined with the same name.</exception>
+        public static FileDescriptor BuildFrom(FileDescriptorProto proto, FileDescriptor[] dependencies)
+        {
+            // Building descriptors involves two steps: translating and linking.
+            // In the translation step (implemented by FileDescriptor's
+            // constructor), we build an object tree mirroring the
+            // FileDescriptorProto's tree and put all of the descriptors into the
+            // DescriptorPool's lookup tables.  In the linking step, we look up all
+            // type references in the DescriptorPool, so that, for example, a
+            // FieldDescriptor for an embedded message contains a pointer directly
+            // to the Descriptor for that message's type.  We also detect undefined
+            // types in the linking step.
+            if (dependencies == null)
+            {
+                dependencies = new FileDescriptor[0];
+            }
+
+            DescriptorPool pool = new DescriptorPool(dependencies);
+            FileDescriptor result = new FileDescriptor(proto, dependencies, pool);
+
+            if (dependencies.Length != proto.DependencyCount)
+            {
+                throw new DescriptorValidationException(result,
+                                                        "Dependencies passed to FileDescriptor.BuildFrom() don't match " +
+                                                        "those listed in the FileDescriptorProto.");
+            }
+            for (int i = 0; i < proto.DependencyCount; i++)
+            {
+                if (dependencies[i].Name != proto.DependencyList[i])
+                {
+                    throw new DescriptorValidationException(result,
+                                                            "Dependencies passed to FileDescriptor.BuildFrom() don't match " +
+                                                            "those listed in the FileDescriptorProto.");
+                }
+            }
+
+            result.CrossLink();
+            return result;
+        }
+
+        private void CrossLink()
+        {
+            foreach (MessageDescriptor message in messageTypes)
+            {
+                message.CrossLink();
+            }
+
+            foreach (ServiceDescriptor service in services)
+            {
+                service.CrossLink();
+            }
+
+            foreach (FieldDescriptor extension in extensions)
+            {
+                extension.CrossLink();
+            }
+
+            foreach (MessageDescriptor message in messageTypes)
+            {
+                message.CheckRequiredFields();
+            }
+        }
+
+        /// <summary>
+        /// This method is to be called by generated code only.  It is equivalent
+        /// to BuildFrom except that the FileDescriptorProto is encoded in
+        /// protocol buffer wire format. This overload is maintained for backward
+        /// compatibility with source code generated before the custom options were available
+        /// (and working).
+        /// </summary>
+        public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData, FileDescriptor[] dependencies)
+        {
+            return InternalBuildGeneratedFileFrom(descriptorData, dependencies, x => null);
+        }
+
+        /// <summary>
+        /// This delegate should be used by generated code only. When calling
+        /// FileDescriptor.InternalBuildGeneratedFileFrom, the caller can provide
+        /// a callback which assigns the global variables defined in the generated code
+        /// which point at parts of the FileDescriptor. The callback returns an
+        /// Extension Registry which contains any extensions which might be used in
+        /// the descriptor - that is, extensions of the various "Options" messages defined
+        /// in descriptor.proto. The callback may also return null to indicate that
+        /// no extensions are used in the descriptor.
+        /// </summary>
+        /// <param name="descriptor"></param>
+        /// <returns></returns>
+        public delegate ExtensionRegistry InternalDescriptorAssigner(FileDescriptor descriptor);
+
+        public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData,
+                                                                    FileDescriptor[] dependencies,
+                                                                    InternalDescriptorAssigner descriptorAssigner)
+        {
+            FileDescriptorProto proto;
+            try
+            {
+                proto = FileDescriptorProto.ParseFrom(descriptorData);
+            }
+            catch (InvalidProtocolBufferException e)
+            {
+                throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e);
+            }
+
+            FileDescriptor result;
+            try
+            {
+                result = BuildFrom(proto, dependencies);
+            }
+            catch (DescriptorValidationException e)
+            {
+                throw new ArgumentException("Invalid embedded descriptor for \"" + proto.Name + "\".", e);
+            }
+
+            ExtensionRegistry registry = descriptorAssigner(result);
+
+            if (registry != null)
+            {
+                // We must re-parse the proto using the registry.
+                try
+                {
+                    proto = FileDescriptorProto.ParseFrom(descriptorData, registry);
+                }
+                catch (InvalidProtocolBufferException e)
+                {
+                    throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e);
+                }
+
+                result.ReplaceProto(proto);
+            }
+            return result;
+        }
+
+        /// <summary>
+        /// Replace our FileDescriptorProto with the given one, which is
+        /// identical except that it might contain extensions that weren't present
+        /// in the original. This method is needed for bootstrapping when a file
+        /// defines custom options. The options may be defined in the file itself,
+        /// so we can't actually parse them until we've constructed the descriptors,
+        /// but to construct the decsriptors we have to have parsed the descriptor
+        /// protos. So, we have to parse the descriptor protos a second time after
+        /// constructing the descriptors.
+        /// </summary>
+        private void ReplaceProto(FileDescriptorProto newProto)
+        {
+            proto = newProto;
+
+            for (int i = 0; i < messageTypes.Count; i++)
+            {
+                messageTypes[i].ReplaceProto(proto.GetMessageType(i));
+            }
+
+            for (int i = 0; i < enumTypes.Count; i++)
+            {
+                enumTypes[i].ReplaceProto(proto.GetEnumType(i));
+            }
+
+            for (int i = 0; i < services.Count; i++)
+            {
+                services[i].ReplaceProto(proto.GetService(i));
+            }
+
+            for (int i = 0; i < extensions.Count; i++)
+            {
+                extensions[i].ReplaceProto(proto.GetExtension(i));
+            }
+        }
+    }
 }

+ 55 - 53
src/ProtocolBuffers/Descriptors/IDescriptor.cs

@@ -1,53 +1,55 @@
-// 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.
-
-namespace Google.ProtocolBuffers.Descriptors {
-
-  /// <summary>
-  /// The non-generic form of the IDescriptor interface. Useful for describing a general
-  /// descriptor.
-  /// </summary>
-  public interface IDescriptor {
-    string Name { get; }
-    string FullName { get; }
-    FileDescriptor File { get; }
-    IMessage Proto { get; }
-  }
-
-  /// <summary>
-  /// Strongly-typed form of the IDescriptor interface.
-  /// </summary>
-  /// <typeparam name="TProto">Protocol buffer type underlying this descriptor type</typeparam>
-  public interface IDescriptor<TProto> : IDescriptor where TProto : IMessage {
-    new TProto Proto { get; }
-  }
-}
+// 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.
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// The non-generic form of the IDescriptor interface. Useful for describing a general
+    /// descriptor.
+    /// </summary>
+    public interface IDescriptor
+    {
+        string Name { get; }
+        string FullName { get; }
+        FileDescriptor File { get; }
+        IMessage Proto { get; }
+    }
+
+    /// <summary>
+    /// Strongly-typed form of the IDescriptor interface.
+    /// </summary>
+    /// <typeparam name="TProto">Protocol buffer type underlying this descriptor type</typeparam>
+    public interface IDescriptor<TProto> : IDescriptor where TProto : IMessage
+    {
+        new TProto Proto { get; }
+    }
+}

+ 64 - 61
src/ProtocolBuffers/Descriptors/IndexedDescriptorBase.cs

@@ -1,61 +1,64 @@
-// 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.
-using Google.ProtocolBuffers.DescriptorProtos;
-
-namespace Google.ProtocolBuffers.Descriptors {
-  /// <summary>
-  /// Base class for descriptors which are also indexed. This is all of them other than
-  /// <see cref="FileDescriptor" />.
-  /// </summary>
-  public abstract class IndexedDescriptorBase<TProto, TOptions> : DescriptorBase<TProto, TOptions>
-      where TProto : IMessage<TProto>, IDescriptorProto<TOptions> {
-
-    private readonly int index;
-
-    protected IndexedDescriptorBase(TProto proto, FileDescriptor file, string fullName, int index)
-        : base(proto, file, fullName) {
-      this.index = index;
-    }
-
-    /// <value>
-    /// The index of this descriptor within its parent descriptor. 
-    /// </value>
-    /// <remarks>
-    /// This returns the index of this descriptor within its parent, for
-    /// this descriptor's type. (There can be duplicate values for different
-    /// types, e.g. one enum type with index 0 and one message type with index 0.)
-    /// </remarks>
-    public int Index {
-      get { return index; }
-    }
-  }
-}
+// 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.
+using Google.ProtocolBuffers.DescriptorProtos;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Base class for descriptors which are also indexed. This is all of them other than
+    /// <see cref="FileDescriptor" />.
+    /// </summary>
+    public abstract class IndexedDescriptorBase<TProto, TOptions> : DescriptorBase<TProto, TOptions>
+        where TProto : IMessage<TProto>, IDescriptorProto<TOptions>
+    {
+        private readonly int index;
+
+        protected IndexedDescriptorBase(TProto proto, FileDescriptor file, string fullName, int index)
+            : base(proto, file, fullName)
+        {
+            this.index = index;
+        }
+
+        /// <value>
+        /// The index of this descriptor within its parent descriptor. 
+        /// </value>
+        /// <remarks>
+        /// This returns the index of this descriptor within its parent, for
+        /// this descriptor's type. (There can be duplicate values for different
+        /// types, e.g. one enum type with index 0 and one message type with index 0.)
+        /// </remarks>
+        public int Index
+        {
+            get { return index; }
+        }
+    }
+}

+ 52 - 50
src/ProtocolBuffers/Descriptors/MappedType.cs

@@ -1,50 +1,52 @@
-// 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.
-
-namespace Google.ProtocolBuffers.Descriptors {
-  /// <summary>
-  /// Type as it's mapped onto a .NET type.
-  /// </summary>
-  public enum MappedType {
-    Int32,
-    Int64,
-    UInt32,
-    UInt64,
-    Single,
-    Double,
-    Boolean,
-    String,
-    ByteString,
-    Message,
-    Enum
-  }
-}
+// 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.
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Type as it's mapped onto a .NET type.
+    /// </summary>
+    public enum MappedType
+    {
+        Int32,
+        Int64,
+        UInt32,
+        UInt64,
+        Single,
+        Double,
+        Boolean,
+        String,
+        ByteString,
+        Message,
+        Enum
+    }
+}

+ 288 - 252
src/ProtocolBuffers/Descriptors/MessageDescriptor.cs

@@ -1,252 +1,288 @@
-// 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.
-using System;
-using System.Collections.Generic;
-using Google.ProtocolBuffers.DescriptorProtos;
-
-namespace Google.ProtocolBuffers.Descriptors {
-
-  /// <summary>
-  /// Describes a message type.
-  /// </summary>
-  public sealed class MessageDescriptor : IndexedDescriptorBase<DescriptorProto, MessageOptions> {
-
-    private readonly MessageDescriptor containingType;
-    private readonly IList<MessageDescriptor> nestedTypes;
-    private readonly IList<EnumDescriptor> enumTypes;
-    private readonly IList<FieldDescriptor> fields;
-    private readonly IList<FieldDescriptor> extensions;
-    private bool hasRequiredFields;
-
-    internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex)
-        : base(proto, file, ComputeFullName(file, parent, proto.Name), typeIndex) {
-      containingType = parent;
-
-      nestedTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.NestedTypeList,
-          (type, index) => new MessageDescriptor(type, file, this, index));
-
-      enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumTypeList,
-          (type, index) => new EnumDescriptor(type, file, this, index));
-
-      // TODO(jonskeet): Sort fields first?
-      fields = DescriptorUtil.ConvertAndMakeReadOnly(proto.FieldList,
-          (field, index) => new FieldDescriptor(field, file, this, index, false));
-
-      extensions = DescriptorUtil.ConvertAndMakeReadOnly(proto.ExtensionList,
-          (field, index) => new FieldDescriptor(field, file, this, index, true));
-
-      file.DescriptorPool.AddSymbol(this);
-    }
-
-    /// <value>
-    /// If this is a nested type, get the outer descriptor, otherwise null.
-    /// </value>
-    public MessageDescriptor ContainingType {
-      get { return containingType; }
-    }
-
-    /// <value>
-    /// An unmodifiable list of this message type's fields.
-    /// </value>
-    public IList<FieldDescriptor> Fields {
-      get { return fields; }
-    }
-
-    /// <value>
-    /// An unmodifiable list of this message type's extensions.
-    /// </value>
-    public IList<FieldDescriptor> Extensions {
-      get { return extensions; }
-    }
-
-    /// <value>
-    /// An unmodifiable list of this message type's nested types.
-    /// </value>
-    public IList<MessageDescriptor> NestedTypes {
-      get { return nestedTypes; }
-    }
-
-    /// <value>
-    /// An unmodifiable list of this message type's enum types.
-    /// </value>
-    public IList<EnumDescriptor> EnumTypes {
-      get { return enumTypes; }
-    }
-
-    /// <summary>
-    /// Returns a pre-computed result as to whether this message
-    /// has required fields. This includes optional fields which are
-    /// message types which in turn have required fields, and any 
-    /// extension fields.
-    /// </summary>
-    internal bool HasRequiredFields {
-      get { return hasRequiredFields; }
-    }
-
-    /// <summary>
-    /// Determines if the given field number is an extension.
-    /// </summary>
-    public bool IsExtensionNumber(int number) {
-      foreach (DescriptorProto.Types.ExtensionRange range in Proto.ExtensionRangeList) {
-        if (range.Start <= number && number < range.End) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    /// <summary>
-    /// Finds a field by field name.
-    /// </summary>
-    /// <param name="name">The unqualified name of the field (e.g. "foo").</param>
-    /// <returns>The field's descriptor, or null if not found.</returns>
-    public FieldDescriptor FindFieldByName(String name) {
-      return File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName  + "." + name);
-    }
-
-    /// <summary>
-    /// Finds a field by field number.
-    /// </summary>
-    /// <param name="number">The field number within this message type.</param>
-    /// <returns>The field's descriptor, or null if not found.</returns>
-    public FieldDescriptor FindFieldByNumber(int number) {
-      return File.DescriptorPool.FindFieldByNumber(this, number);
-    }
-
-    /// <summary>
-    /// Finds a field by its property name, as it would be generated by protogen.
-    /// </summary>
-    /// <param name="propertyName">The property name within this message type.</param>
-    /// <returns>The field's descriptor, or null if not found.</returns>
-    public FieldDescriptor FindFieldByPropertyName(string propertyName) {
-      // For reasonably short messages, this will be more efficient than a dictionary
-      // lookup. It also means we don't need to do things lazily with locks etc.
-      foreach (FieldDescriptor field in Fields) {
-        if (field.CSharpOptions.PropertyName == propertyName) {
-          return field;
-        }
-      }
-      return null;
-    }
-
-    /// <summary>
-    /// Finds a nested descriptor by name. The is valid for fields, nested
-    /// message types and enums.
-    /// </summary>
-    /// <param name="name">The unqualified name of the descriptor, e.g. "Foo"</param>
-    /// <returns>The descriptor, or null if not found.</returns>
-    public T FindDescriptor<T>(string name) 
-        where T : class, IDescriptor {
-      return File.DescriptorPool.FindSymbol<T>(FullName + "." + name);
-    }
-
-    /// <summary>
-    /// Looks up and cross-links all fields, nested types, and extensions.
-    /// </summary>
-    internal void CrossLink() {
-      foreach (MessageDescriptor message in nestedTypes) {
-        message.CrossLink();
-      }
-
-      foreach (FieldDescriptor field in fields) {
-        field.CrossLink();
-      }
-
-      foreach (FieldDescriptor extension in extensions) {
-        extension.CrossLink();
-      }
-    }
-
-    internal void CheckRequiredFields() {
-      IDictionary<MessageDescriptor, byte> alreadySeen = new Dictionary<MessageDescriptor, byte>();
-      hasRequiredFields = CheckRequiredFields(alreadySeen);
-    }
-
-    private bool CheckRequiredFields(IDictionary<MessageDescriptor,byte> alreadySeen) {
-
-      if (alreadySeen.ContainsKey(this)) {
-        // The type is already in the cache. This means that either:
-        // a. The type has no required fields.
-        // b. We are in the midst of checking if the type has required fields,
-        //    somewhere up the stack.  In this case, we know that if the type
-        //    has any required fields, they'll be found when we return to it,
-        //    and the whole call to HasRequiredFields() will return true.
-        //    Therefore, we don't have to check if this type has required fields
-        //    here.
-        return false;
-      }
-      alreadySeen[this] = 0; // Value is irrelevant; we want set semantics
-
-      // If the type allows extensions, an extension with message type could contain
-      // required fields, so we have to be conservative and assume such an
-      // extension exists.
-      if (Proto.ExtensionRangeCount != 0) {
-        return true;
-      }
-
-      foreach (FieldDescriptor field in Fields) {
-        if (field.IsRequired) {
-          return true;
-        }
-        if (field.MappedType == MappedType.Message) {
-          if (field.MessageType.CheckRequiredFields(alreadySeen)) {
-            return true;
-          }
-        }
-      }
-      return false;
-    }
-
-    /// <summary>
-    /// See FileDescriptor.ReplaceProto
-    /// </summary>
-    internal override void ReplaceProto(DescriptorProto newProto) {
-      base.ReplaceProto(newProto);
-
-      for (int i = 0; i < nestedTypes.Count; i++) {
-        nestedTypes[i].ReplaceProto(newProto.GetNestedType(i));
-      }
-
-      for (int i = 0; i < enumTypes.Count; i++) {
-        enumTypes[i].ReplaceProto(newProto.GetEnumType(i));
-      }
-
-      for (int i = 0; i < fields.Count; i++) {
-        fields[i].ReplaceProto(newProto.GetField(i));
-      }
-
-      for (int i = 0; i < extensions.Count; i++) {
-        extensions[i].ReplaceProto(newProto.GetExtension(i));
-      }
-    }
-  }
-}
+// 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.
+using System;
+using System.Collections.Generic;
+using Google.ProtocolBuffers.DescriptorProtos;
+
+namespace Google.ProtocolBuffers.Descriptors
+{
+    /// <summary>
+    /// Describes a message type.
+    /// </summary>
+    public sealed class MessageDescriptor : IndexedDescriptorBase<DescriptorProto, MessageOptions>
+    {
+        private readonly MessageDescriptor containingType;
+        private readonly IList<MessageDescriptor> nestedTypes;
+        private readonly IList<EnumDescriptor> enumTypes;
+        private readonly IList<FieldDescriptor> fields;
+        private readonly IList<FieldDescriptor> extensions;
+        private bool hasRequiredFields;
+
+        internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex)
+            : base(proto, file, ComputeFullName(file, parent, proto.Name), typeIndex)
+        {
+            containingType = parent;
+
+            nestedTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.NestedTypeList,
+                                                                (type, index) =>
+                                                                new MessageDescriptor(type, file, this, index));
+
+            enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumTypeList,
+                                                              (type, index) =>
+                                                              new EnumDescriptor(type, file, this, index));
+
+            // TODO(jonskeet): Sort fields first?
+            fields = DescriptorUtil.ConvertAndMakeReadOnly(proto.FieldList,
+                                                           (field, index) =>
+                                                           new FieldDescriptor(field, file, this, index, false));
+
+            extensions = DescriptorUtil.ConvertAndMakeReadOnly(proto.ExtensionList,
+                                                               (field, index) =>
+                                                               new FieldDescriptor(field, file, this, index, true));
+
+            file.DescriptorPool.AddSymbol(this);
+        }
+
+        /// <value>
+        /// If this is a nested type, get the outer descriptor, otherwise null.
+        /// </value>
+        public MessageDescriptor ContainingType
+        {
+            get { return containingType; }
+        }
+
+        /// <value>
+        /// An unmodifiable list of this message type's fields.
+        /// </value>
+        public IList<FieldDescriptor> Fields
+        {
+            get { return fields; }
+        }
+
+        /// <value>
+        /// An unmodifiable list of this message type's extensions.
+        /// </value>
+        public IList<FieldDescriptor> Extensions
+        {
+            get { return extensions; }
+        }
+
+        /// <value>
+        /// An unmodifiable list of this message type's nested types.
+        /// </value>
+        public IList<MessageDescriptor> NestedTypes
+        {
+            get { return nestedTypes; }
+        }
+
+        /// <value>
+        /// An unmodifiable list of this message type's enum types.
+        /// </value>
+        public IList<EnumDescriptor> EnumTypes
+        {
+            get { return enumTypes; }
+        }
+
+        /// <summary>
+        /// Returns a pre-computed result as to whether this message
+        /// has required fields. This includes optional fields which are
+        /// message types which in turn have required fields, and any 
+        /// extension fields.
+        /// </summary>
+        internal bool HasRequiredFields
+        {
+            get { return hasRequiredFields; }
+        }
+
+        /// <summary>
+        /// Determines if the given field number is an extension.
+        /// </summary>
+        public bool IsExtensionNumber(int number)
+        {
+            foreach (DescriptorProto.Types.ExtensionRange range in Proto.ExtensionRangeList)
+            {
+                if (range.Start <= number && number < range.End)
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Finds a field by field name.
+        /// </summary>
+        /// <param name="name">The unqualified name of the field (e.g. "foo").</param>
+        /// <returns>The field's descriptor, or null if not found.</returns>
+        public FieldDescriptor FindFieldByName(String name)
+        {
+            return File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName + "." + name);
+        }
+
+        /// <summary>
+        /// Finds a field by field number.
+        /// </summary>
+        /// <param name="number">The field number within this message type.</param>
+        /// <returns>The field's descriptor, or null if not found.</returns>
+        public FieldDescriptor FindFieldByNumber(int number)
+        {
+            return File.DescriptorPool.FindFieldByNumber(this, number);
+        }
+
+        /// <summary>
+        /// Finds a field by its property name, as it would be generated by protogen.
+        /// </summary>
+        /// <param name="propertyName">The property name within this message type.</param>
+        /// <returns>The field's descriptor, or null if not found.</returns>
+        public FieldDescriptor FindFieldByPropertyName(string propertyName)
+        {
+            // For reasonably short messages, this will be more efficient than a dictionary
+            // lookup. It also means we don't need to do things lazily with locks etc.
+            foreach (FieldDescriptor field in Fields)
+            {
+                if (field.CSharpOptions.PropertyName == propertyName)
+                {
+                    return field;
+                }
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Finds a nested descriptor by name. The is valid for fields, nested
+        /// message types and enums.
+        /// </summary>
+        /// <param name="name">The unqualified name of the descriptor, e.g. "Foo"</param>
+        /// <returns>The descriptor, or null if not found.</returns>
+        public T FindDescriptor<T>(string name)
+            where T : class, IDescriptor
+        {
+            return File.DescriptorPool.FindSymbol<T>(FullName + "." + name);
+        }
+
+        /// <summary>
+        /// Looks up and cross-links all fields, nested types, and extensions.
+        /// </summary>
+        internal void CrossLink()
+        {
+            foreach (MessageDescriptor message in nestedTypes)
+            {
+                message.CrossLink();
+            }
+
+            foreach (FieldDescriptor field in fields)
+            {
+                field.CrossLink();
+            }
+
+            foreach (FieldDescriptor extension in extensions)
+            {
+                extension.CrossLink();
+            }
+        }
+
+        internal void CheckRequiredFields()
+        {
+            IDictionary<MessageDescriptor, byte> alreadySeen = new Dictionary<MessageDescriptor, byte>();
+            hasRequiredFields = CheckRequiredFields(alreadySeen);
+        }
+
+        private bool CheckRequiredFields(IDictionary<MessageDescriptor, byte> alreadySeen)
+        {
+            if (alreadySeen.ContainsKey(this))
+            {
+                // The type is already in the cache. This means that either:
+                // a. The type has no required fields.
+                // b. We are in the midst of checking if the type has required fields,
+                //    somewhere up the stack.  In this case, we know that if the type
+                //    has any required fields, they'll be found when we return to it,
+                //    and the whole call to HasRequiredFields() will return true.
+                //    Therefore, we don't have to check if this type has required fields
+                //    here.
+                return false;
+            }
+            alreadySeen[this] = 0; // Value is irrelevant; we want set semantics
+
+            // If the type allows extensions, an extension with message type could contain
+            // required fields, so we have to be conservative and assume such an
+            // extension exists.
+            if (Proto.ExtensionRangeCount != 0)
+            {
+                return true;
+            }
+
+            foreach (FieldDescriptor field in Fields)
+            {
+                if (field.IsRequired)
+                {
+                    return true;
+                }
+                if (field.MappedType == MappedType.Message)
+                {
+                    if (field.MessageType.CheckRequiredFields(alreadySeen))
+                    {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// See FileDescriptor.ReplaceProto
+        /// </summary>
+        internal override void ReplaceProto(DescriptorProto newProto)
+        {
+            base.ReplaceProto(newProto);
+
+            for (int i = 0; i < nestedTypes.Count; i++)
+            {
+                nestedTypes[i].ReplaceProto(newProto.GetNestedType(i));
+            }
+
+            for (int i = 0; i < enumTypes.Count; i++)
+            {
+                enumTypes[i].ReplaceProto(newProto.GetEnumType(i));
+            }
+
+            for (int i = 0; i < fields.Count; i++)
+            {
+                fields[i].ReplaceProto(newProto.GetField(i));
+            }
+
+            for (int i = 0; i < extensions.Count; i++)
+            {
+                extensions[i].ReplaceProto(newProto.GetExtension(i));
+            }
+        }
+    }
+}

部分文件因为文件数量过多而无法显示