Browse Source

reformatted all code to .NET standard formatting

csharptest 14 năm trước cách đây
mục cha
commit
71f662c33e
100 tập tin đã thay đổi với 34832 bổ sung27661 xóa
  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));
+            }
+        }
+    }
+}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác