From 71f662c33e9938951eec3da97140aed25aa815d7 Mon Sep 17 00:00:00 2001 From: csharptest Date: Fri, 20 May 2011 15:15:34 -0500 Subject: reformatted all code to .NET standard formatting --- src/AddressBook/AddPerson.cs | 255 +- src/AddressBook/ListPeople.cs | 193 +- src/AddressBook/Program.cs | 186 +- src/AddressBook/Properties/AssemblyInfo.cs | 74 +- src/AddressBook/SampleUsage.cs | 70 +- src/ProtoBench/Program.cs | 312 +- src/ProtoBench/Properties/AssemblyInfo.cs | 81 +- src/ProtoDump/Program.cs | 162 +- src/ProtoDump/Properties/AssemblyInfo.cs | 76 +- src/ProtoDump/app.config | 8 +- src/ProtoGen.Test/DependencyResolutionTest.cs | 274 +- src/ProtoGen.Test/Properties/AssemblyInfo.cs | 76 +- src/ProtoGen.Test/TempFile.cs | 113 +- src/ProtoGen.Test/TestPreprocessing.cs | 1287 +- src/ProtoGen/DependencyResolutionException.cs | 104 +- src/ProtoGen/DescriptorUtil.cs | 192 +- src/ProtoGen/EnumFieldGenerator.cs | 269 +- src/ProtoGen/EnumGenerator.cs | 115 +- src/ProtoGen/ExtensionGenerator.cs | 312 +- src/ProtoGen/FieldGeneratorBase.cs | 584 +- src/ProtoGen/Generator.cs | 455 +- src/ProtoGen/GeneratorOptions.cs | 613 +- src/ProtoGen/Helpers.cs | 87 +- src/ProtoGen/IFieldSourceGenerator.cs | 102 +- src/ProtoGen/ISourceGenerator.cs | 82 +- src/ProtoGen/InvalidOptionsException.cs | 147 +- src/ProtoGen/MessageFieldGenerator.cs | 303 +- src/ProtoGen/MessageGenerator.cs | 1349 +- src/ProtoGen/PrimitiveFieldGenerator.cs | 253 +- src/ProtoGen/Program.cs | 148 +- src/ProtoGen/ProgramPreprocess.cs | 339 +- src/ProtoGen/Properties/AssemblyInfo.cs | 77 +- src/ProtoGen/RepeatedEnumFieldGenerator.cs | 413 +- src/ProtoGen/RepeatedMessageFieldGenerator.cs | 323 +- src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs | 403 +- src/ProtoGen/ServiceGenerator.cs | 352 +- src/ProtoGen/ServiceInterfaceGenerator.cs | 436 +- src/ProtoGen/SourceGeneratorBase.cs | 287 +- src/ProtoGen/SourceGenerators.cs | 231 +- src/ProtoGen/UmbrellaClassGenerator.cs | 526 +- src/ProtoGen/app.config | 8 +- src/ProtoMunge/Program.cs | 564 +- src/ProtoMunge/Properties/AssemblyInfo.cs | 76 +- src/ProtoMunge/app.config | 8 +- src/ProtocolBuffers.Test/AbstractMessageTest.cs | 895 +- src/ProtocolBuffers.Test/ByteStringTest.cs | 248 +- src/ProtocolBuffers.Test/CSharpOptionsTest.cs | 231 +- src/ProtocolBuffers.Test/CodedInputStreamTest.cs | 985 +- src/ProtocolBuffers.Test/CodedOutputStreamTest.cs | 562 +- .../Collections/PopsicleListTest.cs | 210 +- .../Descriptors/MessageDescriptorTest.cs | 137 +- src/ProtocolBuffers.Test/DescriptorsTest.cs | 675 +- src/ProtocolBuffers.Test/DynamicMessageTest.cs | 452 +- src/ProtocolBuffers.Test/ExtendableMessageTest.cs | 394 +- src/ProtocolBuffers.Test/GeneratedMessageTest.cs | 1003 +- .../MessageStreamIteratorTest.cs | 174 +- .../MessageStreamWriterTest.cs | 149 +- src/ProtocolBuffers.Test/MessageTest.cs | 709 +- src/ProtocolBuffers.Test/MessageUtilTest.cs | 164 +- src/ProtocolBuffers.Test/NameHelpersTest.cs | 136 +- .../Properties/AssemblyInfo.cs | 85 +- src/ProtocolBuffers.Test/ReflectionTester.cs | 1926 +- src/ProtocolBuffers.Test/ServiceTest.cs | 414 +- src/ProtocolBuffers.Test/TestRpcGenerator.cs | 160 +- src/ProtocolBuffers.Test/TestUtil.cs | 3325 ++-- src/ProtocolBuffers.Test/TextFormatTest.cs | 1107 +- src/ProtocolBuffers.Test/UnknownFieldSetTest.cs | 833 +- src/ProtocolBuffers.Test/WireFormatTest.cs | 613 +- src/ProtocolBuffers/AbstractBuilder.cs | 468 +- src/ProtocolBuffers/AbstractBuilderLite.cs | 498 +- src/ProtocolBuffers/AbstractMessage.cs | 548 +- src/ProtocolBuffers/AbstractMessageLite.cs | 275 +- src/ProtocolBuffers/ByteString.cs | 454 +- src/ProtocolBuffers/CodedInputStream.cs | 2140 +-- src/ProtocolBuffers/CodedOutputStream.cs | 2569 +-- src/ProtocolBuffers/Collections/Dictionaries.cs | 230 +- src/ProtocolBuffers/Collections/Enumerables.cs | 137 +- src/ProtocolBuffers/Collections/IPopsicleList.cs | 98 +- src/ProtocolBuffers/Collections/Lists.cs | 209 +- src/ProtocolBuffers/Collections/PopsicleList.cs | 282 +- .../Collections/ReadOnlyDictionary.cs | 274 +- src/ProtocolBuffers/Delegates.cs | 111 +- .../DescriptorProtos/CSharpOptions.cs | 3660 ++-- .../DescriptorProtos/DescriptorProtoFile.cs | 17626 +++++++++++-------- .../DescriptorProtos/IDescriptorProto.cs | 104 +- .../DescriptorProtos/PartialClasses.cs | 110 +- src/ProtocolBuffers/Descriptors/DescriptorBase.cs | 218 +- src/ProtocolBuffers/Descriptors/DescriptorPool.cs | 648 +- src/ProtocolBuffers/Descriptors/DescriptorUtil.cs | 123 +- .../Descriptors/DescriptorValidationException.cs | 176 +- src/ProtocolBuffers/Descriptors/EnumDescriptor.cs | 230 +- .../Descriptors/EnumValueDescriptor.cs | 122 +- src/ProtocolBuffers/Descriptors/FieldDescriptor.cs | 1187 +- .../Descriptors/FieldMappingAttribute.cs | 165 +- src/ProtocolBuffers/Descriptors/FieldType.cs | 118 +- src/ProtocolBuffers/Descriptors/FileDescriptor.cs | 926 +- src/ProtocolBuffers/Descriptors/IDescriptor.cs | 108 +- .../Descriptors/IndexedDescriptorBase.cs | 125 +- src/ProtocolBuffers/Descriptors/MappedType.cs | 102 +- .../Descriptors/MessageDescriptor.cs | 540 +- .../Descriptors/MethodDescriptor.cs | 180 +- .../Descriptors/PackageDescriptor.cs | 140 +- .../Descriptors/ServiceDescriptor.cs | 172 +- src/ProtocolBuffers/DynamicMessage.cs | 946 +- src/ProtocolBuffers/EnumLite.cs | 249 +- src/ProtocolBuffers/ExtendableBuilder.cs | 392 +- src/ProtocolBuffers/ExtendableBuilderLite.cs | 594 +- src/ProtocolBuffers/ExtendableMessage.cs | 493 +- src/ProtocolBuffers/ExtendableMessageLite.cs | 402 +- src/ProtocolBuffers/ExtensionInfo.cs | 163 +- src/ProtocolBuffers/ExtensionRegistry.cs | 437 +- src/ProtocolBuffers/ExtensionRegistryLite.cs | 376 +- .../FieldAccess/FieldAccessorTable.cs | 231 +- src/ProtocolBuffers/FieldAccess/IFieldAccessor.cs | 186 +- src/ProtocolBuffers/FieldAccess/ReflectionUtil.cs | 260 +- .../FieldAccess/RepeatedEnumAccessor.cs | 160 +- .../FieldAccess/RepeatedMessageAccessor.cs | 187 +- .../FieldAccess/RepeatedPrimitiveAccessor.cs | 302 +- .../FieldAccess/SingleEnumAccessor.cs | 142 +- .../FieldAccess/SingleMessageAccessor.cs | 169 +- .../FieldAccess/SinglePrimitiveAccessor.cs | 257 +- src/ProtocolBuffers/FieldSet.cs | 1157 +- src/ProtocolBuffers/GeneratedBuilder.cs | 456 +- src/ProtocolBuffers/GeneratedBuilderLite.cs | 250 +- src/ProtocolBuffers/GeneratedExtensionBase.cs | 344 +- src/ProtocolBuffers/GeneratedExtensionLite.cs | 634 +- src/ProtocolBuffers/GeneratedMessage.cs | 331 +- src/ProtocolBuffers/GeneratedMessageLite.cs | 305 +- src/ProtocolBuffers/GeneratedRepeatExtension.cs | 164 +- src/ProtocolBuffers/GeneratedSingleExtension.cs | 123 +- src/ProtocolBuffers/IBuilder.cs | 611 +- src/ProtocolBuffers/IBuilderLite.cs | 425 +- src/ProtocolBuffers/IMessage.cs | 485 +- src/ProtocolBuffers/IMessageLite.cs | 369 +- src/ProtocolBuffers/IRpcChannel.cs | 122 +- src/ProtocolBuffers/IRpcController.cs | 243 +- src/ProtocolBuffers/IRpcDispatch.cs | 31 +- src/ProtocolBuffers/IService.cs | 200 +- .../InvalidProtocolBufferException.cs | 211 +- src/ProtocolBuffers/MessageStreamIterator.cs | 445 +- src/ProtocolBuffers/MessageStreamWriter.cs | 134 +- src/ProtocolBuffers/MessageUtil.cs | 203 +- src/ProtocolBuffers/NameHelpers.cs | 246 +- src/ProtocolBuffers/Properties/AssemblyInfo.cs | 7 +- src/ProtocolBuffers/RpcUtil.cs | 68 +- src/ProtocolBuffers/SilverlightCompatibility.cs | 6 +- src/ProtocolBuffers/SortedList.cs | 13 +- src/ProtocolBuffers/TextFormat.cs | 1346 +- src/ProtocolBuffers/TextGenerator.cs | 202 +- src/ProtocolBuffers/TextTokenizer.cs | 779 +- src/ProtocolBuffers/ThrowHelper.cs | 70 +- .../UninitializedMessageException.cs | 262 +- src/ProtocolBuffers/UnknownField.cs | 644 +- src/ProtocolBuffers/UnknownFieldSet.cs | 1463 +- src/ProtocolBuffers/WireFormat.cs | 271 +- .../AbstractBuilderLiteTest.cs | 495 +- .../AbstractMessageLiteTest.cs | 162 +- .../ExtendableBuilderLiteTest.cs | 472 +- .../ExtendableMessageLiteTest.cs | 510 +- src/ProtocolBuffersLite.Test/InteropLiteTest.cs | 268 +- src/ProtocolBuffersLite.Test/LiteTest.cs | 130 +- .../MissingFieldAndExtensionTest.cs | 53 +- src/ProtocolBuffersLite.Test/TestLiteByApi.cs | 152 +- 163 files changed, 46300 insertions(+), 37493 deletions(-) diff --git a/src/AddressBook/AddPerson.cs b/src/AddressBook/AddPerson.cs index 9d2eaa2a..462b0c56 100644 --- a/src/AddressBook/AddPerson.cs +++ b/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 { - - /// - /// Builds a person based on user input - /// - 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(); - } - - /// - /// Entry point - loads an existing addressbook or creates a new one, - /// then writes it back to the file. - /// - 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 + { + /// + /// Builds a person based on user input + /// + 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(); + } + + /// + /// Entry point - loads an existing addressbook or creates a new one, + /// then writes it back to the file. + /// + 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; + } + } } \ No newline at end of file diff --git a/src/AddressBook/ListPeople.cs b/src/AddressBook/ListPeople.cs index 6c8111df..fe6f52d8 100644 --- a/src/AddressBook/ListPeople.cs +++ b/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 { - /// - /// Iterates though all people in the AddressBook and prints info about them. - /// - 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); - } - } - } - - /// - /// Entry point - loads the addressbook and then displays it. - /// - 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 + { + /// + /// Iterates though all people in the AddressBook and prints info about them. + /// + 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); + } + } + } + + /// + /// Entry point - loads the addressbook and then displays it. + /// + 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; + } + } +} \ No newline at end of file diff --git a/src/AddressBook/Program.cs b/src/AddressBook/Program.cs index dd6e148c..e0d6d49b 100644 --- a/src/AddressBook/Program.cs +++ b/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 -{ - /// - /// 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. - /// - 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 +{ + /// + /// 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. + /// + 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; + } + } } \ No newline at end of file diff --git a/src/AddressBook/Properties/AssemblyInfo.cs b/src/AddressBook/Properties/AssemblyInfo.cs index 118595fc..614e1b48 100644 --- a/src/AddressBook/Properties/AssemblyInfo.cs +++ b/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")] \ No newline at end of file diff --git a/src/AddressBook/SampleUsage.cs b/src/AddressBook/SampleUsage.cs index ae7b6802..084b1655 100644 --- a/src/AddressBook/SampleUsage.cs +++ b/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!"); + } } -} -} +} \ No newline at end of file diff --git a/src/ProtoBench/Program.cs b/src/ProtoBench/Program.cs index 7a9370e4..6203486c 100644 --- a/src/ProtoBench/Program.cs +++ b/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 -{ - /// - /// Simple benchmarking of arbitrary messages. - /// - 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 "); - 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; - } - - /// - /// Runs a single test. Error messages are displayed to Console.Error, and the return value indicates - /// general success/failure. - /// - 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 +{ + /// + /// Simple benchmarking of arbitrary messages. + /// + 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 "); + 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; + } + + /// + /// Runs a single test. Error messages are displayed to Console.Error, and the return value indicates + /// general success/failure. + /// + 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; + } + } } \ No newline at end of file diff --git a/src/ProtoBench/Properties/AssemblyInfo.cs b/src/ProtoBench/Properties/AssemblyInfo.cs index a91c85e3..a5779209 100644 --- a/src/ProtoBench/Properties/AssemblyInfo.cs +++ b/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")] \ No newline at end of file diff --git a/src/ProtoDump/Program.cs b/src/ProtoDump/Program.cs index ce4f5df4..a935e780 100644 --- a/src/ProtoDump/Program.cs +++ b/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 -{ - /// - /// Small utility to load a binary message and dump it in text form - /// - class Program { - static int Main(string[] args) { - if (args.Length != 2) { - Console.Error.WriteLine("Usage: ProtoDump "); - 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 +{ + /// + /// Small utility to load a binary message and dump it in text form + /// + internal class Program + { + private static int Main(string[] args) + { + if (args.Length != 2) + { + Console.Error.WriteLine("Usage: ProtoDump "); + 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; + } + } + } } \ No newline at end of file diff --git a/src/ProtoDump/Properties/AssemblyInfo.cs b/src/ProtoDump/Properties/AssemblyInfo.cs index 02580820..816d6f98 100644 --- a/src/ProtoDump/Properties/AssemblyInfo.cs +++ b/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")] \ No newline at end of file diff --git a/src/ProtoDump/app.config b/src/ProtoDump/app.config index 0df7832f..285f9f93 100644 --- a/src/ProtoDump/app.config +++ b/src/ProtoDump/app.config @@ -1,3 +1,5 @@ - - - + + + + + \ No newline at end of file diff --git a/src/ProtoGen.Test/DependencyResolutionTest.cs b/src/ProtoGen.Test/DependencyResolutionTest.cs index 7e19d443..8ac5b348 100644 --- a/src/ProtoGen.Test/DependencyResolutionTest.cs +++ b/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 { - /// - /// Tests for the dependency resolution in Generator. - /// - [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 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 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 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 +{ + /// + /// Tests for the dependency resolution in Generator. + /// + [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 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 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 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 + } + } + } } \ No newline at end of file diff --git a/src/ProtoGen.Test/Properties/AssemblyInfo.cs b/src/ProtoGen.Test/Properties/AssemblyInfo.cs index d663c00a..8a64bf4b 100644 --- a/src/ProtoGen.Test/Properties/AssemblyInfo.cs +++ b/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")] \ No newline at end of file diff --git a/src/ProtoGen.Test/TempFile.cs b/src/ProtoGen.Test/TempFile.cs index e41b591b..74a183f5 100644 --- a/src/ProtoGen.Test/TempFile.cs +++ b/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); + } + } + } +} \ No newline at end of file diff --git a/src/ProtoGen.Test/TestPreprocessing.cs b/src/ProtoGen.Test/TestPreprocessing.cs index 53cd5fec..af1d22ab 100644 --- a/src/ProtoGen.Test/TestPreprocessing.cs +++ b/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 args = new List(); - 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 args = new List(); + 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); + } + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/DependencyResolutionException.cs b/src/ProtoGen/DependencyResolutionException.cs index b41149b6..aef192e0 100644 --- a/src/ProtoGen/DependencyResolutionException.cs +++ b/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 { - /// - /// Exception thrown when dependencies within a descriptor set can't be resolved. - /// - 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 +{ + /// + /// Exception thrown when dependencies within a descriptor set can't be resolved. + /// + public sealed class DependencyResolutionException : Exception + { + public DependencyResolutionException(string message) : base(message) + { + } + + public DependencyResolutionException(string format, params object[] args) + : base(string.Format(format, args)) + { + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/DescriptorUtil.cs b/src/ProtoGen/DescriptorUtil.cs index af5a2f9a..0666bb93 100644 --- a/src/ProtoGen/DescriptorUtil.cs +++ b/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 { - /// - /// Utility class for determining namespaces etc. - /// - 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; - } - - /// - /// 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. - /// - 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 +{ + /// + /// Utility class for determining namespaces etc. + /// + 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; + } + + /// + /// 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. + /// + 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); + } + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/EnumFieldGenerator.cs b/src/ProtoGen/EnumFieldGenerator.cs index 6cd59869..fe0d3bab 100644 --- a/src/ProtoGen/EnumFieldGenerator.cs +++ b/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); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/EnumGenerator.cs b/src/ProtoGen/EnumGenerator.cs index bc07e219..c1013345 100644 --- a/src/ProtoGen/EnumGenerator.cs +++ b/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, 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, 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(); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/ExtensionGenerator.cs b/src/ProtoGen/ExtensionGenerator.cs index 57713bf7..ce37b2de 100644 --- a/src/ProtoGen/ExtensionGenerator.cs +++ b/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> {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> {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) + { + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/FieldGeneratorBase.cs b/src/ProtoGen/FieldGeneratorBase.cs index 45a096a0..c4f5dbf4 100644 --- a/src/ProtoGen/FieldGeneratorBase.cs +++ b/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 { - 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; - } - - /// Copy exists in ExtensionGenerator.cs - 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)]"); - } - } - - /// - /// For encodings with fixed sizes, returns that size in bytes. Otherwise - /// returns -1. TODO(jonskeet): Make this less ugly. - /// - 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"; } - } - - /// - /// Returns the type name as used in CodedInputStream method names: SFixed32, UInt32 etc. - /// - 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 + { + 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; + } + + /// Copy exists in ExtensionGenerator.cs + 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)]"); + } + } + + /// + /// For encodings with fixed sizes, returns that size in bytes. Otherwise + /// returns -1. TODO(jonskeet): Make this less ugly. + /// + 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"; } + } + + /// + /// Returns the type name as used in CodedInputStream method names: SFixed32, UInt32 etc. + /// + protected string CapitalizedTypeName + { + get + { + // Our enum names match perfectly. How serendipitous. + return Descriptor.FieldType.ToString(); + } + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/Generator.cs b/src/ProtoGen/Generator.cs index 13797487..a3c6a504 100644 --- a/src/ProtoGen/Generator.cs +++ b/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 { - /// - /// Code generator for protocol buffers. Only C# is supported at the moment. - /// - public sealed class Generator { - - private readonly GeneratorOptions options; - - private Generator(GeneratorOptions options) { - options.Validate(); - this.options = options; - } - - /// - /// Returns a generator configured with the specified options. - /// - public static Generator CreateGenerator(GeneratorOptions options) { - return new Generator(options); - } - - public void Generate() { - List descriptorProtos = new List(); - 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 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); - } - } - - /// - /// Generates code for a particular file. All dependencies must - /// already have been resolved. - /// - 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); - } - - /// - /// 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. - /// - /// Not all dependencies could be resolved. - public static IList 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 fileList = new List(); - foreach (FileDescriptorSet set in descriptorProtos) - fileList.AddRange(set.FileList); - - FileDescriptor[] converted = new FileDescriptor[fileList.Count]; - - Dictionary convertedMap = new Dictionary(); - - 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 +{ + /// + /// Code generator for protocol buffers. Only C# is supported at the moment. + /// + public sealed class Generator + { + private readonly GeneratorOptions options; + + private Generator(GeneratorOptions options) + { + options.Validate(); + this.options = options; + } + + /// + /// Returns a generator configured with the specified options. + /// + public static Generator CreateGenerator(GeneratorOptions options) + { + return new Generator(options); + } + + public void Generate() + { + List descriptorProtos = new List(); + 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 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); + } + } + + /// + /// Generates code for a particular file. All dependencies must + /// already have been resolved. + /// + 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); + } + + /// + /// 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. + /// + /// Not all dependencies could be resolved. + public static IList 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 fileList = new List(); + foreach (FileDescriptorSet set in descriptorProtos) + fileList.AddRange(set.FileList); + + FileDescriptor[] converted = new FileDescriptor[fileList.Count]; + + Dictionary convertedMap = new Dictionary(); + + 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); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/GeneratorOptions.cs b/src/ProtoGen/GeneratorOptions.cs index 05317724..ec500d82 100644 --- a/src/ProtoGen/GeneratorOptions.cs +++ b/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 { - /// - /// 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. - /// - public sealed class GeneratorOptions { - - private static Dictionary LineBreaks = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { - { "Windows", "\r\n" }, - { "Unix", "\n" }, - { "Default", Environment.NewLine } - }; - - public IList InputFiles { get; set; } - - public GeneratorOptions() { - LineBreak = Environment.NewLine; - } - - /// - /// 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. - /// - /// Variable to receive a list of reasons in case of validation failure. - /// true if the options are valid; false otherwise - public bool TryValidate(out IList reasons) { - List tmpReasons = new List(); - - 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; - } - - /// - /// Validates that all the options have been set and are valid, - /// throwing an exception if they haven't. - /// - /// The options are invalid. - public void Validate() { - IList reasons; - if (!TryValidate(out reasons)) { - throw new InvalidOptionsException(reasons); - } - } - - // Raw arguments, used to provide defaults for proto file options - public IList 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(@"^[-/](?[\w_]+?)[:=](?.*)$"); - private CSharpFileOptions fileOptions; - - public CSharpFileOptions FileOptions { - get { return fileOptions ?? (fileOptions = CSharpFileOptions.DefaultInstance); } - set { fileOptions = value; } - } - - public string LineBreak { get; set; } - - private void ParseArguments(IList tmpReasons) { - bool doHelp = Arguments.Count == 0; - - InputFiles = new List(); - CSharpFileOptions.Builder builder = FileOptions.ToBuilder(); - Dictionary fields = - new Dictionary(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 field in fields) { - tmpReasons.Add(String.Format("-{0}=[{1}]", field.Key, field.Value.FieldType)); - } - tmpReasons.Add("-line_break=[" + string.Join("|", new List(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 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 +{ + /// + /// 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. + /// + public sealed class GeneratorOptions + { + private static Dictionary LineBreaks = + new Dictionary(StringComparer.InvariantCultureIgnoreCase) + { + {"Windows", "\r\n"}, + {"Unix", "\n"}, + {"Default", Environment.NewLine} + }; + + public IList InputFiles { get; set; } + + public GeneratorOptions() + { + LineBreak = Environment.NewLine; + } + + /// + /// 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. + /// + /// Variable to receive a list of reasons in case of validation failure. + /// true if the options are valid; false otherwise + public bool TryValidate(out IList reasons) + { + List tmpReasons = new List(); + + 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; + } + + /// + /// Validates that all the options have been set and are valid, + /// throwing an exception if they haven't. + /// + /// The options are invalid. + public void Validate() + { + IList reasons; + if (!TryValidate(out reasons)) + { + throw new InvalidOptionsException(reasons); + } + } + + // Raw arguments, used to provide defaults for proto file options + public IList 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(@"^[-/](?[\w_]+?)[:=](?.*)$"); + private CSharpFileOptions fileOptions; + + public CSharpFileOptions FileOptions + { + get { return fileOptions ?? (fileOptions = CSharpFileOptions.DefaultInstance); } + set { fileOptions = value; } + } + + public string LineBreak { get; set; } + + private void ParseArguments(IList tmpReasons) + { + bool doHelp = Arguments.Count == 0; + + InputFiles = new List(); + CSharpFileOptions.Builder builder = FileOptions.ToBuilder(); + Dictionary fields = + new Dictionary(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 field in fields) + { + tmpReasons.Add(String.Format("-{0}=[{1}]", field.Key, field.Value.FieldType)); + } + tmpReasons.Add("-line_break=[" + string.Join("|", new List(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 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; + } + } } \ No newline at end of file diff --git a/src/ProtoGen/Helpers.cs b/src/ProtoGen/Helpers.cs index 6b6e3163..3c001150 100644 --- a/src/ProtoGen/Helpers.cs +++ b/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 { - - /// - /// Helpers to resolve class names etc. - /// - 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 +{ + /// + /// Helpers to resolve class names etc. + /// + internal static class Helpers + { + } +} \ No newline at end of file diff --git a/src/ProtoGen/IFieldSourceGenerator.cs b/src/ProtoGen/IFieldSourceGenerator.cs index 9c71a579..f53ae5e4 100644 --- a/src/ProtoGen/IFieldSourceGenerator.cs +++ b/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); + } +} \ No newline at end of file diff --git a/src/ProtoGen/ISourceGenerator.cs b/src/ProtoGen/ISourceGenerator.cs index c2d172e7..452d854a 100644 --- a/src/ProtoGen/ISourceGenerator.cs +++ b/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); + } +} \ No newline at end of file diff --git a/src/ProtoGen/InvalidOptionsException.cs b/src/ProtoGen/InvalidOptionsException.cs index c1fcdd6a..fb698495 100644 --- a/src/ProtoGen/InvalidOptionsException.cs +++ b/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 { - /// - /// Exception thrown to indicate that the options passed were invalid. - /// - public sealed class InvalidOptionsException : Exception { - - private readonly IList reasons; - - /// - /// An immutable list of reasons why the options were invalid. - /// - public IList Reasons { - get { return reasons; } - } - - public InvalidOptionsException(IList reasons) - : base(BuildMessage(reasons)) { - this.reasons = Lists.AsReadOnly(reasons); - } - - private static string BuildMessage(IEnumerable 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 +{ + /// + /// Exception thrown to indicate that the options passed were invalid. + /// + public sealed class InvalidOptionsException : Exception + { + private readonly IList reasons; + + /// + /// An immutable list of reasons why the options were invalid. + /// + public IList Reasons + { + get { return reasons; } + } + + public InvalidOptionsException(IList reasons) + : base(BuildMessage(reasons)) + { + this.reasons = Lists.AsReadOnly(reasons); + } + + private static string BuildMessage(IEnumerable reasons) + { + StringBuilder builder = new StringBuilder("Invalid options:"); + builder.AppendLine(); + foreach (string reason in reasons) + { + builder.Append(" "); + builder.AppendLine(reason); + } + return builder.ToString(); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/MessageFieldGenerator.cs b/src/ProtoGen/MessageFieldGenerator.cs index d952984a..495a461d 100644 --- a/src/ProtoGen/MessageFieldGenerator.cs +++ b/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); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/MessageGenerator.cs b/src/ProtoGen/MessageGenerator.cs index 43b8b7eb..9eff86c4 100644 --- a/src/ProtoGen/MessageGenerator.cs +++ b/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, ISourceGenerator { - internal MessageGenerator(MessageDescriptor descriptor) : base(descriptor) { - } - - private string ClassName { - get { return Descriptor.Name; } - } - - private string FullClassName { - get { return GetClassName(Descriptor); } - } - - /// - /// 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. - /// - 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 sorted = new List(Descriptor.Fields); - sorted.Sort(new Comparison(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 sortedFields = new List(Descriptor.Fields); - sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber)); - - List sortedExtensions = new List(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("}"); - } - - /// - /// 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? - /// - private static bool HasRequiredFields(MessageDescriptor descriptor, Dictionary 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 sortedFields = new List(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())) { - 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, ISourceGenerator + { + internal MessageGenerator(MessageDescriptor descriptor) : base(descriptor) + { + } + + private string ClassName + { + get { return Descriptor.Name; } + } + + private string FullClassName + { + get { return GetClassName(Descriptor); } + } + + /// + /// 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. + /// + 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 sorted = new List(Descriptor.Fields); + sorted.Sort( + new Comparison( + 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 sortedFields = new List(Descriptor.Fields); + sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber)); + + List sortedExtensions = new List(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("}"); + } + + /// + /// 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? + /// + private static bool HasRequiredFields(MessageDescriptor descriptor, + Dictionary 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 sortedFields = new List(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())) + { + 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); + } + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/PrimitiveFieldGenerator.cs b/src/ProtoGen/PrimitiveFieldGenerator.cs index dbc203d0..ed7d0dc1 100644 --- a/src/ProtoGen/PrimitiveFieldGenerator.cs +++ b/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); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/Program.cs b/src/ProtoGen/Program.cs index e8c486cf..4bd6c463 100644 --- a/src/ProtoGen/Program.cs +++ b/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 { - /// - /// Entry point for the Protocol Buffers generator. - /// - 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 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 +{ + /// + /// Entry point for the Protocol Buffers generator. + /// + 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 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; + } + } + } } \ No newline at end of file diff --git a/src/ProtoGen/ProgramPreprocess.cs b/src/ProtoGen/ProgramPreprocess.cs index 3cc0826d..ed582989 100644 --- a/src/ProtoGen/ProgramPreprocess.cs +++ b/src/ProtoGen/ProgramPreprocess.cs @@ -1,153 +1,186 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; - -namespace Google.ProtocolBuffers.ProtoGen { - /// - /// 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. - /// - 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 protocArgs = new List(); - List protoGenArgs = new List(); - - 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 searchPath = new List(); - 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 +{ + /// + /// 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. + /// + 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 protocArgs = new List(); + List protoGenArgs = new List(); + + 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 searchPath = new List(); + 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; + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/Properties/AssemblyInfo.cs b/src/ProtoGen/Properties/AssemblyInfo.cs index 7f77b259..a8b228c0 100644 --- a/src/ProtoGen/Properties/AssemblyInfo.cs +++ b/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")] \ No newline at end of file diff --git a/src/ProtoGen/RepeatedEnumFieldGenerator.cs b/src/ProtoGen/RepeatedEnumFieldGenerator.cs index c500d38b..e98bc929 100644 --- a/src/ProtoGen/RepeatedEnumFieldGenerator.cs +++ b/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); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/RepeatedMessageFieldGenerator.cs b/src/ProtoGen/RepeatedMessageFieldGenerator.cs index 4461190f..c882f562 100644 --- a/src/ProtoGen/RepeatedMessageFieldGenerator.cs +++ b/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); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs b/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs index d670c4ce..b7fe19b3 100644 --- a/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs +++ b/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); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/ServiceGenerator.cs b/src/ProtoGen/ServiceGenerator.cs index 3c70b9ce..baeee4f4 100644 --- a/src/ProtoGen/ServiceGenerator.cs +++ b/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, 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, 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 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 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("}"); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/ServiceInterfaceGenerator.cs b/src/ProtoGen/ServiceInterfaceGenerator.cs index 019df4c8..698b7016 100644 --- a/src/ProtoGen/ServiceInterfaceGenerator.cs +++ b/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, 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, ISourceGenerator + { + private readonly CSharpServiceType svcType; + private ISourceGenerator _generator; - public void Generate(TextGenerator writer) { - _generator.Generate(writer); - } - - class NoServicesGenerator : SourceGeneratorBase, 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, 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, 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, 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(string method, pb::IMessageLite request, pb::IBuilderLite 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(string methodName, pb::IMessageLite request, pb::IBuilderLite response)"); - writer.WriteLine(" where TMessage : IMessageLite"); - writer.WriteLine(" where TBuilder : IBuilderLite {"); - 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(string method, pb::IMessageLite request, pb::IBuilderLite 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(string methodName, pb::IMessageLite request, pb::IBuilderLite response)"); + writer.WriteLine(" where TMessage : IMessageLite"); + writer.WriteLine(" where TBuilder : IBuilderLite {"); + 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("}"); + } + } } - } -} +} \ No newline at end of file diff --git a/src/ProtoGen/SourceGeneratorBase.cs b/src/ProtoGen/SourceGeneratorBase.cs index a7dc2f93..4b9d6ec3 100644 --- a/src/ProtoGen/SourceGeneratorBase.cs +++ b/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 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(TextGenerator writer, string region, IEnumerable children) - where TChild : IDescriptor { - // Copy the set of children; makes access easier - List copy = new List(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 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(TextGenerator writer, string region, IEnumerable children) + where TChild : IDescriptor + { + // Copy the set of children; makes access easier + List copy = new List(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(); + } + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/SourceGenerators.cs b/src/ProtoGen/SourceGenerators.cs index 33f5573e..398868cb 100644 --- a/src/ProtoGen/SourceGenerators.cs +++ b/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 arg); - - internal static class SourceGenerators { - - private static readonly Dictionary> GeneratorFactories = new Dictionary> { - { 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 descriptor) where T : IDescriptor { - Func 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 arg); + + internal static class SourceGenerators + { + private static readonly Dictionary> GeneratorFactories = new Dictionary + > + { + { + 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 descriptor) where T : IDescriptor + { + Func factory; + if (!GeneratorFactories.TryGetValue(typeof (T), out factory)) + { + throw new ArgumentException("No generator registered for " + typeof (T).Name); + } + return factory(descriptor); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/UmbrellaClassGenerator.cs b/src/ProtoGen/UmbrellaClassGenerator.cs index e1bbee5d..4e5f8ae4 100644 --- a/src/ProtoGen/UmbrellaClassGenerator.cs +++ b/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 { - /// - /// Generator for the class describing the .proto file in general, - /// containing things like the message descriptor. - /// - internal sealed class UmbrellaClassGenerator : SourceGeneratorBase, 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 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 +{ + /// + /// Generator for the class describing the .proto file in general, + /// containing things like the message descriptor. + /// + internal sealed class UmbrellaClassGenerator : SourceGeneratorBase, 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 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(); + } + } +} \ No newline at end of file diff --git a/src/ProtoGen/app.config b/src/ProtoGen/app.config index 0df7832f..285f9f93 100644 --- a/src/ProtoGen/app.config +++ b/src/ProtoGen/app.config @@ -1,3 +1,5 @@ - - - + + + + + \ No newline at end of file diff --git a/src/ProtoMunge/Program.cs b/src/ProtoMunge/Program.cs index 04a9c4ee..53dc3501 100644 --- a/src/ProtoMunge/Program.cs +++ b/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 -{ - /// - /// 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. - /// - public sealed class Program { - - static readonly Random rng = new Random(); - - static int Main(string[] args) { - if (args.Length != 3) { - Console.Error.WriteLine("Usage: ProtoMunge "); - 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; - } - } - - /// - /// Munges a message recursively. - /// - /// A new message of the same type as the original message, - /// but munged so that all the data is desensitised. - 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; - } - - /// - /// Munges a single value and checks that the length ends up the same as it was before. - /// - 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; - } - - /// - /// 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). - /// - 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); - } - - /// - /// 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. - /// - 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); - } - - /// - /// Returns a random number in the range [min, max] (both inclusive). - /// - 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 sameSizeValues = new List (); - 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 +{ + /// + /// 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. + /// + 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 "); + 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; + } + } + + /// + /// Munges a message recursively. + /// + /// A new message of the same type as the original message, + /// but munged so that all the data is desensitised. + 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; + } + + /// + /// Munges a single value and checks that the length ends up the same as it was before. + /// + 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; + } + + /// + /// 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). + /// + 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); + } + + /// + /// 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. + /// + 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); + } + + /// + /// Returns a random number in the range [min, max] (both inclusive). + /// + 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 sameSizeValues = new List(); + 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); + } + } } \ No newline at end of file diff --git a/src/ProtoMunge/Properties/AssemblyInfo.cs b/src/ProtoMunge/Properties/AssemblyInfo.cs index fe6440b0..5e62c848 100644 --- a/src/ProtoMunge/Properties/AssemblyInfo.cs +++ b/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")] \ No newline at end of file diff --git a/src/ProtoMunge/app.config b/src/ProtoMunge/app.config index 0df7832f..285f9f93 100644 --- a/src/ProtoMunge/app.config +++ b/src/ProtoMunge/app.config @@ -1,3 +1,5 @@ - - - + + + + + \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/AbstractMessageTest.cs b/src/ProtocolBuffers.Test/AbstractMessageTest.cs index 3f7b8648..e300ac94 100644 --- a/src/ProtocolBuffers.Test/AbstractMessageTest.cs +++ b/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); - } - - /// - /// Asserts that the given protos are equal and have the same hash code. - /// - 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); - } - - /// - /// Asserts that the given protos are equal and have the same hash code. - /// - private static void CheckEqualsIsConsistent(IMessage message1, IMessage message2) { - Assert.AreEqual(message1, message2); - Assert.AreEqual(message2, message1); - Assert.AreEqual(message2.GetHashCode(), message1.GetHashCode()); - } - - /// - /// Asserts that the given protos are not equal and have different hash codes. - /// - /// - /// 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.) - /// - 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)); - } - - /// - /// 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. - /// - private class AbstractMessageWrapper : AbstractMessage { - 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 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 { - 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 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); + } + + /// + /// Asserts that the given protos are equal and have the same hash code. + /// + 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); + } + + /// + /// Asserts that the given protos are equal and have the same hash code. + /// + private static void CheckEqualsIsConsistent(IMessage message1, IMessage message2) + { + Assert.AreEqual(message1, message2); + Assert.AreEqual(message2, message1); + Assert.AreEqual(message2.GetHashCode(), message1.GetHashCode()); + } + + /// + /// Asserts that the given protos are not equal and have different hash codes. + /// + /// + /// 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.) + /// + 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)); + } + + /// + /// 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. + /// + private class AbstractMessageWrapper : AbstractMessage + { + 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 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 + { + 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 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; + } + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/ByteStringTest.cs b/src/ProtocolBuffers.Test/ByteStringTest.cs index 6106368f..0ba665de 100644 --- a/src/ProtocolBuffers.Test/ByteStringTest.cs +++ b/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)); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/CSharpOptionsTest.cs b/src/ProtocolBuffers.Test/CSharpOptionsTest.cs index 2c755972..3901933b 100644 --- a/src/ProtocolBuffers.Test/CSharpOptionsTest.cs +++ b/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); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/CodedInputStreamTest.cs b/src/ProtocolBuffers.Test/CodedInputStreamTest.cs index 037e9a00..878febee 100644 --- a/src/ProtocolBuffers.Test/CodedInputStreamTest.cs +++ b/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 { - - /// - /// 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. - /// - 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; - } - - /// - /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and - /// - 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); - } - - /// - /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and - /// expects them to fail with an InvalidProtocolBufferException whose - /// description matches the given one. - /// - 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)); - } - - /// - /// Parses the given bytes using ReadRawLittleEndian32() and checks - /// that the result matches the given value. - /// - 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); - } - } - - /// - /// Parses the given bytes using ReadRawLittleEndian64() and checks - /// that the result matches the given value. - /// - 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); - } - } - - /// - /// Test that a bug in SkipRawBytes has been fixed: if the skip - /// skips exactly up to a limit, this should bnot break things - /// - [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. - } - } - - /// - /// 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. - /// - [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]); - } - - /// - /// 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. - /// - 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 + { + /// + /// 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. + /// + 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; + } + + /// + /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and + /// + 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); + } + + /// + /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and + /// expects them to fail with an InvalidProtocolBufferException whose + /// description matches the given one. + /// + 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)); + } + + /// + /// Parses the given bytes using ReadRawLittleEndian32() and checks + /// that the result matches the given value. + /// + 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); + } + } + + /// + /// Parses the given bytes using ReadRawLittleEndian64() and checks + /// that the result matches the given value. + /// + 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); + } + } + + /// + /// Test that a bug in SkipRawBytes has been fixed: if the skip + /// skips exactly up to a limit, this should bnot break things + /// + [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. + } + } + + /// + /// 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. + /// + [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]); + } + + /// + /// 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. + /// + 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)); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs b/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs index a8291a23..3dd2e0c3 100644 --- a/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs +++ b/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 { - - /// - /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and - /// checks that the result matches the given bytes - /// - 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()); - } - } - } - - /// - /// Tests WriteRawVarint32() and WriteRawVarint64() - /// - [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)))); - } - - /// - /// Parses the given bytes using WriteRawLittleEndian32() and checks - /// that the result matches the given value. - /// - 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()); - } - } - - /// - /// Parses the given bytes using WriteRawLittleEndian64() and checks - /// that the result matches the given value. - /// - 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()); - } - } - - /// - /// Tests writeRawLittleEndian32() and writeRawLittleEndian64(). - /// - [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()); - } - } - - /// - /// Tests writing a whole message with every packed field type. Ensures the - /// wire format of packed fields is compatible with C++. - /// - [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 + { + /// + /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and + /// checks that the result matches the given bytes + /// + 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()); + } + } + } + + /// + /// Tests WriteRawVarint32() and WriteRawVarint64() + /// + [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)))); + } + + /// + /// Parses the given bytes using WriteRawLittleEndian32() and checks + /// that the result matches the given value. + /// + 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()); + } + } + + /// + /// Parses the given bytes using WriteRawLittleEndian64() and checks + /// that the result matches the given value. + /// + 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()); + } + } + + /// + /// Tests writeRawLittleEndian32() and writeRawLittleEndian64(). + /// + [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()); + } + } + + /// + /// Tests writing a whole message with every packed field type. Ensures the + /// wire format of packed fields is compatible with C++. + /// + [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))); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/Collections/PopsicleListTest.cs b/src/ProtocolBuffers.Test/Collections/PopsicleListTest.cs index 6b42209b..c339cef6 100644 --- a/src/ProtocolBuffers.Test/Collections/PopsicleListTest.cs +++ b/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 list = new PopsicleList(); - 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 list = new PopsicleList(); - 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 list = new PopsicleList(); - 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 list = new PopsicleList(); - 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 list = new PopsicleList(); + 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 list = new PopsicleList(); + 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 list = new PopsicleList(); + 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 list = new PopsicleList(); + 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 + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/Descriptors/MessageDescriptorTest.cs b/src/ProtocolBuffers.Test/Descriptors/MessageDescriptorTest.cs index df3b236a..d536db2d 100644 --- a/src/ProtocolBuffers.Test/Descriptors/MessageDescriptorTest.cs +++ b/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")); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/DescriptorsTest.cs b/src/ProtocolBuffers.Test/DescriptorsTest.cs index f3c03cd6..671fb5a8 100644 --- a/src/ProtocolBuffers.Test/DescriptorsTest.cs +++ b/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 { - /// - /// 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...) - /// - [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("TestAllTypes")); - Assert.IsNull(file.FindTypeByName("NoSuchType")); - Assert.IsNull(file.FindTypeByName("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("ForeignEnum")); - Assert.IsNull(file.FindTypeByName("NoSuchType")); - Assert.IsNull(file.FindTypeByName("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("TestGenericService")); - Assert.IsNull(UnitTestGenericServices.Descriptor.FindTypeByName("NoSuchType")); - Assert.IsNull(UnitTestGenericServices.Descriptor.FindTypeByName("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("optional_int32_extension")); - Assert.IsNull(file.FindTypeByName("no_such_ext")); - Assert.IsNull(file.FindTypeByName("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("optional_int32")); - Assert.IsNull(messageType.FindDescriptor("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("NestedMessage")); - Assert.IsNull(messageType.FindDescriptor("NoSuchType")); - for (int i = 0; i < messageType.NestedTypes.Count; i++) { - Assert.AreEqual(i, messageType.NestedTypes[i].Index); - } - - Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor("NestedEnum")); - Assert.IsNull(messageType.FindDescriptor("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("optional_int32"); - FieldDescriptor enumField = messageType.FindDescriptor("optional_nested_enum"); - FieldDescriptor messageField = messageType.FindDescriptor("optional_foreign_message"); - FieldDescriptor cordField = messageType.FindDescriptor("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("a"); - FieldDescriptor optionalField = - TestAllTypes.Descriptor.FindDescriptor("optional_int32"); - FieldDescriptor repeatedField = - TestAllTypes.Descriptor.FindDescriptor("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("optional_int32").HasDefaultValue); - Assert.AreEqual(0, d.FindDescriptor("optional_int32").DefaultValue); - Assert.IsTrue(d.FindDescriptor("default_int32").HasDefaultValue); - Assert.AreEqual(41, d.FindDescriptor("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("escaped_bytes").DefaultValue); - Assert.AreEqual(uint.MaxValue, d.FindDescriptor("large_uint32").DefaultValue); - Assert.AreEqual(ulong.MaxValue, d.FindDescriptor("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("ForeignEnum"); - EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor("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 +{ + /// + /// 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...) + /// + [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("TestAllTypes")); + Assert.IsNull(file.FindTypeByName("NoSuchType")); + Assert.IsNull(file.FindTypeByName("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("ForeignEnum")); + Assert.IsNull(file.FindTypeByName("NoSuchType")); + Assert.IsNull(file.FindTypeByName("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("TestGenericService")); + Assert.IsNull(UnitTestGenericServices.Descriptor.FindTypeByName("NoSuchType")); + Assert.IsNull( + UnitTestGenericServices.Descriptor.FindTypeByName( + "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("optional_int32_extension")); + Assert.IsNull(file.FindTypeByName("no_such_ext")); + Assert.IsNull(file.FindTypeByName("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("optional_int32")); + Assert.IsNull(messageType.FindDescriptor("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("NestedMessage")); + Assert.IsNull(messageType.FindDescriptor("NoSuchType")); + for (int i = 0; i < messageType.NestedTypes.Count; i++) + { + Assert.AreEqual(i, messageType.NestedTypes[i].Index); + } + + Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor("NestedEnum")); + Assert.IsNull(messageType.FindDescriptor("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("optional_int32"); + FieldDescriptor enumField = messageType.FindDescriptor("optional_nested_enum"); + FieldDescriptor messageField = messageType.FindDescriptor("optional_foreign_message"); + FieldDescriptor cordField = messageType.FindDescriptor("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("a"); + FieldDescriptor optionalField = + TestAllTypes.Descriptor.FindDescriptor("optional_int32"); + FieldDescriptor repeatedField = + TestAllTypes.Descriptor.FindDescriptor("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("optional_int32").HasDefaultValue); + Assert.AreEqual(0, d.FindDescriptor("optional_int32").DefaultValue); + Assert.IsTrue(d.FindDescriptor("default_int32").HasDefaultValue); + Assert.AreEqual(41, d.FindDescriptor("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("escaped_bytes").DefaultValue); + Assert.AreEqual(uint.MaxValue, d.FindDescriptor("large_uint32").DefaultValue); + Assert.AreEqual(ulong.MaxValue, d.FindDescriptor("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("ForeignEnum"); + EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor("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)); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/DynamicMessageTest.cs b/src/ProtocolBuffers.Test/DynamicMessageTest.cs index e2971692..b6c8178a 100644 --- a/src/ProtocolBuffers.Test/DynamicMessageTest.cs +++ b/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 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 values = derived.UnknownFields.FieldDictionary[unknownFieldNum].VarintList; + Assert.AreEqual(1, values.Count); + Assert.AreEqual(unknownFieldVal, values[0]); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/ExtendableMessageTest.cs b/src/ProtocolBuffers.Test/ExtendableMessageTest.cs index 6ec0cf16..29423ff2 100644 --- a/src/ProtocolBuffers.Test/ExtendableMessageTest.cs +++ b/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)); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/GeneratedMessageTest.cs b/src/ProtocolBuffers.Test/GeneratedMessageTest.cs index b87794a5..410452d3 100644 --- a/src/ProtocolBuffers.Test/GeneratedMessageTest.cs +++ b/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 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 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("foreign_enum"); - Assert.AreEqual(MultiFileProto.Descriptor.FindTypeByName("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 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 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("foreign_enum"); + Assert.AreEqual(MultiFileProto.Descriptor.FindTypeByName("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); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/MessageStreamIteratorTest.cs b/src/ProtocolBuffers.Test/MessageStreamIteratorTest.cs index 38125de5..3e4eafe7 100644 --- a/src/ProtocolBuffers.Test/MessageStreamIteratorTest.cs +++ b/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 iterator = MessageStreamIterator.FromStreamProvider(() => stream); - List messages = new List(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 writer = new MessageStreamWriter(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.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 iterator = MessageStreamIterator.FromStreamProvider(() => stream); + List messages = new List(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 writer = new MessageStreamWriter(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.FromStreamProvider(() => stream) + .WithSizeLimit(CodedInputStream.BufferSize*2)) + { + count++; + TestUtil.AssertAllFieldsSet(message); + } + Assert.AreEqual(correctCount, count); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/MessageStreamWriterTest.cs b/src/ProtocolBuffers.Test/MessageStreamWriterTest.cs index 3be830a7..e2737914 100644 --- a/src/ProtocolBuffers.Test/MessageStreamWriterTest.cs +++ b/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 writer = new MessageStreamWriter(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 writer = new MessageStreamWriter(stream); + writer.Write(message1); + writer.Write(message2); + writer.Write(message3); + writer.Flush(); + data = stream.ToArray(); + } + + TestUtil.AssertEqualBytes(ThreeMessageData, data); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/MessageTest.cs b/src/ProtocolBuffers.Test/MessageTest.cs index e06254d7..0f2d1c9a 100644 --- a/src/ProtocolBuffers.Test/MessageTest.cs +++ b/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 { - /// - /// Miscellaneous tests for message operations that apply to both - /// generated and dynamic messages. - /// - [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()); - } - - /// - /// 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. - /// - [Test] - public void MergeFromDynamic() { - TestAllTypes result = (TestAllTypes) TestAllTypes.CreateBuilder(MergeDest) - .MergeFrom(DynamicMessage.CreateBuilder(MergeSource).Build()) - .Build(); - - Assert.AreEqual(MergeResultText, result.ToString()); - } - - /// - /// Test merging two DynamicMessages. - /// - [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("a")] = 1; - Assert.IsFalse(builder.IsInitialized); - builder[descriptor.FindDescriptor("b")] = 1; - Assert.IsFalse(builder.IsInitialized); - builder[descriptor.FindDescriptor("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("optional_message")] = TestRequiredUninitialized; - Assert.IsFalse(builder.IsInitialized); - - builder[descriptor.FindDescriptor("optional_message")] = TestRequiredInitialized; - Assert.IsTrue(builder.IsInitialized); - - builder.AddRepeatedField(descriptor.FindDescriptor("repeated_message"), TestRequiredUninitialized); - Assert.IsFalse(builder.IsInitialized); - - builder.SetRepeatedField(descriptor.FindDescriptor("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 +{ + /// + /// Miscellaneous tests for message operations that apply to both + /// generated and dynamic messages. + /// + [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()); + } + + /// + /// 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. + /// + [Test] + public void MergeFromDynamic() + { + TestAllTypes result = (TestAllTypes) TestAllTypes.CreateBuilder(MergeDest) + .MergeFrom(DynamicMessage.CreateBuilder(MergeSource).Build()) + .Build(); + + Assert.AreEqual(MergeResultText, result.ToString()); + } + + /// + /// Test merging two DynamicMessages. + /// + [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("a")] = 1; + Assert.IsFalse(builder.IsInitialized); + builder[descriptor.FindDescriptor("b")] = 1; + Assert.IsFalse(builder.IsInitialized); + builder[descriptor.FindDescriptor("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("optional_message")] = TestRequiredUninitialized; + Assert.IsFalse(builder.IsInitialized); + + builder[descriptor.FindDescriptor("optional_message")] = TestRequiredInitialized; + Assert.IsTrue(builder.IsInitialized); + + builder.AddRepeatedField(descriptor.FindDescriptor("repeated_message"), + TestRequiredUninitialized); + Assert.IsFalse(builder.IsInitialized); + + builder.SetRepeatedField(descriptor.FindDescriptor("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); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/MessageUtilTest.cs b/src/ProtocolBuffers.Test/MessageUtilTest.cs index 4054d5f8..c7e08fe8 100644 --- a/src/ProtocolBuffers.Test/MessageUtilTest.cs +++ b/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))); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/NameHelpersTest.cs b/src/ProtocolBuffers.Test/NameHelpersTest.cs index 61270116..b14b0fcf 100644 --- a/src/ProtocolBuffers.Test/NameHelpersTest.cs +++ b/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); + } + } } \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/Properties/AssemblyInfo.cs b/src/ProtocolBuffers.Test/Properties/AssemblyInfo.cs index d182bdbd..9c51aca6 100644 --- a/src/ProtocolBuffers.Test/Properties/AssemblyInfo.cs +++ b/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)] \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/ReflectionTester.cs b/src/ProtocolBuffers.Test/ReflectionTester.cs index 3e7ed390..5f323228 100644 --- a/src/ProtocolBuffers.Test/ReflectionTester.cs +++ b/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 { - /// - /// 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. - /// - 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; - - /// - /// Constructs an instance that will expect messages using the given - /// descriptor. Normally 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. - /// - 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("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("OptionalGroup"); - this.repeatedGroup = - testAllTypes.FindDescriptor("RepeatedGroup"); - } else { - this.optionalGroup = - file.FindTypeByName("OptionalGroup_extension"); - this.repeatedGroup = - file.FindTypeByName("RepeatedGroup_extension"); - } - this.nestedMessage = testAllTypes.FindDescriptor("NestedMessage"); - this.foreignMessage = file.FindTypeByName("ForeignMessage"); - this.importMessage = importFile.FindTypeByName("ImportMessage"); - - this.nestedEnum = testAllTypes.FindDescriptor("NestedEnum"); - this.foreignEnum = file.FindTypeByName("ForeignEnum"); - this.importEnum = importFile.FindTypeByName("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("bb"); - this.foreignC = foreignMessage.FindDescriptor("c"); - this.importD = importMessage.FindDescriptor("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("a"); - this.repeatedGroupA = repeatedGroup.FindDescriptor("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); - } - - /// - /// Creates an instance for the TestAllTypes message, with no extension registry. - /// - public static ReflectionTester CreateTestAllTypesInstance() { - return new ReflectionTester(TestAllTypes.Descriptor, null); - } - - /// - /// Creates an instance for the TestAllExtensions message, with an - /// extension registry from TestUtil.CreateExtensionRegistry. - /// - public static ReflectionTester CreateTestAllExtensionsInstance() { - return new ReflectionTester(TestAllExtensions.Descriptor, TestUtil.CreateExtensionRegistry()); - } - - /// - /// Creates an instance for the TestPackedTypes message, with no extensions. - /// - public static ReflectionTester CreateTestPackedTypesInstance() { - return new ReflectionTester(TestPackedTypes.Descriptor, null); - } - - /// - /// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. - /// - private FieldDescriptor f(String name) { - FieldDescriptor result; - if (extensionRegistry == null) { - result = baseDescriptor.FindDescriptor(name); - } else { - result = file.FindTypeByName(name + "_extension"); - } - Assert.IsNotNull(result); - return result; - } - - /// - /// Calls parent.CreateBuilderForField() or uses the extension registry - /// to find an appropriate builder, depending on what type is being tested. - /// - 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(); - } - } - - /// - /// Sets every field of the message to the values expected by - /// AssertAllFieldsSet, using the reflection interface. - /// - /// - 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"; - } - - // ------------------------------------------------------------------- - - /// - /// Modify the repeated fields of the specified message to contain the - /// values expected by AssertRepeatedFieldsModified, using the IBuilder - /// reflection interface. - /// - 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"; - } - - // ------------------------------------------------------------------- - - /// - /// Asserts that all fields of the specified message are set to the values - /// assigned by SetAllFields, using the IMessage reflection interface. - /// - 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")]); - } - - /// - /// Assert that all fields of the message are cleared, and that - /// getting the fields returns their default values, using the reflection interface. - /// - 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]); - } - - /// - /// Verifies that the reflection setters for the given Builder object throw an - /// ArgumentNullException if they are passed a null value. - /// - 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)); - } - - /// - /// Verifies that the reflection repeated setters for the given Builder object throw an - /// ArgumentNullException if they are passed a null value. - /// - 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 +{ + /// + /// 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. + /// + 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; + + /// + /// Constructs an instance that will expect messages using the given + /// descriptor. Normally 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. + /// + 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("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("OptionalGroup"); + this.repeatedGroup = + testAllTypes.FindDescriptor("RepeatedGroup"); + } + else + { + this.optionalGroup = + file.FindTypeByName("OptionalGroup_extension"); + this.repeatedGroup = + file.FindTypeByName("RepeatedGroup_extension"); + } + this.nestedMessage = testAllTypes.FindDescriptor("NestedMessage"); + this.foreignMessage = file.FindTypeByName("ForeignMessage"); + this.importMessage = importFile.FindTypeByName("ImportMessage"); + + this.nestedEnum = testAllTypes.FindDescriptor("NestedEnum"); + this.foreignEnum = file.FindTypeByName("ForeignEnum"); + this.importEnum = importFile.FindTypeByName("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("bb"); + this.foreignC = foreignMessage.FindDescriptor("c"); + this.importD = importMessage.FindDescriptor("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("a"); + this.repeatedGroupA = repeatedGroup.FindDescriptor("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); + } + + /// + /// Creates an instance for the TestAllTypes message, with no extension registry. + /// + public static ReflectionTester CreateTestAllTypesInstance() + { + return new ReflectionTester(TestAllTypes.Descriptor, null); + } + + /// + /// Creates an instance for the TestAllExtensions message, with an + /// extension registry from TestUtil.CreateExtensionRegistry. + /// + public static ReflectionTester CreateTestAllExtensionsInstance() + { + return new ReflectionTester(TestAllExtensions.Descriptor, TestUtil.CreateExtensionRegistry()); + } + + /// + /// Creates an instance for the TestPackedTypes message, with no extensions. + /// + public static ReflectionTester CreateTestPackedTypesInstance() + { + return new ReflectionTester(TestPackedTypes.Descriptor, null); + } + + /// + /// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. + /// + private FieldDescriptor f(String name) + { + FieldDescriptor result; + if (extensionRegistry == null) + { + result = baseDescriptor.FindDescriptor(name); + } + else + { + result = file.FindTypeByName(name + "_extension"); + } + Assert.IsNotNull(result); + return result; + } + + /// + /// Calls parent.CreateBuilderForField() or uses the extension registry + /// to find an appropriate builder, depending on what type is being tested. + /// + 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(); + } + } + + /// + /// Sets every field of the message to the values expected by + /// AssertAllFieldsSet, using the reflection interface. + /// + /// + 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"; + } + + // ------------------------------------------------------------------- + + /// + /// Modify the repeated fields of the specified message to contain the + /// values expected by AssertRepeatedFieldsModified, using the IBuilder + /// reflection interface. + /// + 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"; + } + + // ------------------------------------------------------------------- + + /// + /// Asserts that all fields of the specified message are set to the values + /// assigned by SetAllFields, using the IMessage reflection interface. + /// + 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")]); + } + + /// + /// Assert that all fields of the message are cleared, and that + /// getting the fields returns their default values, using the reflection interface. + /// + 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]); + } + + /// + /// Verifies that the reflection setters for the given Builder object throw an + /// ArgumentNullException if they are passed a null value. + /// + 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)); + } + + /// + /// Verifies that the reflection repeated setters for the given Builder object throw an + /// ArgumentNullException if they are passed a null value. + /// + 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]); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/ServiceTest.cs b/src/ProtocolBuffers.Test/ServiceTest.cs index 579c4582..dbfa10c9 100644 --- a/src/ProtocolBuffers.Test/ServiceTest.cs +++ b/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 { - - /// - /// Tests for generated service classes. - /// TODO(jonskeet): Convert the mocking tests using Rhino.Mocks. - /// - [TestFixture] - public class ServiceTest { - - delegate void Action(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(); - - bool fooCalled = false; - - TestGenericService service = new TestServiceImpl((request, responseAction) => { - Assert.AreSame(fooRequest, request); - fooCalled = true; - responseAction(fooResponse); - }, null, controller); - - bool doneHandlerCalled = false; - Action 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 doneHandler); - - /// - /// 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. - /// - [Test] - [Ignore("Crashes Mono - needs further investigation")] - public void GeneratedStubFooCall() { - FooRequest fooRequest = FooRequest.CreateBuilder().Build(); - MockRepository mocks = new MockRepository(); - IRpcChannel mockChannel = mocks.StrictMock(); - IRpcController mockController = mocks.StrictMock(); - TestGenericService service = TestGenericService.CreateStub(mockChannel); - Action doneHandler = mocks.StrictMock>(); - - 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(); - - bool barCalled = false; - - TestGenericService service = new TestServiceImpl(null, (request, responseAction) => { - Assert.AreSame(barRequest, request); - barCalled = true; - responseAction(barResponse); - }, controller); - - bool doneHandlerCalled = false; - Action 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> fooHandler; - private readonly Action> barHandler; - private readonly IRpcController expectedController; - - internal TestServiceImpl() { - } - - internal TestServiceImpl(Action> fooHandler, - Action> barHandler, - IRpcController expectedController) { - this.fooHandler = fooHandler; - this.barHandler = barHandler; - this.expectedController = expectedController; - } - - public override void Foo(IRpcController controller, FooRequest request, Action done) { - Assert.AreSame(expectedController, controller); - fooHandler(request, done); - } - - public override void Bar(IRpcController controller, BarRequest request, Action 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 +{ + /// + /// Tests for generated service classes. + /// TODO(jonskeet): Convert the mocking tests using Rhino.Mocks. + /// + [TestFixture] + public class ServiceTest + { + private delegate void Action(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(); + + bool fooCalled = false; + + TestGenericService service = new TestServiceImpl((request, responseAction) => + { + Assert.AreSame(fooRequest, request); + fooCalled = true; + responseAction(fooResponse); + }, null, controller); + + bool doneHandlerCalled = false; + Action 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 doneHandler); + + /// + /// 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. + /// + [Test] + [Ignore("Crashes Mono - needs further investigation")] + public void GeneratedStubFooCall() + { + FooRequest fooRequest = FooRequest.CreateBuilder().Build(); + MockRepository mocks = new MockRepository(); + IRpcChannel mockChannel = mocks.StrictMock(); + IRpcController mockController = mocks.StrictMock(); + TestGenericService service = TestGenericService.CreateStub(mockChannel); + Action doneHandler = mocks.StrictMock>(); + + 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(); + + bool barCalled = false; + + TestGenericService service = new TestServiceImpl(null, (request, responseAction) => + { + Assert.AreSame(barRequest, request); + barCalled = true; + responseAction(barResponse); + }, controller); + + bool doneHandlerCalled = false; + Action 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> fooHandler; + private readonly Action> barHandler; + private readonly IRpcController expectedController; + + internal TestServiceImpl() + { + } + + internal TestServiceImpl(Action> fooHandler, + Action> barHandler, + IRpcController expectedController) + { + this.fooHandler = fooHandler; + this.barHandler = barHandler; + this.expectedController = expectedController; + } + + public override void Foo(IRpcController controller, FooRequest request, Action done) + { + Assert.AreSame(expectedController, controller); + fooHandler(request, done); + } + + public override void Bar(IRpcController controller, BarRequest request, Action done) + { + Assert.AreSame(expectedController, controller); + barHandler(request, done); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/TestRpcGenerator.cs b/src/ProtocolBuffers.Test/TestRpcGenerator.cs index ac98c496..5f159b62 100644 --- a/src/ProtocolBuffers.Test/TestRpcGenerator.cs +++ b/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 { - /// - /// A sample implementation of the ISearchService for testing - /// - class ExampleSearchImpl : ISearchService { - SearchResponse ISearchService.Search(SearchRequest searchRequest) { - if (searchRequest.CriteriaCount == 0) { - throw new ArgumentException("No criteria specified.", new InvalidOperationException()); + /// + /// A sample implementation of the ISearchService for testing + /// + 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(); + } + } + + /// + /// An example extraction of the wire protocol + /// + private interface IWireTransfer + { + byte[] Execute(string method, byte[] message); + } + + /// + /// An example of a server responding to a wire request + /// + 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()); + /// + /// An example of a client sending a wire request + /// + private class ExampleClient : IRpcDispatch + { + private readonly IWireTransfer _wire; + + public ExampleClient(IWireTransfer wire) + { + _wire = wire; + } + + TMessage IRpcDispatch.CallMethod(string method, IMessageLite request, + IBuilderLite response) + { + byte[] rawResponse = _wire.Execute(method, request.ToByteArray()); + response.MergeFrom(rawResponse); + return response.Build(); } - return resp.Build(); } - } - - /// - /// An example extraction of the wire protocol - /// - interface IWireTransfer - { - byte[] Execute(string method, byte[] message); - } - - /// - /// An example of a server responding to a wire request - /// - 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(); - } - } - - /// - /// An example of a client sending a wire request - /// - class ExampleClient : IRpcDispatch - { - readonly IWireTransfer _wire; - public ExampleClient(IWireTransfer wire) - { - _wire = wire; - } - - TMessage IRpcDispatch.CallMethod(string method, IMessageLite request, IBuilderLite response) - { - byte[] rawResponse = _wire.Execute(method, request.ToByteArray()); - response.MergeFrom(rawResponse); - return response.Build(); - } - } /// /// 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); diff --git a/src/ProtocolBuffers.Test/TestUtil.cs b/src/ProtocolBuffers.Test/TestUtil.cs index 63fb0817..45169840 100644 --- a/src/ProtocolBuffers.Test/TestUtil.cs +++ b/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; - } - } - - /// - /// Creates an unmodifiable ExtensionRegistry containing all the extensions - /// of TestAllExtensions. - /// - /// - internal static ExtensionRegistry CreateExtensionRegistry() { - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - RegisterAllExtensions(registry); - return registry.AsReadOnly(); - } - - /// - /// Registers all of the extensions in TestAllExtensions with the given - /// ExtensionRegistry. - /// - 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); - } - - /// - /// Helper to convert a String to ByteString. - /// - 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(); - } - - /// - /// Sets every field of the specified message to the values expected by - /// AssertAllFieldsSet. - /// - 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"); - } - - /// - /// Asserts that all fields of the specified message are set to the values - /// assigned by SetAllFields. - /// - 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); - } - - /// - /// Get a TestAllExtensions with all fields set as they would be by - /// SetAllExtensions(TestAllExtensions.Builder). - /// - 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(); - } - - /// - /// Sets every field of the specified builder to the values expected by - /// AssertAllExtensionsSet. - /// - 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)); - } - - /// - /// Helper to assert that sequences are equal. - /// - internal static void AssertEqual(IEnumerable first, IEnumerable second) { - using (IEnumerator 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)); - } - - /// - /// Modifies the repeated extensions of the given message to contain the values - /// expected by AssertRepeatedExtensionsModified. - /// - 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"); - } - - /// - /// Asserts that all repeated extensions are set to the values assigned by - /// SetAllExtensions follwed by ModifyRepeatedExtensions. - /// - 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)); - } - - /// - /// Set every field of the specified message to a unique value. - /// - 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); - } - - /// - /// Asserts that all the fields of the specified message are set to the values assigned - /// in SetPackedFields. - /// - 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; - - /// - /// 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++. - /// - 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; - } - } - } - - /// - /// Helper to construct a byte array from a bunch of bytes. - /// - 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; + } + } + + /// + /// Creates an unmodifiable ExtensionRegistry containing all the extensions + /// of TestAllExtensions. + /// + /// + internal static ExtensionRegistry CreateExtensionRegistry() + { + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + RegisterAllExtensions(registry); + return registry.AsReadOnly(); + } + + /// + /// Registers all of the extensions in TestAllExtensions with the given + /// ExtensionRegistry. + /// + 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); + } + + /// + /// Helper to convert a String to ByteString. + /// + 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(); + } + + /// + /// Sets every field of the specified message to the values expected by + /// AssertAllFieldsSet. + /// + 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"); + } + + /// + /// Asserts that all fields of the specified message are set to the values + /// assigned by SetAllFields. + /// + 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); + } + + /// + /// Get a TestAllExtensions with all fields set as they would be by + /// SetAllExtensions(TestAllExtensions.Builder). + /// + 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(); + } + + /// + /// Sets every field of the specified builder to the values expected by + /// AssertAllExtensionsSet. + /// + 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)); + } + + /// + /// Helper to assert that sequences are equal. + /// + internal static void AssertEqual(IEnumerable first, IEnumerable second) + { + using (IEnumerator 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)); + } + + /// + /// Modifies the repeated extensions of the given message to contain the values + /// expected by AssertRepeatedExtensionsModified. + /// + 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"); + } + + /// + /// Asserts that all repeated extensions are set to the values assigned by + /// SetAllExtensions follwed by ModifyRepeatedExtensions. + /// + 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)); + } + + /// + /// Set every field of the specified message to a unique value. + /// + 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); + } + + /// + /// Asserts that all the fields of the specified message are set to the values assigned + /// in SetPackedFields. + /// + 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; + + /// + /// 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++. + /// + 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; + } + } + } + + /// + /// Helper to construct a byte array from a bunch of bytes. + /// + 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. + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/TextFormatTest.cs b/src/ProtocolBuffers.Test/TextFormatTest.cs index 681c9d0c..76b89203 100644 --- a/src/ProtocolBuffers.Test/TextFormatTest.cs +++ b/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"); - - /// - /// 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. - /// - 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"; - - /// - /// Print TestAllTypes and compare with golden file. - /// - [Test] - public void PrintMessage() { - TestUtil.TestInMultipleCultures(() => { - string text = TextFormat.PrintToString(TestUtil.GetAllSet()); - Assert.AreEqual(AllFieldsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n")); - }); - } - - /// - /// Print TestAllExtensions and compare with golden file. - /// - [Test] - public void PrintExtensions() { - string text = TextFormat.PrintToString(TestUtil.GetAllExtensionsSet()); - - Assert.AreEqual(AllExtensionsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n")); - } - - /// - /// Test printing of unknown fields in a message. - /// - [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)); - } - - /// - /// 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. - /// - 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"); + + /// + /// 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. + /// + 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"; + + /// + /// Print TestAllTypes and compare with golden file. + /// + [Test] + public void PrintMessage() + { + TestUtil.TestInMultipleCultures(() => + { + string text = TextFormat.PrintToString(TestUtil.GetAllSet()); + Assert.AreEqual(AllFieldsSetText.Replace("\r\n", "\n"), + text.Replace("\r\n", "\n")); + }); + } + + /// + /// Print TestAllExtensions and compare with golden file. + /// + [Test] + public void PrintExtensions() + { + string text = TextFormat.PrintToString(TestUtil.GetAllExtensionsSet()); + + Assert.AreEqual(AllExtensionsSetText.Replace("\r\n", "\n"), text.Replace("\r\n", "\n")); + } + + /// + /// Test printing of unknown fields in a message. + /// + [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)); + } + + /// + /// 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. + /// + 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); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/UnknownFieldSetTest.cs b/src/ProtocolBuffers.Test/UnknownFieldSetTest.cs index 08de7fbf..bd3d950a 100644 --- a/src/ProtocolBuffers.Test/UnknownFieldSetTest.cs +++ b/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; - - /// - /// An empty message that has been parsed from allFieldsData. So, it has - /// unknown fields of every type. - /// - 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(name); - Assert.IsNotNull(field); - return unknownFields.FieldDictionary[field.FieldNumber]; - } - - /// - /// Constructs a protocol buffer which contains fields with all the same - /// numbers as allFieldsData except that each field is some other wire - /// type. - /// - private ByteString GetBizarroData() { - UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.CreateBuilder(); - - UnknownField varintField = UnknownField.CreateBuilder().AddVarint(1).Build(); - UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build(); - - foreach (KeyValuePair 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("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("optional_nested_enum"); - FieldDescriptor repeatedField = TestAllTypes.Descriptor.FindDescriptor("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); - } - - /// - /// Asserts that the given field sets are not equal and have different - /// hash codes. - /// - /// - /// 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. - /// - /// - /// - 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; + + /// + /// An empty message that has been parsed from allFieldsData. So, it has + /// unknown fields of every type. + /// + 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(name); + Assert.IsNotNull(field); + return unknownFields.FieldDictionary[field.FieldNumber]; + } + + /// + /// Constructs a protocol buffer which contains fields with all the same + /// numbers as allFieldsData except that each field is some other wire + /// type. + /// + private ByteString GetBizarroData() + { + UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.CreateBuilder(); + + UnknownField varintField = UnknownField.CreateBuilder().AddVarint(1).Build(); + UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build(); + + foreach (KeyValuePair 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("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("optional_nested_enum"); + FieldDescriptor repeatedField = + TestAllTypes.Descriptor.FindDescriptor("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); + } + + /// + /// Asserts that the given field sets are not equal and have different + /// hash codes. + /// + /// + /// 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. + /// + /// + /// + 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()); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/WireFormatTest.cs b/src/ProtocolBuffers.Test/WireFormatTest.cs index e61f4cca..f7ad864e 100644 --- a/src/ProtocolBuffers.Test/WireFormatTest.cs +++ b/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 { - - /// - /// Keeps the attributes on FieldType and the switch statement in WireFormat in sync. - /// - [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("my_int"), 1L) - .SetField(descriptor.FindDescriptor("my_string"), "foo") - .SetField(descriptor.FindDescriptor("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 + { + /// + /// Keeps the attributes on FieldType and the switch statement in WireFormat in sync. + /// + [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("my_int"), 1L) + .SetField(descriptor.FindDescriptor("my_string"), "foo") + .SetField(descriptor.FindDescriptor("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()); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/AbstractBuilder.cs b/src/ProtocolBuffers/AbstractBuilder.cs index 0d1279c7..ae5b3063 100644 --- a/src/ProtocolBuffers/AbstractBuilder.cs +++ b/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 { - /// - /// Implementation of the non-generic IMessage interface as far as possible. - /// - public abstract class AbstractBuilder : AbstractBuilderLite, IBuilder - where TMessage : AbstractMessage - where TBuilder : AbstractBuilder { - - #region Unimplemented members of IBuilder - public abstract UnknownFieldSet UnknownFields { get; set; } - public abstract IDictionary 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."); - } - - /// - /// 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 , - /// then 's value overwrites the value in this message. - /// For singular message fields, if the field is set in , - /// it is merged into the corresponding sub-message of this message using the same - /// merging rules. - /// For repeated fields, the elements in are concatenated - /// with the elements in this message. - /// - /// - /// - 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 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 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 +{ + /// + /// Implementation of the non-generic IMessage interface as far as possible. + /// + public abstract class AbstractBuilder : AbstractBuilderLite, + IBuilder + where TMessage : AbstractMessage + where TBuilder : AbstractBuilder + { + #region Unimplemented members of IBuilder + + public abstract UnknownFieldSet UnknownFields { get; set; } + public abstract IDictionary 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."); + } + + /// + /// 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 , + /// then 's value overwrites the value in this message. + /// For singular message fields, if the field is set in , + /// it is merged into the corresponding sub-message of this message using the same + /// merging rules. + /// For repeated fields, the elements in are concatenated + /// with the elements in this message. + /// + /// + /// + 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 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 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 + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/AbstractBuilderLite.cs b/src/ProtocolBuffers/AbstractBuilderLite.cs index c5fbf0ce..756f621e 100644 --- a/src/ProtocolBuffers/AbstractBuilderLite.cs +++ b/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 { - /// - /// Implementation of the non-generic IMessage interface as far as possible. - /// - public abstract class AbstractBuilderLite : IBuilderLite - where TMessage : AbstractMessageLite - where TBuilder : AbstractBuilderLite { - - 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 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 - /// - /// 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. - /// - 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 +{ + /// + /// Implementation of the non-generic IMessage interface as far as possible. + /// + public abstract class AbstractBuilderLite : IBuilderLite + where TMessage : AbstractMessageLite + where TBuilder : AbstractBuilderLite + { + 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 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 + + /// + /// 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. + /// + 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 + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/AbstractMessage.cs b/src/ProtocolBuffers/AbstractMessage.cs index 203b71a4..a4d98045 100644 --- a/src/ProtocolBuffers/AbstractMessage.cs +++ b/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 { - /// - /// Implementation of the non-generic IMessage interface as far as possible. - /// - public abstract class AbstractMessage : AbstractMessageLite, IMessage - where TMessage : AbstractMessage - where TBuilder : AbstractBuilder { - /// - /// The serialized size if it's already been computed, or null - /// if we haven't computed it yet. - /// - private int? memoizedSize = null; - - #region Unimplemented members of IMessage - public abstract MessageDescriptor DescriptorForType { get; } - public abstract IDictionary 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 - - /// - /// Returns true iff all required fields in the message and all embedded - /// messages are set. - /// - 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 entry in AllFields) { - FieldDescriptor field = entry.Key; - if (field.MappedType == MappedType.Message) { - if (field.IsRepeated) { - // We know it's an IList, 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); - } - - /// - /// Serializes the message and writes it to the given output stream. - /// This does not flush or close the stream. - /// - /// - /// 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). - /// - public override void WriteTo(CodedOutputStream output) { - foreach (KeyValuePair entry in AllFields) { - FieldDescriptor field = entry.Key; - if (field.IsRepeated) { - // We know it's an IList, 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); - } - } - - /// - /// Returns the number of bytes required to encode this message. - /// The result is only computed on the first call and memoized after that. - /// - public override int SerializedSize { - get { - if (memoizedSize != null) { - return memoizedSize.Value; - } - - int size = 0; - foreach (KeyValuePair 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; - } - } - - /// - /// 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. - /// - 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); - } - - /// - /// Returns the hash code value for this message. - /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one! - /// - 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 +{ + /// + /// Implementation of the non-generic IMessage interface as far as possible. + /// + public abstract class AbstractMessage : AbstractMessageLite, + IMessage + where TMessage : AbstractMessage + where TBuilder : AbstractBuilder + { + /// + /// The serialized size if it's already been computed, or null + /// if we haven't computed it yet. + /// + private int? memoizedSize = null; + + #region Unimplemented members of IMessage + + public abstract MessageDescriptor DescriptorForType { get; } + public abstract IDictionary 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 + + /// + /// Returns true iff all required fields in the message and all embedded + /// messages are set. + /// + 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 entry in AllFields) + { + FieldDescriptor field = entry.Key; + if (field.MappedType == MappedType.Message) + { + if (field.IsRepeated) + { + // We know it's an IList, 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); + } + + /// + /// Serializes the message and writes it to the given output stream. + /// This does not flush or close the stream. + /// + /// + /// 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). + /// + public override void WriteTo(CodedOutputStream output) + { + foreach (KeyValuePair entry in AllFields) + { + FieldDescriptor field = entry.Key; + if (field.IsRepeated) + { + // We know it's an IList, 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); + } + } + + /// + /// Returns the number of bytes required to encode this message. + /// The result is only computed on the first call and memoized after that. + /// + public override int SerializedSize + { + get + { + if (memoizedSize != null) + { + return memoizedSize.Value; + } + + int size = 0; + foreach (KeyValuePair 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; + } + } + + /// + /// 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. + /// + 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); + } + + /// + /// Returns the hash code value for this message. + /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one! + /// + 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 + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/AbstractMessageLite.cs b/src/ProtocolBuffers/AbstractMessageLite.cs index ee75f3dd..c98b2242 100644 --- a/src/ProtocolBuffers/AbstractMessageLite.cs +++ b/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 { - /// - /// Implementation of the non-generic IMessage interface as far as possible. - /// - public abstract class AbstractMessageLite : IMessageLite - where TMessage : AbstractMessageLite - where TBuilder : AbstractBuilderLite { - - - 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 Members - - /// - /// Serializes the message to a ByteString. This is a trivial wrapper - /// around WriteTo(CodedOutputStream). - /// - public ByteString ToByteString() { - ByteString.CodedBuilder output = new ByteString.CodedBuilder(SerializedSize); - WriteTo(output.CodedOutput); - return output.Build(); - } - - /// - /// Serializes the message to a byte array. This is a trivial wrapper - /// around WriteTo(CodedOutputStream). - /// - public byte[] ToByteArray() { - byte[] result = new byte[SerializedSize]; - CodedOutputStream output = CodedOutputStream.CreateInstance(result); - WriteTo(output); - output.CheckNoSpaceLeft(); - return result; - } - - /// - /// 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. - /// - /// - public void WriteTo(Stream output) { - CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output); - WriteTo(codedOutput); - codedOutput.Flush(); - } - - /// - /// 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. - /// - /// - 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 +{ + /// + /// Implementation of the non-generic IMessage interface as far as possible. + /// + public abstract class AbstractMessageLite : IMessageLite + where TMessage : AbstractMessageLite + where TBuilder : AbstractBuilderLite + { + 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 Members + + /// + /// Serializes the message to a ByteString. This is a trivial wrapper + /// around WriteTo(CodedOutputStream). + /// + public ByteString ToByteString() + { + ByteString.CodedBuilder output = new ByteString.CodedBuilder(SerializedSize); + WriteTo(output.CodedOutput); + return output.Build(); + } + + /// + /// Serializes the message to a byte array. This is a trivial wrapper + /// around WriteTo(CodedOutputStream). + /// + public byte[] ToByteArray() + { + byte[] result = new byte[SerializedSize]; + CodedOutputStream output = CodedOutputStream.CreateInstance(result); + WriteTo(output); + output.CheckNoSpaceLeft(); + return result; + } + + /// + /// 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. + /// + /// + public void WriteTo(Stream output) + { + CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output); + WriteTo(codedOutput); + codedOutput.Flush(); + } + + /// + /// 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. + /// + /// + 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 + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/ByteString.cs b/src/ProtocolBuffers/ByteString.cs index 5add171e..2cce287a 100644 --- a/src/ProtocolBuffers/ByteString.cs +++ b/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 { - /// - /// Immutable array of bytes. - /// TODO(jonskeet): Implement the common collection interfaces? - /// - public sealed class ByteString : IEnumerable, IEquatable { - - private static readonly ByteString empty = new ByteString(new byte[0]); - - private readonly byte[] bytes; - - /// - /// Constructs a new ByteString from the given byte array. The array is - /// *not* copied, and must not be modified after this constructor is called. - /// - private ByteString(byte[] bytes) { - this.bytes = bytes; - } - - /// - /// Returns an empty ByteString. - /// - public static ByteString Empty { - get { return empty; } - } - - /// - /// Returns the length of this ByteString in bytes. - /// - public int Length { - get { return bytes.Length; } - } - - public bool IsEmpty { - get { return Length == 0; } - } - - public byte[] ToByteArray() { - return (byte[])bytes.Clone(); - } - - /// - /// Constructs a ByteString from the Base64 Encoded String. - /// - public static ByteString FromBase64(string bytes) { - return new ByteString(System.Convert.FromBase64String(bytes)); - } - - /// - /// 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. - /// - public static ByteString CopyFrom(byte[] bytes) { - return new ByteString((byte[]) bytes.Clone()); - } - - /// - /// Constructs a ByteString from a portion of a byte array. - /// - 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); - } - - /// - /// Creates a new ByteString by encoding the specified text with - /// the given encoding. - /// - public static ByteString CopyFrom(string text, Encoding encoding) { - return new ByteString(encoding.GetBytes(text)); - } - - /// - /// Creates a new ByteString by encoding the specified text in UTF-8. - /// - public static ByteString CopyFromUtf8(string text) { - return CopyFrom(text, Encoding.UTF8); - } - - /// - /// Retuns the byte at the given index. - /// - 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 GetEnumerator() { - return ((IEnumerable) bytes).GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() { - return GetEnumerator(); - } - - /// - /// Creates a CodedInputStream from this ByteString's data. - /// - 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; - } - - /// - /// 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. - /// - 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 +{ + /// + /// Immutable array of bytes. + /// TODO(jonskeet): Implement the common collection interfaces? + /// + public sealed class ByteString : IEnumerable, IEquatable + { + private static readonly ByteString empty = new ByteString(new byte[0]); + + private readonly byte[] bytes; + + /// + /// Constructs a new ByteString from the given byte array. The array is + /// *not* copied, and must not be modified after this constructor is called. + /// + private ByteString(byte[] bytes) + { + this.bytes = bytes; + } + + /// + /// Returns an empty ByteString. + /// + public static ByteString Empty + { + get { return empty; } + } + + /// + /// Returns the length of this ByteString in bytes. + /// + public int Length + { + get { return bytes.Length; } + } + + public bool IsEmpty + { + get { return Length == 0; } + } + + public byte[] ToByteArray() + { + return (byte[]) bytes.Clone(); + } + + /// + /// Constructs a ByteString from the Base64 Encoded String. + /// + public static ByteString FromBase64(string bytes) + { + return new ByteString(System.Convert.FromBase64String(bytes)); + } + + /// + /// 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. + /// + public static ByteString CopyFrom(byte[] bytes) + { + return new ByteString((byte[]) bytes.Clone()); + } + + /// + /// Constructs a ByteString from a portion of a byte array. + /// + 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); + } + + /// + /// Creates a new ByteString by encoding the specified text with + /// the given encoding. + /// + public static ByteString CopyFrom(string text, Encoding encoding) + { + return new ByteString(encoding.GetBytes(text)); + } + + /// + /// Creates a new ByteString by encoding the specified text in UTF-8. + /// + public static ByteString CopyFromUtf8(string text) + { + return CopyFrom(text, Encoding.UTF8); + } + + /// + /// Retuns the byte at the given index. + /// + 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 GetEnumerator() + { + return ((IEnumerable) bytes).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// Creates a CodedInputStream from this ByteString's data. + /// + 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; + } + + /// + /// 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. + /// + 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; } + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/CodedInputStream.cs b/src/ProtocolBuffers/CodedInputStream.cs index 8b4c860b..225cf4da 100644 --- a/src/ProtocolBuffers/CodedInputStream.cs +++ b/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 { - - /// - /// Readings and decodes protocol message fields. - /// - /// - /// 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. - /// - 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; - - /// - /// 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. - /// - private int totalBytesRetired = 0; - - /// - /// The absolute position of the end of the current message. - /// - private int currentLimit = int.MaxValue; - - /// - /// - /// - private int recursionDepth = 0; - private int recursionLimit = DefaultRecursionLimit; - - /// - /// - /// - private int sizeLimit = DefaultSizeLimit; - - #region Construction - /// - /// Creates a new CodedInputStream reading data from the given - /// stream. - /// - public static CodedInputStream CreateInstance(Stream input) { - return new CodedInputStream(input); - } - - /// - /// Creates a new CodedInputStream reading data from the given - /// byte array. - /// - public static CodedInputStream CreateInstance(byte[] buf) { - return new CodedInputStream(buf, 0, buf.Length); - } - - /// - /// Creates a new CodedInputStream that reads from the given - /// byte array slice. - /// - 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 - /// - /// 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. - /// - /// The last - /// tag read was not the one specified - [CLSCompliant(false)] - public void CheckLastTagWas(uint value) { - if (lastTag != value) { - throw InvalidProtocolBufferException.InvalidEndTag(); - } - } - #endregion - - #region Reading of tags etc - /// - /// 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. - /// - [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; - } - - /// - /// Read a double field from the stream. - /// - public double ReadDouble() { -#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35 - byte[] bytes = ReadRawBytes(8); - return BitConverter.ToDouble(bytes, 0); -#else - return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64()); -#endif - } - - /// - /// Read a float field from the stream. - /// - public float ReadFloat() { - // TODO(jonskeet): Test this on different endiannesses - uint raw = ReadRawLittleEndian32(); - byte[] rawBytes = BitConverter.GetBytes(raw); - return BitConverter.ToSingle(rawBytes, 0); - } - - /// - /// Read a uint64 field from the stream. - /// - [CLSCompliant(false)] - public ulong ReadUInt64() { - return ReadRawVarint64(); - } - - /// - /// Read an int64 field from the stream. - /// - public long ReadInt64() { - return (long) ReadRawVarint64(); - } - - /// - /// Read an int32 field from the stream. - /// - public int ReadInt32() { - return (int) ReadRawVarint32(); - } - - /// - /// Read a fixed64 field from the stream. - /// - [CLSCompliant(false)] - public ulong ReadFixed64() { - return ReadRawLittleEndian64(); - } - - /// - /// Read a fixed32 field from the stream. - /// - [CLSCompliant(false)] - public uint ReadFixed32() { - return ReadRawLittleEndian32(); - } - - /// - /// Read a bool field from the stream. - /// - public bool ReadBool() { - return ReadRawVarint32() != 0; - } - - /// - /// Reads a string field from the stream. - /// - 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); - } - - /// - /// Reads a group field value from the stream. - /// - 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; - } - - /// - /// Reads a group field value from the stream and merges it into the given - /// UnknownFieldSet. - /// - [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; - } - - /// - /// Reads an embedded message field value from the stream. - /// - 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); - } - - /// - /// Reads a bytes field value from the stream. - /// - 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)); - } - } - - /// - /// Reads a uint32 field value from the stream. - /// - [CLSCompliant(false)] - public uint ReadUInt32() { - return ReadRawVarint32(); - } - - /// - /// Reads an enum field value from the stream. The caller is responsible - /// for converting the numeric value to an actual enum. - /// - public int ReadEnum() { - return (int) ReadRawVarint32(); - } - - /// - /// Reads an sfixed32 field value from the stream. - /// - public int ReadSFixed32() { - return (int) ReadRawLittleEndian32(); - } - - /// - /// Reads an sfixed64 field value from the stream. - /// - public long ReadSFixed64() { - return (long) ReadRawLittleEndian64(); - } - - /// - /// Reads an sint32 field value from the stream. - /// - public int ReadSInt32() { - return DecodeZigZag32(ReadRawVarint32()); - } - - /// - /// Reads an sint64 field value from the stream. - /// - public long ReadSInt64() { - return DecodeZigZag64(ReadRawVarint64()); - } - - /// - /// Reads a field of any primitive type. Enums, groups and embedded - /// messages are not handled by this method. - /// - 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 - - /// - /// Same code as ReadRawVarint32, but read each byte individually, checking for - /// buffer overflow. - /// - 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; - } - - /// - /// 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. - /// - [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; - } - - /// - /// 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. - /// - /// - /// - [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(); - } - - /// - /// Read a raw varint from the stream. - /// - [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(); - } - - /// - /// Read a 32-bit little-endian integer from the stream. - /// - [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); - } - - /// - /// Read a 64-bit little-endian integer from the stream. - /// - [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 - - /// - /// Decode a 32-bit value with ZigZag encoding. - /// - /// - /// 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.) - /// - [CLSCompliant(false)] - public static int DecodeZigZag32(uint n) { - return (int)(n >> 1) ^ -(int)(n & 1); - } - - /// - /// Decode a 32-bit value with ZigZag encoding. - /// - /// - /// 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.) - /// - [CLSCompliant(false)] - public static long DecodeZigZag64(ulong n) { - return (long)(n >> 1) ^ -(long)(n & 1); - } - - /// - /// Set the maximum message recursion depth. - /// - /// - /// In order to prevent malicious - /// messages from causing stack overflows, CodedInputStream limits - /// how deeply messages may be nested. The default limit is 64. - /// - public int SetRecursionLimit(int limit) { - if (limit < 0) { - throw new ArgumentOutOfRangeException("Recursion limit cannot be negative: " + limit); - } - int oldLimit = recursionLimit; - recursionLimit = limit; - return oldLimit; - } - - /// - /// Set the maximum message size. - /// - /// - /// 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. - /// - 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 - /// - /// Resets the current size counter to zero (see SetSizeLimit). - /// - public void ResetSizeCounter() { - totalBytesRetired = 0; - } - - /// - /// Sets currentLimit to (current position) + byteLimit. This is called - /// when descending into a length-delimited embedded message. The previous - /// limit is returned. - /// - /// The old limit. - 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; - } - } - - /// - /// Discards the current limit, returning the previous limit. - /// - public void PopLimit(int oldLimit) { - currentLimit = oldLimit; - RecomputeBufferSizeAfterLimit(); - } - - /// - /// Returns whether or not all the data before the limit has been read. - /// - /// - public bool ReachedLimit { - get { - if (currentLimit == int.MaxValue) { - return false; - } - int currentAbsolutePosition = totalBytesRetired + bufferPos; - return currentAbsolutePosition >= currentLimit; - } - } - - /// - /// 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. - /// - public bool IsAtEnd { - get { - return bufferPos == bufferSize && !RefillBuffer(false); - } - } - - /// - /// Called when buffer is empty to read more bytes from the - /// input. If 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 is false, - /// RefillBuffer() returns false if no more bytes were available. - /// - /// - /// - 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; - } - } - - /// - /// Read one byte from the input. - /// - /// - /// the end of the stream or the current limit was reached - /// - public byte ReadRawByte() { - if (bufferPos == bufferSize) { - RefillBuffer(true); - } - return buffer[bufferPos++]; - } - - /// - /// Read a fixed size of bytes from the input. - /// - /// - /// the end of the stream or the current limit was reached - /// - 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 chunks = new List(); - - 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; - } - } - - /// - /// Reads and discards a single field, given its tag value. - /// - /// false if the tag is an end-group tag, in which case - /// nothing is skipped. Otherwise, returns true. - [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(); - } - } - - /// - /// Reads and discards an entire message. This will read either until EOF - /// or until an endgroup tag, whichever comes first. - /// - public void SkipMessage() { - while (true) { - uint tag = ReadTag(); - if (tag == 0 || !SkipField(tag)) { - return; - } - } - } - - /// - /// Reads and discards bytes. - /// - /// the end of the stream - /// or the current limit was reached - 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; - } - } - } - - /// - /// Abstraction of skipping to cope with streams which can't really skip. - /// - 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 +{ + /// + /// Readings and decodes protocol message fields. + /// + /// + /// 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. + /// + 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; + + /// + /// 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. + /// + private int totalBytesRetired = 0; + + /// + /// The absolute position of the end of the current message. + /// + private int currentLimit = int.MaxValue; + + /// + /// + /// + private int recursionDepth = 0; + + private int recursionLimit = DefaultRecursionLimit; + + /// + /// + /// + private int sizeLimit = DefaultSizeLimit; + + #region Construction + + /// + /// Creates a new CodedInputStream reading data from the given + /// stream. + /// + public static CodedInputStream CreateInstance(Stream input) + { + return new CodedInputStream(input); + } + + /// + /// Creates a new CodedInputStream reading data from the given + /// byte array. + /// + public static CodedInputStream CreateInstance(byte[] buf) + { + return new CodedInputStream(buf, 0, buf.Length); + } + + /// + /// Creates a new CodedInputStream that reads from the given + /// byte array slice. + /// + 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 + + /// + /// 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. + /// + /// The last + /// tag read was not the one specified + [CLSCompliant(false)] + public void CheckLastTagWas(uint value) + { + if (lastTag != value) + { + throw InvalidProtocolBufferException.InvalidEndTag(); + } + } + + #endregion + + #region Reading of tags etc + + /// + /// 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. + /// + [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; + } + + /// + /// Read a double field from the stream. + /// + public double ReadDouble() + { +#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35 + byte[] bytes = ReadRawBytes(8); + return BitConverter.ToDouble(bytes, 0); +#else + return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64()); +#endif + } + + /// + /// Read a float field from the stream. + /// + public float ReadFloat() + { + // TODO(jonskeet): Test this on different endiannesses + uint raw = ReadRawLittleEndian32(); + byte[] rawBytes = BitConverter.GetBytes(raw); + return BitConverter.ToSingle(rawBytes, 0); + } + + /// + /// Read a uint64 field from the stream. + /// + [CLSCompliant(false)] + public ulong ReadUInt64() + { + return ReadRawVarint64(); + } + + /// + /// Read an int64 field from the stream. + /// + public long ReadInt64() + { + return (long) ReadRawVarint64(); + } + + /// + /// Read an int32 field from the stream. + /// + public int ReadInt32() + { + return (int) ReadRawVarint32(); + } + + /// + /// Read a fixed64 field from the stream. + /// + [CLSCompliant(false)] + public ulong ReadFixed64() + { + return ReadRawLittleEndian64(); + } + + /// + /// Read a fixed32 field from the stream. + /// + [CLSCompliant(false)] + public uint ReadFixed32() + { + return ReadRawLittleEndian32(); + } + + /// + /// Read a bool field from the stream. + /// + public bool ReadBool() + { + return ReadRawVarint32() != 0; + } + + /// + /// Reads a string field from the stream. + /// + 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); + } + + /// + /// Reads a group field value from the stream. + /// + 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; + } + + /// + /// Reads a group field value from the stream and merges it into the given + /// UnknownFieldSet. + /// + [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; + } + + /// + /// Reads an embedded message field value from the stream. + /// + 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); + } + + /// + /// Reads a bytes field value from the stream. + /// + 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)); + } + } + + /// + /// Reads a uint32 field value from the stream. + /// + [CLSCompliant(false)] + public uint ReadUInt32() + { + return ReadRawVarint32(); + } + + /// + /// Reads an enum field value from the stream. The caller is responsible + /// for converting the numeric value to an actual enum. + /// + public int ReadEnum() + { + return (int) ReadRawVarint32(); + } + + /// + /// Reads an sfixed32 field value from the stream. + /// + public int ReadSFixed32() + { + return (int) ReadRawLittleEndian32(); + } + + /// + /// Reads an sfixed64 field value from the stream. + /// + public long ReadSFixed64() + { + return (long) ReadRawLittleEndian64(); + } + + /// + /// Reads an sint32 field value from the stream. + /// + public int ReadSInt32() + { + return DecodeZigZag32(ReadRawVarint32()); + } + + /// + /// Reads an sint64 field value from the stream. + /// + public long ReadSInt64() + { + return DecodeZigZag64(ReadRawVarint64()); + } + + /// + /// Reads a field of any primitive type. Enums, groups and embedded + /// messages are not handled by this method. + /// + 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 + + /// + /// Same code as ReadRawVarint32, but read each byte individually, checking for + /// buffer overflow. + /// + 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; + } + + /// + /// 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. + /// + [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; + } + + /// + /// 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. + /// + /// + /// + [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(); + } + + /// + /// Read a raw varint from the stream. + /// + [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(); + } + + /// + /// Read a 32-bit little-endian integer from the stream. + /// + [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); + } + + /// + /// Read a 64-bit little-endian integer from the stream. + /// + [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 + + /// + /// Decode a 32-bit value with ZigZag encoding. + /// + /// + /// 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.) + /// + [CLSCompliant(false)] + public static int DecodeZigZag32(uint n) + { + return (int) (n >> 1) ^ -(int) (n & 1); + } + + /// + /// Decode a 32-bit value with ZigZag encoding. + /// + /// + /// 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.) + /// + [CLSCompliant(false)] + public static long DecodeZigZag64(ulong n) + { + return (long) (n >> 1) ^ -(long) (n & 1); + } + + /// + /// Set the maximum message recursion depth. + /// + /// + /// In order to prevent malicious + /// messages from causing stack overflows, CodedInputStream limits + /// how deeply messages may be nested. The default limit is 64. + /// + public int SetRecursionLimit(int limit) + { + if (limit < 0) + { + throw new ArgumentOutOfRangeException("Recursion limit cannot be negative: " + limit); + } + int oldLimit = recursionLimit; + recursionLimit = limit; + return oldLimit; + } + + /// + /// Set the maximum message size. + /// + /// + /// 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. + /// + 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 + + /// + /// Resets the current size counter to zero (see SetSizeLimit). + /// + public void ResetSizeCounter() + { + totalBytesRetired = 0; + } + + /// + /// Sets currentLimit to (current position) + byteLimit. This is called + /// when descending into a length-delimited embedded message. The previous + /// limit is returned. + /// + /// The old limit. + 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; + } + } + + /// + /// Discards the current limit, returning the previous limit. + /// + public void PopLimit(int oldLimit) + { + currentLimit = oldLimit; + RecomputeBufferSizeAfterLimit(); + } + + /// + /// Returns whether or not all the data before the limit has been read. + /// + /// + public bool ReachedLimit + { + get + { + if (currentLimit == int.MaxValue) + { + return false; + } + int currentAbsolutePosition = totalBytesRetired + bufferPos; + return currentAbsolutePosition >= currentLimit; + } + } + + /// + /// 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. + /// + public bool IsAtEnd + { + get { return bufferPos == bufferSize && !RefillBuffer(false); } + } + + /// + /// Called when buffer is empty to read more bytes from the + /// input. If 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 is false, + /// RefillBuffer() returns false if no more bytes were available. + /// + /// + /// + 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; + } + } + + /// + /// Read one byte from the input. + /// + /// + /// the end of the stream or the current limit was reached + /// + public byte ReadRawByte() + { + if (bufferPos == bufferSize) + { + RefillBuffer(true); + } + return buffer[bufferPos++]; + } + + /// + /// Read a fixed size of bytes from the input. + /// + /// + /// the end of the stream or the current limit was reached + /// + 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 chunks = new List(); + + 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; + } + } + + /// + /// Reads and discards a single field, given its tag value. + /// + /// false if the tag is an end-group tag, in which case + /// nothing is skipped. Otherwise, returns true. + [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(); + } + } + + /// + /// Reads and discards an entire message. This will read either until EOF + /// or until an endgroup tag, whichever comes first. + /// + public void SkipMessage() + { + while (true) + { + uint tag = ReadTag(); + if (tag == 0 || !SkipField(tag)) + { + return; + } + } + } + + /// + /// Reads and discards bytes. + /// + /// the end of the stream + /// or the current limit was reached + 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; + } + } + } + + /// + /// Abstraction of skipping to cope with streams which can't really skip. + /// + 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 + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/CodedOutputStream.cs b/src/ProtocolBuffers/CodedOutputStream.cs index 264ca6ef..f905b357 100644 --- a/src/ProtocolBuffers/CodedOutputStream.cs +++ b/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 { - - /// - /// Encodes and writes protocol message fields. - /// - /// - /// 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.) - /// - public sealed class CodedOutputStream { - /// - /// The buffer size used by CreateInstance(Stream). - /// - 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; - } - - /// - /// Creates a new CodedOutputStream which write to the given stream. - /// - public static CodedOutputStream CreateInstance(Stream output) { - return CreateInstance(output, DefaultBufferSize); - } - - /// - /// Creates a new CodedOutputStream which write to the given stream and uses - /// the specified buffer size. - /// - public static CodedOutputStream CreateInstance(Stream output, int bufferSize) { - return new CodedOutputStream(output, new byte[bufferSize]); - } - - /// - /// 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. - /// - public static CodedOutputStream CreateInstance(byte[] flatArray) { - return CreateInstance(flatArray, 0, flatArray.Length); - } - - /// - /// 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. - /// - public static CodedOutputStream CreateInstance(byte[] flatArray, int offset, int length) { - return new CodedOutputStream(flatArray, offset, length); - } - #endregion - - #region Writing of tags etc - /// - /// Writes a double field value, including tag, to the stream. - /// - public void WriteDouble(int fieldNumber, double value) { - WriteTag(fieldNumber, WireFormat.WireType.Fixed64); - WriteDoubleNoTag(value); - } - - /// - /// Writes a float field value, including tag, to the stream. - /// - public void WriteFloat(int fieldNumber, float value) { - WriteTag(fieldNumber, WireFormat.WireType.Fixed32); - WriteFloatNoTag(value); - } - - /// - /// Writes a uint64 field value, including tag, to the stream. - /// - [CLSCompliant(false)] - public void WriteUInt64(int fieldNumber, ulong value) { - WriteTag(fieldNumber, WireFormat.WireType.Varint); - WriteRawVarint64(value); - } - - /// - /// Writes an int64 field value, including tag, to the stream. - /// - public void WriteInt64(int fieldNumber, long value) { - WriteTag(fieldNumber, WireFormat.WireType.Varint); - WriteRawVarint64((ulong)value); - } - - /// - /// Writes an int32 field value, including tag, to the stream. - /// - 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); - } - } - - /// - /// Writes a fixed64 field value, including tag, to the stream. - /// - [CLSCompliant(false)] - public void WriteFixed64(int fieldNumber, ulong value) { - WriteTag(fieldNumber, WireFormat.WireType.Fixed64); - WriteRawLittleEndian64(value); - } - - /// - /// Writes a fixed32 field value, including tag, to the stream. - /// - [CLSCompliant(false)] - public void WriteFixed32(int fieldNumber, uint value) { - WriteTag(fieldNumber, WireFormat.WireType.Fixed32); - WriteRawLittleEndian32(value); - } - - /// - /// Writes a bool field value, including tag, to the stream. - /// - public void WriteBool(int fieldNumber, bool value) { - WriteTag(fieldNumber, WireFormat.WireType.Varint); - WriteRawByte(value ? (byte)1 : (byte)0); - } - - /// - /// Writes a string field value, including tag, to the stream. - /// - 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); - } - } - - /// - /// Writes a group field value, including tag, to the stream. - /// - 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 - /// - /// Writes a double field value, including tag, to the stream. - /// - 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 - } - - /// - /// Writes a float field value, without a tag, to the stream. - /// - 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); - } - - /// - /// Writes a uint64 field value, without a tag, to the stream. - /// - [CLSCompliant(false)] - public void WriteUInt64NoTag(ulong value) { - WriteRawVarint64(value); - } - - /// - /// Writes an int64 field value, without a tag, to the stream. - /// - public void WriteInt64NoTag(long value) { - WriteRawVarint64((ulong)value); - } - - /// - /// Writes an int32 field value, without a tag, to the stream. - /// - public void WriteInt32NoTag(int value) { - if (value >= 0) { - WriteRawVarint32((uint)value); - } else { - // Must sign-extend. - WriteRawVarint64((ulong)value); - } - } - - /// - /// Writes a fixed64 field value, without a tag, to the stream. - /// - [CLSCompliant(false)] - public void WriteFixed64NoTag(ulong value) { - WriteRawLittleEndian64(value); - } - - /// - /// Writes a fixed32 field value, without a tag, to the stream. - /// - [CLSCompliant(false)] - public void WriteFixed32NoTag(uint value) { - WriteRawLittleEndian32(value); - } - - /// - /// Writes a bool field value, without a tag, to the stream. - /// - public void WriteBoolNoTag(bool value) { - WriteRawByte(value ? (byte)1 : (byte)0); - } - - /// - /// Writes a string field value, without a tag, to the stream. - /// - 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); - } - } - - /// - /// Writes a group field value, without a tag, to the stream. - /// - 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 - /// - /// Encodes and writes a tag. - /// - [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; - } - } - } - - /// - /// 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. - /// - [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); - } - - /// - /// Writes out an array of bytes. - /// - public void WriteRawBytes(byte[] value) { - WriteRawBytes(value, 0, value.Length); - } - - /// - /// Writes out part of an array of bytes. - /// - 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; - - /// - /// Compute the number of bytes that would be needed to encode a - /// double field, including the tag. - /// - public static int ComputeDoubleSize(int fieldNumber, double value) { - return ComputeTagSize(fieldNumber) + LittleEndian64Size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// float field, including the tag. - /// - public static int ComputeFloatSize(int fieldNumber, float value) { - return ComputeTagSize(fieldNumber) + LittleEndian32Size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// uint64 field, including the tag. - /// - [CLSCompliant(false)] - public static int ComputeUInt64Size(int fieldNumber, ulong value) { - return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(value); - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// int64 field, including the tag. - /// - public static int ComputeInt64Size(int fieldNumber, long value) { - return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size((ulong)value); - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// int32 field, including the tag. - /// - 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; - } - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// fixed64 field, including the tag. - /// - [CLSCompliant(false)] - public static int ComputeFixed64Size(int fieldNumber, ulong value) { - return ComputeTagSize(fieldNumber) + LittleEndian64Size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// fixed32 field, including the tag. - /// - [CLSCompliant(false)] - public static int ComputeFixed32Size(int fieldNumber, uint value) { - return ComputeTagSize(fieldNumber) + LittleEndian32Size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// bool field, including the tag. - /// - public static int ComputeBoolSize(int fieldNumber, bool value) { - return ComputeTagSize(fieldNumber) + 1; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// string field, including the tag. - /// - public static int ComputeStringSize(int fieldNumber, String value) { - int byteArraySize = Encoding.UTF8.GetByteCount(value); - return ComputeTagSize(fieldNumber) + - ComputeRawVarint32Size((uint)byteArraySize) + - byteArraySize; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// group field, including the tag. - /// - public static int ComputeGroupSize(int fieldNumber, IMessageLite value) { - return ComputeTagSize(fieldNumber) * 2 + value.SerializedSize; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// group field represented by an UnknownFieldSet, including the tag. - /// - [Obsolete] - public static int ComputeUnknownGroupSize(int fieldNumber, - IMessageLite value) { - return ComputeTagSize(fieldNumber) * 2 + value.SerializedSize; - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// embedded message field, including the tag. - /// - public static int ComputeMessageSize(int fieldNumber, IMessageLite value) { - int size = value.SerializedSize; - return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint)size) + size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// bytes field, including the tag. - /// - public static int ComputeBytesSize(int fieldNumber, ByteString value) { - return ComputeTagSize(fieldNumber) + - ComputeRawVarint32Size((uint)value.Length) + - value.Length; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// uint32 field, including the tag. - /// - [CLSCompliant(false)] - public static int ComputeUInt32Size(int fieldNumber, uint value) { - return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(value); - } - - /// - /// 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. - /// - public static int ComputeEnumSize(int fieldNumber, int value) { - return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint)value); - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// sfixed32 field, including the tag. - /// - public static int ComputeSFixed32Size(int fieldNumber, int value) { - return ComputeTagSize(fieldNumber) + LittleEndian32Size; - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// sfixed64 field, including the tag. - /// - public static int ComputeSFixed64Size(int fieldNumber, long value) { - return ComputeTagSize(fieldNumber) + LittleEndian64Size; - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// sint32 field, including the tag. - /// - public static int ComputeSInt32Size(int fieldNumber, int value) { - return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(EncodeZigZag32(value)); - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// sint64 field, including the tag. - /// - public static int ComputeSInt64Size(int fieldNumber, long value) { - return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(EncodeZigZag64(value)); - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// double field, including the tag. - /// - public static int ComputeDoubleSizeNoTag(double value) { - return LittleEndian64Size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// float field, including the tag. - /// - public static int ComputeFloatSizeNoTag(float value) { - return LittleEndian32Size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// uint64 field, including the tag. - /// - [CLSCompliant(false)] - public static int ComputeUInt64SizeNoTag(ulong value) { - return ComputeRawVarint64Size(value); - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// int64 field, including the tag. - /// - public static int ComputeInt64SizeNoTag(long value) { - return ComputeRawVarint64Size((ulong)value); - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// int32 field, including the tag. - /// - public static int ComputeInt32SizeNoTag(int value) { - if (value >= 0) { - return ComputeRawVarint32Size((uint)value); - } else { - // Must sign-extend. - return 10; - } - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// fixed64 field, including the tag. - /// - [CLSCompliant(false)] - public static int ComputeFixed64SizeNoTag(ulong value) { - return LittleEndian64Size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// fixed32 field, including the tag. - /// - [CLSCompliant(false)] - public static int ComputeFixed32SizeNoTag(uint value) { - return LittleEndian32Size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// bool field, including the tag. - /// - public static int ComputeBoolSizeNoTag(bool value) { - return 1; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// string field, including the tag. - /// - public static int ComputeStringSizeNoTag(String value) { - int byteArraySize = Encoding.UTF8.GetByteCount(value); - return ComputeRawVarint32Size((uint)byteArraySize) + - byteArraySize; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// group field, including the tag. - /// - public static int ComputeGroupSizeNoTag(IMessageLite value) { - return value.SerializedSize; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// group field represented by an UnknownFieldSet, including the tag. - /// - [Obsolete] - public static int ComputeUnknownGroupSizeNoTag(IMessageLite value) { - return value.SerializedSize; - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// embedded message field, including the tag. - /// - public static int ComputeMessageSizeNoTag(IMessageLite value) { - int size = value.SerializedSize; - return ComputeRawVarint32Size((uint)size) + size; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// bytes field, including the tag. - /// - public static int ComputeBytesSizeNoTag(ByteString value) { - return ComputeRawVarint32Size((uint)value.Length) + - value.Length; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// uint32 field, including the tag. - /// - [CLSCompliant(false)] - public static int ComputeUInt32SizeNoTag(uint value) { - return ComputeRawVarint32Size(value); - } - - /// - /// 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. - /// - public static int ComputeEnumSizeNoTag(int value) { - return ComputeRawVarint32Size((uint)value); - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// sfixed32 field, including the tag. - /// - public static int ComputeSFixed32SizeNoTag(int value) { - return LittleEndian32Size; - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// sfixed64 field, including the tag. - /// - public static int ComputeSFixed64SizeNoTag(long value) { - return LittleEndian64Size; - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// sint32 field, including the tag. - /// - public static int ComputeSInt32SizeNoTag(int value) { - return ComputeRawVarint32Size(EncodeZigZag32(value)); - } - - /// - /// Compute the number of bytes that would be needed to encode an - /// sint64 field, including the tag. - /// - 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. - */ - /// - /// 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. - /// - 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); - } - - /// - /// 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. - /// - 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); - } - - /// - /// Compute the number of bytes that would be needed to encode a varint. - /// - [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; - } - - /// - /// Compute the number of bytes that would be needed to encode a varint. - /// - [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; - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// field of arbitrary type, including the tag, to the stream. - /// - 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); - } - } - - /// - /// Compute the number of bytes that would be needed to encode a - /// field of arbitrary type, excluding the tag, to the stream. - /// - 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); - } - } - - /// - /// Compute the number of bytes that would be needed to encode a tag. - /// - public static int ComputeTagSize(int fieldNumber) { - return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0)); - } - #endregion - - /// - /// Encode a 32-bit value with ZigZag encoding. - /// - /// - /// 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.) - /// - [CLSCompliant(false)] - public static uint EncodeZigZag32(int n) { - // Note: the right-shift must be arithmetic - return (uint)((n << 1) ^ (n >> 31)); - } - - /// - /// Encode a 64-bit value with ZigZag encoding. - /// - /// - /// 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.) - /// - [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; - } - - /// - /// Indicates that a CodedOutputStream wrapping a flat byte array - /// ran out of space. - /// - 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(); - } - } - - /// - /// 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. - /// - public void CheckNoSpaceLeft() { - if (SpaceLeft != 0) { - throw new InvalidOperationException("Did not write as much data as expected."); - } - } - - /// - /// If writing to a flat array, returns the space left in the array. Otherwise, - /// throws an InvalidOperationException. - /// - 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 +{ + /// + /// Encodes and writes protocol message fields. + /// + /// + /// 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.) + /// + public sealed class CodedOutputStream + { + /// + /// The buffer size used by CreateInstance(Stream). + /// + 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; + } + + /// + /// Creates a new CodedOutputStream which write to the given stream. + /// + public static CodedOutputStream CreateInstance(Stream output) + { + return CreateInstance(output, DefaultBufferSize); + } + + /// + /// Creates a new CodedOutputStream which write to the given stream and uses + /// the specified buffer size. + /// + public static CodedOutputStream CreateInstance(Stream output, int bufferSize) + { + return new CodedOutputStream(output, new byte[bufferSize]); + } + + /// + /// 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. + /// + public static CodedOutputStream CreateInstance(byte[] flatArray) + { + return CreateInstance(flatArray, 0, flatArray.Length); + } + + /// + /// 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. + /// + public static CodedOutputStream CreateInstance(byte[] flatArray, int offset, int length) + { + return new CodedOutputStream(flatArray, offset, length); + } + + #endregion + + #region Writing of tags etc + + /// + /// Writes a double field value, including tag, to the stream. + /// + public void WriteDouble(int fieldNumber, double value) + { + WriteTag(fieldNumber, WireFormat.WireType.Fixed64); + WriteDoubleNoTag(value); + } + + /// + /// Writes a float field value, including tag, to the stream. + /// + public void WriteFloat(int fieldNumber, float value) + { + WriteTag(fieldNumber, WireFormat.WireType.Fixed32); + WriteFloatNoTag(value); + } + + /// + /// Writes a uint64 field value, including tag, to the stream. + /// + [CLSCompliant(false)] + public void WriteUInt64(int fieldNumber, ulong value) + { + WriteTag(fieldNumber, WireFormat.WireType.Varint); + WriteRawVarint64(value); + } + + /// + /// Writes an int64 field value, including tag, to the stream. + /// + public void WriteInt64(int fieldNumber, long value) + { + WriteTag(fieldNumber, WireFormat.WireType.Varint); + WriteRawVarint64((ulong) value); + } + + /// + /// Writes an int32 field value, including tag, to the stream. + /// + 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); + } + } + + /// + /// Writes a fixed64 field value, including tag, to the stream. + /// + [CLSCompliant(false)] + public void WriteFixed64(int fieldNumber, ulong value) + { + WriteTag(fieldNumber, WireFormat.WireType.Fixed64); + WriteRawLittleEndian64(value); + } + + /// + /// Writes a fixed32 field value, including tag, to the stream. + /// + [CLSCompliant(false)] + public void WriteFixed32(int fieldNumber, uint value) + { + WriteTag(fieldNumber, WireFormat.WireType.Fixed32); + WriteRawLittleEndian32(value); + } + + /// + /// Writes a bool field value, including tag, to the stream. + /// + public void WriteBool(int fieldNumber, bool value) + { + WriteTag(fieldNumber, WireFormat.WireType.Varint); + WriteRawByte(value ? (byte) 1 : (byte) 0); + } + + /// + /// Writes a string field value, including tag, to the stream. + /// + 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); + } + } + + /// + /// Writes a group field value, including tag, to the stream. + /// + 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 + + /// + /// Writes a double field value, including tag, to the stream. + /// + 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 + } + + /// + /// Writes a float field value, without a tag, to the stream. + /// + 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); + } + + /// + /// Writes a uint64 field value, without a tag, to the stream. + /// + [CLSCompliant(false)] + public void WriteUInt64NoTag(ulong value) + { + WriteRawVarint64(value); + } + + /// + /// Writes an int64 field value, without a tag, to the stream. + /// + public void WriteInt64NoTag(long value) + { + WriteRawVarint64((ulong) value); + } + + /// + /// Writes an int32 field value, without a tag, to the stream. + /// + public void WriteInt32NoTag(int value) + { + if (value >= 0) + { + WriteRawVarint32((uint) value); + } + else + { + // Must sign-extend. + WriteRawVarint64((ulong) value); + } + } + + /// + /// Writes a fixed64 field value, without a tag, to the stream. + /// + [CLSCompliant(false)] + public void WriteFixed64NoTag(ulong value) + { + WriteRawLittleEndian64(value); + } + + /// + /// Writes a fixed32 field value, without a tag, to the stream. + /// + [CLSCompliant(false)] + public void WriteFixed32NoTag(uint value) + { + WriteRawLittleEndian32(value); + } + + /// + /// Writes a bool field value, without a tag, to the stream. + /// + public void WriteBoolNoTag(bool value) + { + WriteRawByte(value ? (byte) 1 : (byte) 0); + } + + /// + /// Writes a string field value, without a tag, to the stream. + /// + 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); + } + } + + /// + /// Writes a group field value, without a tag, to the stream. + /// + 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 + + /// + /// Encodes and writes a tag. + /// + [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; + } + } + } + + /// + /// 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. + /// + [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); + } + + /// + /// Writes out an array of bytes. + /// + public void WriteRawBytes(byte[] value) + { + WriteRawBytes(value, 0, value.Length); + } + + /// + /// Writes out part of an array of bytes. + /// + 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; + + /// + /// Compute the number of bytes that would be needed to encode a + /// double field, including the tag. + /// + public static int ComputeDoubleSize(int fieldNumber, double value) + { + return ComputeTagSize(fieldNumber) + LittleEndian64Size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// float field, including the tag. + /// + public static int ComputeFloatSize(int fieldNumber, float value) + { + return ComputeTagSize(fieldNumber) + LittleEndian32Size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// uint64 field, including the tag. + /// + [CLSCompliant(false)] + public static int ComputeUInt64Size(int fieldNumber, ulong value) + { + return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(value); + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// int64 field, including the tag. + /// + public static int ComputeInt64Size(int fieldNumber, long value) + { + return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size((ulong) value); + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// int32 field, including the tag. + /// + 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; + } + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// fixed64 field, including the tag. + /// + [CLSCompliant(false)] + public static int ComputeFixed64Size(int fieldNumber, ulong value) + { + return ComputeTagSize(fieldNumber) + LittleEndian64Size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// fixed32 field, including the tag. + /// + [CLSCompliant(false)] + public static int ComputeFixed32Size(int fieldNumber, uint value) + { + return ComputeTagSize(fieldNumber) + LittleEndian32Size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// bool field, including the tag. + /// + public static int ComputeBoolSize(int fieldNumber, bool value) + { + return ComputeTagSize(fieldNumber) + 1; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// string field, including the tag. + /// + public static int ComputeStringSize(int fieldNumber, String value) + { + int byteArraySize = Encoding.UTF8.GetByteCount(value); + return ComputeTagSize(fieldNumber) + + ComputeRawVarint32Size((uint) byteArraySize) + + byteArraySize; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// group field, including the tag. + /// + public static int ComputeGroupSize(int fieldNumber, IMessageLite value) + { + return ComputeTagSize(fieldNumber)*2 + value.SerializedSize; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// group field represented by an UnknownFieldSet, including the tag. + /// + [Obsolete] + public static int ComputeUnknownGroupSize(int fieldNumber, + IMessageLite value) + { + return ComputeTagSize(fieldNumber)*2 + value.SerializedSize; + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// embedded message field, including the tag. + /// + public static int ComputeMessageSize(int fieldNumber, IMessageLite value) + { + int size = value.SerializedSize; + return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint) size) + size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// bytes field, including the tag. + /// + public static int ComputeBytesSize(int fieldNumber, ByteString value) + { + return ComputeTagSize(fieldNumber) + + ComputeRawVarint32Size((uint) value.Length) + + value.Length; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// uint32 field, including the tag. + /// + [CLSCompliant(false)] + public static int ComputeUInt32Size(int fieldNumber, uint value) + { + return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(value); + } + + /// + /// 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. + /// + public static int ComputeEnumSize(int fieldNumber, int value) + { + return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint) value); + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// sfixed32 field, including the tag. + /// + public static int ComputeSFixed32Size(int fieldNumber, int value) + { + return ComputeTagSize(fieldNumber) + LittleEndian32Size; + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// sfixed64 field, including the tag. + /// + public static int ComputeSFixed64Size(int fieldNumber, long value) + { + return ComputeTagSize(fieldNumber) + LittleEndian64Size; + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// sint32 field, including the tag. + /// + public static int ComputeSInt32Size(int fieldNumber, int value) + { + return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(EncodeZigZag32(value)); + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// sint64 field, including the tag. + /// + public static int ComputeSInt64Size(int fieldNumber, long value) + { + return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(EncodeZigZag64(value)); + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// double field, including the tag. + /// + public static int ComputeDoubleSizeNoTag(double value) + { + return LittleEndian64Size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// float field, including the tag. + /// + public static int ComputeFloatSizeNoTag(float value) + { + return LittleEndian32Size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// uint64 field, including the tag. + /// + [CLSCompliant(false)] + public static int ComputeUInt64SizeNoTag(ulong value) + { + return ComputeRawVarint64Size(value); + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// int64 field, including the tag. + /// + public static int ComputeInt64SizeNoTag(long value) + { + return ComputeRawVarint64Size((ulong) value); + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// int32 field, including the tag. + /// + public static int ComputeInt32SizeNoTag(int value) + { + if (value >= 0) + { + return ComputeRawVarint32Size((uint) value); + } + else + { + // Must sign-extend. + return 10; + } + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// fixed64 field, including the tag. + /// + [CLSCompliant(false)] + public static int ComputeFixed64SizeNoTag(ulong value) + { + return LittleEndian64Size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// fixed32 field, including the tag. + /// + [CLSCompliant(false)] + public static int ComputeFixed32SizeNoTag(uint value) + { + return LittleEndian32Size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// bool field, including the tag. + /// + public static int ComputeBoolSizeNoTag(bool value) + { + return 1; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// string field, including the tag. + /// + public static int ComputeStringSizeNoTag(String value) + { + int byteArraySize = Encoding.UTF8.GetByteCount(value); + return ComputeRawVarint32Size((uint) byteArraySize) + + byteArraySize; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// group field, including the tag. + /// + public static int ComputeGroupSizeNoTag(IMessageLite value) + { + return value.SerializedSize; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// group field represented by an UnknownFieldSet, including the tag. + /// + [Obsolete] + public static int ComputeUnknownGroupSizeNoTag(IMessageLite value) + { + return value.SerializedSize; + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// embedded message field, including the tag. + /// + public static int ComputeMessageSizeNoTag(IMessageLite value) + { + int size = value.SerializedSize; + return ComputeRawVarint32Size((uint) size) + size; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// bytes field, including the tag. + /// + public static int ComputeBytesSizeNoTag(ByteString value) + { + return ComputeRawVarint32Size((uint) value.Length) + + value.Length; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// uint32 field, including the tag. + /// + [CLSCompliant(false)] + public static int ComputeUInt32SizeNoTag(uint value) + { + return ComputeRawVarint32Size(value); + } + + /// + /// 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. + /// + public static int ComputeEnumSizeNoTag(int value) + { + return ComputeRawVarint32Size((uint) value); + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// sfixed32 field, including the tag. + /// + public static int ComputeSFixed32SizeNoTag(int value) + { + return LittleEndian32Size; + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// sfixed64 field, including the tag. + /// + public static int ComputeSFixed64SizeNoTag(long value) + { + return LittleEndian64Size; + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// sint32 field, including the tag. + /// + public static int ComputeSInt32SizeNoTag(int value) + { + return ComputeRawVarint32Size(EncodeZigZag32(value)); + } + + /// + /// Compute the number of bytes that would be needed to encode an + /// sint64 field, including the tag. + /// + 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. + */ + + /// + /// 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. + /// + 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); + } + + /// + /// 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. + /// + 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); + } + + /// + /// Compute the number of bytes that would be needed to encode a varint. + /// + [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; + } + + /// + /// Compute the number of bytes that would be needed to encode a varint. + /// + [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; + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// field of arbitrary type, including the tag, to the stream. + /// + 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); + } + } + + /// + /// Compute the number of bytes that would be needed to encode a + /// field of arbitrary type, excluding the tag, to the stream. + /// + 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); + } + } + + /// + /// Compute the number of bytes that would be needed to encode a tag. + /// + public static int ComputeTagSize(int fieldNumber) + { + return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0)); + } + + #endregion + + /// + /// Encode a 32-bit value with ZigZag encoding. + /// + /// + /// 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.) + /// + [CLSCompliant(false)] + public static uint EncodeZigZag32(int n) + { + // Note: the right-shift must be arithmetic + return (uint) ((n << 1) ^ (n >> 31)); + } + + /// + /// Encode a 64-bit value with ZigZag encoding. + /// + /// + /// 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.) + /// + [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; + } + + /// + /// Indicates that a CodedOutputStream wrapping a flat byte array + /// ran out of space. + /// + 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(); + } + } + + /// + /// 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. + /// + public void CheckNoSpaceLeft() + { + if (SpaceLeft != 0) + { + throw new InvalidOperationException("Did not write as much data as expected."); + } + } + + /// + /// If writing to a flat array, returns the space left in the array. Otherwise, + /// throws an InvalidOperationException. + /// + 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."); + } + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Collections/Dictionaries.cs b/src/ProtocolBuffers/Collections/Dictionaries.cs index 2a580385..1f3791b1 100644 --- a/src/ProtocolBuffers/Collections/Dictionaries.cs +++ b/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 { - - /// - /// Utility class for dictionaries. - /// - public static class Dictionaries { - - /// - /// 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... - /// - public static bool Equals(IDictionary left, IDictionary right) { - if (left.Count != right.Count) { - return false; - } - foreach (KeyValuePair 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 AsReadOnly (IDictionary dictionary) { - return dictionary.IsReadOnly ? dictionary : new ReadOnlyDictionary(dictionary); - } - - /// - /// 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. - /// - public static int GetHashCode(IDictionary dictionary) { - int ret = 31; - foreach (KeyValuePair entry in dictionary) { - int hash = entry.Key.GetHashCode() ^ GetDeepHashCode(entry.Value); - ret ^= hash; - } - return ret; - } - - /// - /// Determines the hash of a value by either taking it directly or hashing all the elements - /// for IEnumerable implementations. - /// - 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 +{ + /// + /// Utility class for dictionaries. + /// + public static class Dictionaries + { + /// + /// 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... + /// + public static bool Equals(IDictionary left, IDictionary right) + { + if (left.Count != right.Count) + { + return false; + } + foreach (KeyValuePair 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 AsReadOnly(IDictionary dictionary) + { + return dictionary.IsReadOnly ? dictionary : new ReadOnlyDictionary(dictionary); + } + + /// + /// 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. + /// + public static int GetHashCode(IDictionary dictionary) + { + int ret = 31; + foreach (KeyValuePair entry in dictionary) + { + int hash = entry.Key.GetHashCode() ^ GetDeepHashCode(entry.Value); + ret ^= hash; + } + return ret; + } + + /// + /// Determines the hash of a value by either taking it directly or hashing all the elements + /// for IEnumerable implementations. + /// + 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; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Collections/Enumerables.cs b/src/ProtocolBuffers/Collections/Enumerables.cs index 0f77ad9a..7ad9a832 100644 --- a/src/ProtocolBuffers/Collections/Enumerables.cs +++ b/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 { - /// - /// Utility class for IEnumerable (and potentially the generic version in the future). - /// - 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 +{ + /// + /// Utility class for IEnumerable (and potentially the generic version in the future). + /// + 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; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Collections/IPopsicleList.cs b/src/ProtocolBuffers/Collections/IPopsicleList.cs index de59de94..7f6fd8bc 100644 --- a/src/ProtocolBuffers/Collections/IPopsicleList.cs +++ b/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 { - /// - /// 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. - /// - /// 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...) - /// The element type of the list - public interface IPopsicleList : IList { - void Add(IEnumerable 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 +{ + /// + /// 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. + /// + /// 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...) + /// The element type of the list + public interface IPopsicleList : IList + { + void Add(IEnumerable collection); + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Collections/Lists.cs b/src/ProtocolBuffers/Collections/Lists.cs index 899baae5..a24e1d9b 100644 --- a/src/ProtocolBuffers/Collections/Lists.cs +++ b/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 { - - /// - /// Utility non-generic class for calling into Lists{T} using type inference. - /// - public static class Lists { - - /// - /// Returns a read-only view of the specified list. - /// - public static IList AsReadOnly(IList list) { - return Lists.AsReadOnly(list); - } - - public static bool Equals(IList left, IList right) { - if (left == right) { - return true; - } - if (left == null || right == null) { - return false; - } - if (left.Count != right.Count) { - return false; - } - IEqualityComparer comparer = EqualityComparer.Default; - for (int i = 0; i < left.Count; i++) { - if (!comparer.Equals(left[i], right[i])) { - return false; - } - } - return true; - } - - public static int GetHashCode(IList list) { - int hash = 31; - foreach (T element in list) { - hash = hash * 29 + element.GetHashCode(); - } - return hash; - } - } - - /// - /// Utility class for dealing with lists. - /// - public static class Lists { - - static readonly ReadOnlyCollection empty = new ReadOnlyCollection(new T[0]); - - /// - /// Returns an immutable empty list. - /// - public static ReadOnlyCollection Empty { - get { return empty; } - } - - /// - /// Returns either the original reference if it's already read-only, - /// or a new ReadOnlyCollection wrapping the original list. - /// - public static IList AsReadOnly(IList list) { - return list.IsReadOnly ? list : new ReadOnlyCollection(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 +{ + /// + /// Utility non-generic class for calling into Lists{T} using type inference. + /// + public static class Lists + { + /// + /// Returns a read-only view of the specified list. + /// + public static IList AsReadOnly(IList list) + { + return Lists.AsReadOnly(list); + } + + public static bool Equals(IList left, IList right) + { + if (left == right) + { + return true; + } + if (left == null || right == null) + { + return false; + } + if (left.Count != right.Count) + { + return false; + } + IEqualityComparer comparer = EqualityComparer.Default; + for (int i = 0; i < left.Count; i++) + { + if (!comparer.Equals(left[i], right[i])) + { + return false; + } + } + return true; + } + + public static int GetHashCode(IList list) + { + int hash = 31; + foreach (T element in list) + { + hash = hash*29 + element.GetHashCode(); + } + return hash; + } + } + + /// + /// Utility class for dealing with lists. + /// + public static class Lists + { + private static readonly ReadOnlyCollection empty = new ReadOnlyCollection(new T[0]); + + /// + /// Returns an immutable empty list. + /// + public static ReadOnlyCollection Empty + { + get { return empty; } + } + + /// + /// Returns either the original reference if it's already read-only, + /// or a new ReadOnlyCollection wrapping the original list. + /// + public static IList AsReadOnly(IList list) + { + return list.IsReadOnly ? list : new ReadOnlyCollection(list); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Collections/PopsicleList.cs b/src/ProtocolBuffers/Collections/PopsicleList.cs index 26996d9b..33324303 100644 --- a/src/ProtocolBuffers/Collections/PopsicleList.cs +++ b/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 { - /// - /// Proxies calls to a , but allows the list - /// to be made read-only (with the method), - /// after which any modifying methods throw . - /// - public sealed class PopsicleList : IPopsicleList { - - private readonly List items = new List(); - private bool readOnly = false; - - /// - /// 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. - /// - 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 collection) { - if (readOnly) { - throw new NotSupportedException("List is read-only"); - } - items.AddRange(collection); - } - - public IEnumerator 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 +{ + /// + /// Proxies calls to a , but allows the list + /// to be made read-only (with the method), + /// after which any modifying methods throw . + /// + public sealed class PopsicleList : IPopsicleList + { + private readonly List items = new List(); + private bool readOnly = false; + + /// + /// 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. + /// + 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 collection) + { + if (readOnly) + { + throw new NotSupportedException("List is read-only"); + } + items.AddRange(collection); + } + + public IEnumerator GetEnumerator() + { + return items.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + private void ValidateModification() + { + if (readOnly) + { + throw new NotSupportedException("List is read-only"); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs b/src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs index 3be460dc..b0bc55ff 100644 --- a/src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs +++ b/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 { - /// - /// Read-only wrapper around another dictionary. - /// - public sealed class ReadOnlyDictionary : IDictionary { - readonly IDictionary wrapped; - - public ReadOnlyDictionary(IDictionary 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 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 Values { - get { return wrapped.Values; } - } - - public TValue this[TKey key] { - get { - return wrapped[key]; - } - set { - throw new InvalidOperationException(); - } - } - - public void Add(KeyValuePair item) { - throw new InvalidOperationException(); - } - - public void Clear() { - throw new InvalidOperationException(); - } - - public bool Contains(KeyValuePair item) { - return wrapped.Contains(item); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) { - wrapped.CopyTo(array, arrayIndex); - } - - public int Count { - get { return wrapped.Count; } - } - - public bool IsReadOnly { - get { return true; } - } - - public bool Remove(KeyValuePair item) { - throw new InvalidOperationException(); - } - - public IEnumerator> 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 +{ + /// + /// Read-only wrapper around another dictionary. + /// + public sealed class ReadOnlyDictionary : IDictionary + { + private readonly IDictionary wrapped; + + public ReadOnlyDictionary(IDictionary 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 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 Values + { + get { return wrapped.Values; } + } + + public TValue this[TKey key] + { + get { return wrapped[key]; } + set { throw new InvalidOperationException(); } + } + + public void Add(KeyValuePair item) + { + throw new InvalidOperationException(); + } + + public void Clear() + { + throw new InvalidOperationException(); + } + + public bool Contains(KeyValuePair item) + { + return wrapped.Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + wrapped.CopyTo(array, arrayIndex); + } + + public int Count + { + get { return wrapped.Count; } + } + + public bool IsReadOnly + { + get { return true; } + } + + public bool Remove(KeyValuePair item) + { + throw new InvalidOperationException(); + } + + public IEnumerator> 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(); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Delegates.cs b/src/ProtocolBuffers/Delegates.cs index 11cd2f4c..0a7dec07 100644 --- a/src/ProtocolBuffers/Delegates.cs +++ b/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 { - /// - /// Delegate to return a stream when asked, used by MessageStreamIterator. - /// - public delegate Stream StreamProvider(); - - // These delegate declarations mirror the ones in .NET 3.5 for the sake of familiarity. - internal delegate TResult Func(); - internal delegate TResult Func(T arg); - internal delegate TResult Func(T1 arg1, T2 arg2); - internal delegate TResult Func(T1 arg1, T2 arg2, T3 arg3); - internal delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4); - internal delegate void Action(); - internal delegate void Action(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 +{ + /// + /// Delegate to return a stream when asked, used by MessageStreamIterator. + /// + public delegate Stream StreamProvider(); + + // These delegate declarations mirror the ones in .NET 3.5 for the sake of familiarity. + internal delegate TResult Func(); + + internal delegate TResult Func(T arg); + + internal delegate TResult Func(T1 arg1, T2 arg2); + + internal delegate TResult Func(T1 arg1, T2 arg2, T3 arg3); + + internal delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4); + + internal delegate void Action(); + + internal delegate void Action(T1 arg1, T2 arg2); +} \ No newline at end of file diff --git a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs index adfbc9a3..fecebf1b 100644 --- a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs +++ b/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 CSharpFileOptions; - public const int CSharpFieldOptionsFieldNumber = 1000; - public static pb::GeneratedExtensionBase CSharpFieldOptions; - public const int CsharpServiceOptionsFieldNumber = 1000; - public static pb::GeneratedExtensionBase CsharpServiceOptions; - public const int CsharpMethodOptionsFieldNumber = 1000; - public static pb::GeneratedExtensionBase CsharpMethodOptions; - #endregion - - #region Static variables - internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFileOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFieldOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpServiceOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_CSharpServiceOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpMethodOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable 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 + CSharpFileOptions; + + public const int CSharpFieldOptionsFieldNumber = 1000; + + public static pb::GeneratedExtensionBase + CSharpFieldOptions; + + public const int CsharpServiceOptionsFieldNumber = 1000; + + public static pb::GeneratedExtensionBase + CsharpServiceOptions; + + public const int CsharpMethodOptionsFieldNumber = 1000; + + public static pb::GeneratedExtensionBase + CsharpMethodOptions; + + #endregion + + #region Static variables + + internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFileOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFieldOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpServiceOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_CSharpServiceOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpMethodOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + 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(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(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(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(internal__static_google_protobuf_CSharpMethodOptions__Descriptor, - new string[] { "DispatchId", }); - global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFileOptions = pb::GeneratedSingleExtension.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[0]); - global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFieldOptions = pb::GeneratedSingleExtension.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[1]); - global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CsharpServiceOptions = pb::GeneratedSingleExtension.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[2]); - global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CsharpMethodOptions = pb::GeneratedSingleExtension.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 { - 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 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 + { + 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 + 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 + { + 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 + { + 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 + 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 + { + 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 + { + 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 + 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 { - 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 + { + 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 { - 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 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 { - 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 + { + 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 + 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 + { + 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 { - 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 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 { - 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 { - 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 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 { - 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 +} \ No newline at end of file diff --git a/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs b/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs index 05fdd25f..a460b945 100644 --- a/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs +++ b/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 internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_FileDescriptorProto__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_DescriptorProto__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_DescriptorProto__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_FieldDescriptorProto__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumDescriptorProto__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_ServiceDescriptorProto__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_MethodDescriptorProto__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_FileOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_FileOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_MessageOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_MessageOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_FieldOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_FieldOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_EnumOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumValueOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_ServiceOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_ServiceOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_MethodOptions__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_MethodOptions__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_UninterpretedOption__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable; - internal static pbd::MessageDescriptor internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor; - internal static pb::FieldAccess.FieldAccessorTable 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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 { - 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 InternalFieldAccessors { - get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable; } - } - - public const int FileFieldNumber = 1; - private pbc::PopsicleList file_ = new pbc::PopsicleList(); - public scg::IList 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 { - 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 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 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 { - 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 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 dependency_ = new pbc::PopsicleList(); - public scg::IList 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 messageType_ = new pbc::PopsicleList(); - public scg::IList 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 enumType_ = new pbc::PopsicleList(); - public scg::IList 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 service_ = new pbc::PopsicleList(); - public scg::IList 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 extension_ = new pbc::PopsicleList(); - public scg::IList 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 + + internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_FileDescriptorProto__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_DescriptorProto__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_DescriptorProto__FieldAccessorTable; + + internal static pbd::MessageDescriptor + internal__static_google_protobuf_DescriptorProto_ExtensionRange__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_FieldDescriptorProto__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumDescriptorProto__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumValueDescriptorProto__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_ServiceDescriptorProto__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_MethodDescriptorProto__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_FileOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_FileOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_MessageOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_MessageOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_FieldOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_FieldOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_EnumOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_EnumValueOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_ServiceOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_ServiceOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_MethodOptions__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_MethodOptions__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_UninterpretedOption__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable; + + internal static pbd::MessageDescriptor internal__static_google_protobuf_UninterpretedOption_NamePart__Descriptor; + + internal static + pb::FieldAccess.FieldAccessorTable + + 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 + { + 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 { - 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 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 values) { - base.AddRange(values, result.dependency_); - return this; - } - public Builder ClearDependency() { - result.dependency_.Clear(); - return this; - } - - public pbc::IPopsicleList 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 values) { - base.AddRange(values, result.messageType_); - return this; - } - public Builder ClearMessageType() { - result.messageType_.Clear(); - return this; - } - - public pbc::IPopsicleList 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 values) { - base.AddRange(values, result.enumType_); - return this; - } - public Builder ClearEnumType() { - result.enumType_.Clear(); - return this; - } - - public pbc::IPopsicleList 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 values) { - base.AddRange(values, result.service_); - return this; - } - public Builder ClearService() { - result.service_.Clear(); - return this; - } - - public pbc::IPopsicleList 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 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 { - 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 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 { - 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 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 + 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 file_ = + new pbc::PopsicleList(); + + public scg::IList 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 { - 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 field_ = new pbc::PopsicleList(); - public scg::IList 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 extension_ = new pbc::PopsicleList(); - public scg::IList 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 nestedType_ = new pbc::PopsicleList(); - public scg::IList 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 enumType_ = new pbc::PopsicleList(); - public scg::IList 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 extensionRange_ = new pbc::PopsicleList(); - public scg::IList 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 { - 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 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 values) { - base.AddRange(values, result.field_); - return this; - } - public Builder ClearField() { - result.field_.Clear(); - return this; - } - - public pbc::IPopsicleList 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 values) { - base.AddRange(values, result.extension_); - return this; - } - public Builder ClearExtension() { - result.extension_.Clear(); - return this; - } - - public pbc::IPopsicleList 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 values) { - base.AddRange(values, result.nestedType_); - return this; - } - public Builder ClearNestedType() { - result.nestedType_.Clear(); - return this; - } - - public pbc::IPopsicleList 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 values) { - base.AddRange(values, result.enumType_); - return this; - } - public Builder ClearEnumType() { - result.enumType_.Clear(); - return this; - } - - public pbc::IPopsicleList 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 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 { - 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 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 { - 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 { - 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 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 value_ = new pbc::PopsicleList(); - public scg::IList 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 { - 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 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 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 { - 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 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 { - 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 { - 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 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 method_ = new pbc::PopsicleList(); - public scg::IList 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 + { + 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 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 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 { - 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 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 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 { - 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 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 { - 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 { - 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 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 uninterpretedOption_ = new pbc::PopsicleList(); - public scg::IList 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.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 { - 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 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 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 { - 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 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 uninterpretedOption_ = new pbc::PopsicleList(); - public scg::IList 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.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 { - 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 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 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 { - 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 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 uninterpretedOption_ = new pbc::PopsicleList(); - public scg::IList 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.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 { - 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 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 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 { - 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 InternalFieldAccessors { - get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumOptions__FieldAccessorTable; } - } - - public const int UninterpretedOptionFieldNumber = 999; - private pbc::PopsicleList uninterpretedOption_ = new pbc::PopsicleList(); - public scg::IList 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.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 { - 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 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 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 { - 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 InternalFieldAccessors { - get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable; } - } - - public const int UninterpretedOptionFieldNumber = 999; - private pbc::PopsicleList uninterpretedOption_ = new pbc::PopsicleList(); - public scg::IList 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.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 { - 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 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 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 { - 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 InternalFieldAccessors { - get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_ServiceOptions__FieldAccessorTable; } - } - - public const int UninterpretedOptionFieldNumber = 999; - private pbc::PopsicleList uninterpretedOption_ = new pbc::PopsicleList(); - public scg::IList 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.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 { - 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 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 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 { - 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 InternalFieldAccessors { - get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MethodOptions__FieldAccessorTable; } - } - - public const int UninterpretedOptionFieldNumber = 999; - private pbc::PopsicleList uninterpretedOption_ = new pbc::PopsicleList(); - public scg::IList 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.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 + { + 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 + 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 dependency_ = new pbc::PopsicleList(); + + public scg::IList 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 messageType_ = + new pbc::PopsicleList(); + + public scg::IList 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 enumType_ = + new pbc::PopsicleList(); + + public scg::IList 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 service_ = + new pbc::PopsicleList(); + + public scg::IList 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 extension_ = + new pbc::PopsicleList(); + + public scg::IList 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 + { + 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 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 values) + { + base.AddRange(values, result.dependency_); + return this; + } + + public Builder ClearDependency() + { + result.dependency_.Clear(); + return this; + } + + public pbc::IPopsicleList 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 values) + { + base.AddRange(values, result.messageType_); + return this; + } + + public Builder ClearMessageType() + { + result.messageType_.Clear(); + return this; + } + + public pbc::IPopsicleList 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 values) + { + base.AddRange(values, result.enumType_); + return this; + } + + public Builder ClearEnumType() + { + result.enumType_.Clear(); + return this; + } + + public pbc::IPopsicleList + 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 values) + { + base.AddRange(values, result.service_); + return this; + } + + public Builder ClearService() + { + result.service_.Clear(); + return this; + } + + public pbc::IPopsicleList + 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 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 + { + 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 + 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 + { + 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 + 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 + { + 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 field_ = + new pbc::PopsicleList(); + + public scg::IList 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 extension_ = + new pbc::PopsicleList(); + + public scg::IList 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 nestedType_ = + new pbc::PopsicleList(); + + public scg::IList 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 enumType_ = + new pbc::PopsicleList(); + + public scg::IList 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 + extensionRange_ = + new pbc::PopsicleList + (); + + public scg::IList + 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 + { + 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 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 values) + { + base.AddRange(values, result.field_); + return this; + } + + public Builder ClearField() + { + result.field_.Clear(); + return this; + } + + public pbc::IPopsicleList + 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 values) + { + base.AddRange(values, result.extension_); + return this; + } + + public Builder ClearExtension() + { + result.extension_.Clear(); + return this; + } + + public pbc::IPopsicleList 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 values) + { + base.AddRange(values, result.nestedType_); + return this; + } + + public Builder ClearNestedType() + { + result.nestedType_.Clear(); + return this; + } + + public pbc::IPopsicleList 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 values) + { + base.AddRange(values, result.enumType_); + return this; + } + + public Builder ClearEnumType() + { + result.enumType_.Clear(); + return this; + } + + public + pbc::IPopsicleList + 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 + 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 + { + 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 + 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 + { + 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 + { + 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 + 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 value_ = + new pbc::PopsicleList(); + + public scg::IList 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 + { + 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 + 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 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 + { + 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 + 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 + { + 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 + { + 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 + 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 method_ = + new pbc::PopsicleList(); + + public scg::IList 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 + { + 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 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 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 { - 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 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 values) { - base.AddRange(values, result.uninterpretedOption_); - return this; - } - public Builder ClearUninterpretedOption() { - result.uninterpretedOption_.Clear(); - return this; - } + + public sealed partial class MethodDescriptorProto : + pb::GeneratedMessage + { + 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 + 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 + { + 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 + { + 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 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 + uninterpretedOption_ = + new pbc::PopsicleList(); + + public scg::IList 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.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 + { + 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 + 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 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 { - private static readonly UninterpretedOption defaultInstance = new Builder().BuildPartial(); - public static UninterpretedOption DefaultInstance { - get { return defaultInstance; } + + public sealed partial class MessageOptions : pb::ExtendableMessage + { + 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 + 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 + uninterpretedOption_ = + new pbc::PopsicleList(); + + public scg::IList 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.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 + { + 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 + 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 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 + { + 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 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 + uninterpretedOption_ = + new pbc::PopsicleList(); + + public scg::IList 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.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 + { + 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 + 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 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 + { + 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 InternalFieldAccessors + { + get + { + return + global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile. + internal__static_google_protobuf_EnumOptions__FieldAccessorTable; + } + } + + public const int UninterpretedOptionFieldNumber = 999; + + private pbc::PopsicleList + uninterpretedOption_ = + new pbc::PopsicleList(); + + public scg::IList 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.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 + { + 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 + 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 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 + { + 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 + InternalFieldAccessors + { + get + { + return + global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile. + internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable; + } + } + + public const int UninterpretedOptionFieldNumber = 999; + + private pbc::PopsicleList + uninterpretedOption_ = + new pbc::PopsicleList(); + + public scg::IList 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.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 + { + 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 + 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 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 InternalFieldAccessors { - get { return global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable; } + + public sealed partial class ServiceOptions : pb::ExtendableMessage + { + 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 + InternalFieldAccessors + { + get + { + return + global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile. + internal__static_google_protobuf_ServiceOptions__FieldAccessorTable; + } + } + + public const int UninterpretedOptionFieldNumber = 999; + + private pbc::PopsicleList + uninterpretedOption_ = + new pbc::PopsicleList(); + + public scg::IList 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.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 + { + 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 + 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 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 { - 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 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 + { + 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 + InternalFieldAccessors + { + get + { + return + global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile. + internal__static_google_protobuf_MethodOptions__FieldAccessorTable; + } + } + + public const int UninterpretedOptionFieldNumber = 999; + + private pbc::PopsicleList + uninterpretedOption_ = + new pbc::PopsicleList(); + + public scg::IList 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.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 + { + 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 + 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 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 + { + 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 + 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 + { + 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 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 + { + 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 + name_ = + new pbc::PopsicleList + (); + + public scg::IList 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 { - 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 + { + 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 + 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 + 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 name_ = new pbc::PopsicleList(); - public scg::IList 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 { - 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 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 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 - -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/DescriptorProtos/IDescriptorProto.cs b/src/ProtocolBuffers/DescriptorProtos/IDescriptorProto.cs index 9aad813f..c894d324 100644 --- a/src/ProtocolBuffers/DescriptorProtos/IDescriptorProto.cs +++ b/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 { - - /// - /// 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. - /// - /// The associated options protocol buffer type - public interface IDescriptorProto { - - /// - /// The brief name of the descriptor's target. - /// - string Name { get; } - - /// - /// The options for this descriptor. - /// - 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 +{ + /// + /// 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. + /// + /// The associated options protocol buffer type + public interface IDescriptorProto + { + /// + /// The brief name of the descriptor's target. + /// + string Name { get; } + + /// + /// The options for this descriptor. + /// + TOptions Options { get; } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/DescriptorProtos/PartialClasses.cs b/src/ProtocolBuffers/DescriptorProtos/PartialClasses.cs index 6a4b1430..adc2afb0 100644 --- a/src/ProtocolBuffers/DescriptorProtos/PartialClasses.cs +++ b/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 { } - public partial class EnumDescriptorProto : IDescriptorProto { } - public partial class EnumValueDescriptorProto : IDescriptorProto { } - public partial class FieldDescriptorProto : IDescriptorProto { } - public partial class FileDescriptorProto : IDescriptorProto { } - public partial class MethodDescriptorProto : IDescriptorProto { } - public partial class ServiceDescriptorProto : IDescriptorProto { } -} +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 + { + } + + public partial class EnumDescriptorProto : IDescriptorProto + { + } + + public partial class EnumValueDescriptorProto : IDescriptorProto + { + } + + public partial class FieldDescriptorProto : IDescriptorProto + { + } + + public partial class FileDescriptorProto : IDescriptorProto + { + } + + public partial class MethodDescriptorProto : IDescriptorProto + { + } + + public partial class ServiceDescriptorProto : IDescriptorProto + { + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/DescriptorBase.cs b/src/ProtocolBuffers/Descriptors/DescriptorBase.cs index 1f4d6651..59006f80 100644 --- a/src/ProtocolBuffers/Descriptors/DescriptorBase.cs +++ b/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 { - /// - /// Base class for nearly all descriptors, providing common functionality. - /// - /// Type of the protocol buffer form of this descriptor - /// Type of the options protocol buffer for this descriptor - public abstract class DescriptorBase : IDescriptor - where TProto : IMessage, IDescriptorProto { - - 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; } - } - - /// - /// Returns the protocol buffer form of this descriptor. - /// - public TProto Proto { - get { return proto; } - } - - public TOptions Options { - get { return proto.Options; } - } - - /// - /// The fully qualified name of the descriptor's target. - /// - public string FullName { - get { return fullName; } - } - - /// - /// The brief name of the descriptor's target. - /// - public string Name { - get { return proto.Name; } - } - - /// - /// The file this descriptor was declared in. - /// - 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 +{ + /// + /// Base class for nearly all descriptors, providing common functionality. + /// + /// Type of the protocol buffer form of this descriptor + /// Type of the options protocol buffer for this descriptor + public abstract class DescriptorBase : IDescriptor + where TProto : IMessage, IDescriptorProto + { + 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; } + } + + /// + /// Returns the protocol buffer form of this descriptor. + /// + public TProto Proto + { + get { return proto; } + } + + public TOptions Options + { + get { return proto.Options; } + } + + /// + /// The fully qualified name of the descriptor's target. + /// + public string FullName + { + get { return fullName; } + } + + /// + /// The brief name of the descriptor's target. + /// + public string Name + { + get { return proto.Name; } + } + + /// + /// The file this descriptor was declared in. + /// + public FileDescriptor File + { + get { return file; } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/DescriptorPool.cs b/src/ProtocolBuffers/Descriptors/DescriptorPool.cs index c8654572..12abafeb 100644 --- a/src/ProtocolBuffers/Descriptors/DescriptorPool.cs +++ b/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 { - /// - /// Contains lookup tables containing all the descriptors defined in a particular file. - /// - internal sealed class DescriptorPool { - - private readonly IDictionary descriptorsByName = - new Dictionary(); - private readonly IDictionary fieldsByNumber = - new Dictionary(); - private readonly IDictionary enumValuesByNumber = - new Dictionary(); - 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); - } - } - - /// - /// Finds a symbol of the given name within the pool. - /// - /// The type of symbol to look for - /// Fully-qualified name to look up - /// The symbol with the given name and type, - /// or null if the symbol doesn't exist or has the wrong type - internal T FindSymbol(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; - } - - /// - /// 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). - /// - 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); - } - - /// - /// Adds a symbol to the symbol table. - /// - /// The symbol already existed - /// in the symbol table. - 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); - - /// - /// Verifies that the descriptor's name is valid (i.e. it contains - /// only letters, digits and underscores, and does not start with a digit). - /// - /// - 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."); - } - } - - /// - /// Returns the field with the given number in the given descriptor, - /// or null if it can't be found. - /// - 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; - } - - /// - /// Adds a field to the fieldsByNumber table. - /// - /// A field with the same - /// containing type and number already exists. - 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; - } - - /// - /// 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.) - /// - internal void AddEnumValueByNumber(EnumValueDescriptor enumValue) { - DescriptorIntPair key = new DescriptorIntPair(enumValue.EnumDescriptor, enumValue.Number); - if (!enumValuesByNumber.ContainsKey(key)) { - enumValuesByNumber[key] = enumValue; - } - } - - /// - /// 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. - /// - 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(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(name); - break; - } else { - scopeToTry.Length = dotpos + 1; - - // Append firstPart and try to find. - scopeToTry.Append(firstPart); - result = FindSymbol(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(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; - } - } - - /// - /// Struct used to hold the keys for the fieldByNumber table. - /// - struct DescriptorIntPair : IEquatable { - - 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 +{ + /// + /// Contains lookup tables containing all the descriptors defined in a particular file. + /// + internal sealed class DescriptorPool + { + private readonly IDictionary descriptorsByName = + new Dictionary(); + + private readonly IDictionary fieldsByNumber = + new Dictionary(); + + private readonly IDictionary enumValuesByNumber = + new Dictionary(); + + 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); + } + } + + /// + /// Finds a symbol of the given name within the pool. + /// + /// The type of symbol to look for + /// Fully-qualified name to look up + /// The symbol with the given name and type, + /// or null if the symbol doesn't exist or has the wrong type + internal T FindSymbol(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; + } + + /// + /// 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). + /// + 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); + } + + /// + /// Adds a symbol to the symbol table. + /// + /// The symbol already existed + /// in the symbol table. + 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); + + /// + /// Verifies that the descriptor's name is valid (i.e. it contains + /// only letters, digits and underscores, and does not start with a digit). + /// + /// + 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."); + } + } + + /// + /// Returns the field with the given number in the given descriptor, + /// or null if it can't be found. + /// + 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; + } + + /// + /// Adds a field to the fieldsByNumber table. + /// + /// A field with the same + /// containing type and number already exists. + 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; + } + + /// + /// 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.) + /// + internal void AddEnumValueByNumber(EnumValueDescriptor enumValue) + { + DescriptorIntPair key = new DescriptorIntPair(enumValue.EnumDescriptor, enumValue.Number); + if (!enumValuesByNumber.ContainsKey(key)) + { + enumValuesByNumber[key] = enumValue; + } + } + + /// + /// 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. + /// + 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(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(name); + break; + } + else + { + scopeToTry.Length = dotpos + 1; + + // Append firstPart and try to find. + scopeToTry.Append(firstPart); + result = FindSymbol(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(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; + } + } + + /// + /// Struct used to hold the keys for the fieldByNumber table. + /// + private struct DescriptorIntPair : IEquatable + { + 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; + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/DescriptorUtil.cs b/src/ProtocolBuffers/Descriptors/DescriptorUtil.cs index 4d78b300..00efdbe8 100644 --- a/src/ProtocolBuffers/Descriptors/DescriptorUtil.cs +++ b/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 { - /// - /// Internal class containing utility methods when working with descriptors. - /// - internal static class DescriptorUtil { - /// - /// Equivalent to Func[TInput, int, TOutput] but usable in .NET 2.0. Only used to convert - /// arrays. - /// - internal delegate TOutput IndexedConverter(TInput element, int index); - - /// - /// Converts the given array into a read-only list, applying the specified conversion to - /// each input element. - /// - internal static IList ConvertAndMakeReadOnly(IList input, - IndexedConverter converter) { - TOutput[] array = new TOutput[input.Count]; - for (int i = 0; i < array.Length; i++) { - array[i] = converter(input[i], i); - } - return Lists.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 +{ + /// + /// Internal class containing utility methods when working with descriptors. + /// + internal static class DescriptorUtil + { + /// + /// Equivalent to Func[TInput, int, TOutput] but usable in .NET 2.0. Only used to convert + /// arrays. + /// + internal delegate TOutput IndexedConverter(TInput element, int index); + + /// + /// Converts the given array into a read-only list, applying the specified conversion to + /// each input element. + /// + internal static IList ConvertAndMakeReadOnly(IList input, + IndexedConverter + converter) + { + TOutput[] array = new TOutput[input.Count]; + for (int i = 0; i < array.Length; i++) + { + array[i] = converter(input[i], i); + } + return Lists.AsReadOnly(array); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/DescriptorValidationException.cs b/src/ProtocolBuffers/Descriptors/DescriptorValidationException.cs index a262d173..d05d60d7 100644 --- a/src/ProtocolBuffers/Descriptors/DescriptorValidationException.cs +++ b/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 { - /// - /// Thrown when building descriptors fails because the source DescriptorProtos - /// are not valid. - /// - public sealed class DescriptorValidationException : Exception { - - private readonly String name; - private readonly IMessage proto; - private readonly string description; - - /// - /// The full name of the descriptor where the error occurred. - /// - public String ProblemSymbolName { - get { return name; } - } - - /// - /// The protocol message representation of the invalid descriptor. - /// - public IMessage ProblemProto { - get { return proto; } - } - - /// - /// A human-readable description of the error. (The Message property - /// is made up of the descriptor's name and this description.) - /// - 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 +{ + /// + /// Thrown when building descriptors fails because the source DescriptorProtos + /// are not valid. + /// + public sealed class DescriptorValidationException : Exception + { + private readonly String name; + private readonly IMessage proto; + private readonly string description; + + /// + /// The full name of the descriptor where the error occurred. + /// + public String ProblemSymbolName + { + get { return name; } + } + + /// + /// The protocol message representation of the invalid descriptor. + /// + public IMessage ProblemProto + { + get { return proto; } + } + + /// + /// A human-readable description of the error. (The Message property + /// is made up of the descriptor's name and this description.) + /// + 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; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs index acf113de..80c2bd0f 100644 --- a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs +++ b/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 { - - /// - /// Descriptor for an enum type in a .proto file. - /// - public sealed class EnumDescriptor : IndexedDescriptorBase, IEnumLiteMap { - - private readonly MessageDescriptor containingType; - private readonly IList 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); - } - - /// - /// If this is a nested type, get the outer descriptor, otherwise null. - /// - public MessageDescriptor ContainingType { - get { return containingType; } - } - - /// - /// An unmodifiable list of defined value descriptors for this enum. - /// - public IList Values { - get { return values; } - } - - /// - /// Logic moved from FieldSet to continue current behavior - /// - public bool IsValidValue(IEnumLite value) { - return value is EnumValueDescriptor && ((EnumValueDescriptor)value).EnumDescriptor == this; - } - - /// - /// Finds an enum value by number. If multiple enum values have the - /// same number, this returns the first defined value with that number. - /// - public EnumValueDescriptor FindValueByNumber(int number) { - return File.DescriptorPool.FindEnumValueByNumber(this, number); - } - - IEnumLite IEnumLiteMap.FindValueByNumber(int number) { - return FindValueByNumber(number); - } - /// - /// Finds an enum value by name. - /// - /// The unqualified name of the value (e.g. "FOO"). - /// The value's descriptor, or null if not found. - public EnumValueDescriptor FindValueByName(string name) { - return File.DescriptorPool.FindSymbol(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 +{ + /// + /// Descriptor for an enum type in a .proto file. + /// + public sealed class EnumDescriptor : IndexedDescriptorBase, + IEnumLiteMap + { + private readonly MessageDescriptor containingType; + private readonly IList 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); + } + + /// + /// If this is a nested type, get the outer descriptor, otherwise null. + /// + public MessageDescriptor ContainingType + { + get { return containingType; } + } + + /// + /// An unmodifiable list of defined value descriptors for this enum. + /// + public IList Values + { + get { return values; } + } + + /// + /// Logic moved from FieldSet to continue current behavior + /// + public bool IsValidValue(IEnumLite value) + { + return value is EnumValueDescriptor && ((EnumValueDescriptor) value).EnumDescriptor == this; + } + + /// + /// Finds an enum value by number. If multiple enum values have the + /// same number, this returns the first defined value with that number. + /// + public EnumValueDescriptor FindValueByNumber(int number) + { + return File.DescriptorPool.FindEnumValueByNumber(this, number); + } + + IEnumLite IEnumLiteMap.FindValueByNumber(int number) + { + return FindValueByNumber(number); + } + + /// + /// Finds an enum value by name. + /// + /// The unqualified name of the value (e.g. "FOO"). + /// The value's descriptor, or null if not found. + public EnumValueDescriptor FindValueByName(string name) + { + return File.DescriptorPool.FindSymbol(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)); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs b/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs index 732dec06..afb9cbbc 100644 --- a/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs +++ b/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 { - - /// - /// Descriptor for a single enum value within an enum in a .proto file. - /// - public sealed class EnumValueDescriptor : IndexedDescriptorBase, 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 +{ + /// + /// Descriptor for a single enum value within an enum in a .proto file. + /// + public sealed class EnumValueDescriptor : IndexedDescriptorBase, + 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; } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs b/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs index 854b3a89..8653a078 100644 --- a/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs +++ b/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 { - - /// - /// Descriptor for a field or extension within a message in a .proto file. - /// - public sealed class FieldDescriptor : IndexedDescriptorBase, IComparable, 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(); - } - - /// - /// Maps a field type as included in the .proto file to a FieldType. - /// - 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"); - } - } - - /// - /// Returns the default value for a mapped type. - /// - 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; } - } - - /// - /// Indicates whether or not the field had an explicitly-defined default value. - /// - public bool HasDefaultValue { - get { return Proto.HasDefaultValue; } - } - - /// - /// 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. - /// - public object DefaultValue { - get { - if (MappedType == MappedType.Message) { - throw new InvalidOperationException("FieldDescriptor.DefaultValue called on an embedded message field."); - } - return defaultValue; - } - } - - /// - /// Indicates whether or not this field is an extension. - /// - 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()}. - */ - /// - /// Get the field's containing type. For extensions, this is the type being - /// extended, not the location where the extension was defined. See - /// . - /// - public MessageDescriptor ContainingType { - get { return containingType; } - } - - /// - /// Returns the C#-specific options for this field descriptor. This will always be - /// completely filled in. - /// - public CSharpFieldOptions CSharpOptions { - get { - lock (optionsLock) { - if (csharpFieldOptions == null) { - csharpFieldOptions = BuildOrFakeCSharpOptions(); - } - } - return csharpFieldOptions; - } - } - - /// - /// For extensions defined nested within message types, gets - /// the outer type. Not valid for non-extension fields. - /// - /// - /// - /// message Foo { - /// extensions 1000 to max; - /// } - /// extend Foo { - /// optional int32 baz = 1234; - /// } - /// message Bar { - /// extend Foo { - /// optional int32 qux = 4321; - /// } - /// } - /// - /// The containing type for both baz and qux is Foo. - /// However, the extension scope for baz is null while - /// the extension scope for qux is Bar. - /// - 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; } - } - - /// - /// Compares this descriptor with another one, ordering in "canonical" order - /// which simply means ascending order by field number. - /// must be a field of the same type, i.e. the of - /// both fields must be the same. - /// - 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; - } - - /// - /// Compares this descriptor with another one, ordering in "canonical" order - /// which simply means ascending order by field number. - /// must be a field of the same type, i.e. the of - /// both fields must be the same. - /// - public int CompareTo(IFieldDescriptorLite other) { - return FieldNumber - other.FieldNumber; - } - - IEnumLiteMap IFieldDescriptorLite.EnumType { - get { return EnumType; } - } - - bool IFieldDescriptorLite.MessageSetWireFormat { - get { return ContainingType.Options.MessageSetWireFormat; } - } - - /// - /// For enum fields, returns the field's type. - /// - public EnumDescriptor EnumType { - get { - if (MappedType != MappedType.Enum) { - throw new InvalidOperationException("EnumType is only valid for enum fields."); - } - return enumType; - } - } - - /// - /// For embedded message and group fields, returns the field's type. - /// - public MessageDescriptor MessageType { - get { - if (MappedType != MappedType.Message) { - throw new InvalidOperationException("MessageType is only valid for enum fields."); - } - return messageType; - } - } - - /// - /// Immutable mapping from field type to mapped type. Built using the attributes on - /// FieldType values. - /// - public static readonly IDictionary FieldTypeToMappedTypeMap = MapFieldTypes(); - - private static IDictionary MapFieldTypes() { - var map = new Dictionary(); - 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); - } - - /// - /// Look up and cross-link all field types etc. - /// - 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.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 +{ + /// + /// Descriptor for a field or extension within a message in a .proto file. + /// + public sealed class FieldDescriptor : IndexedDescriptorBase, + IComparable, 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(); + } + + /// + /// Maps a field type as included in the .proto file to a FieldType. + /// + 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"); + } + } + + /// + /// Returns the default value for a mapped type. + /// + 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; } + } + + /// + /// Indicates whether or not the field had an explicitly-defined default value. + /// + public bool HasDefaultValue + { + get { return Proto.HasDefaultValue; } + } + + /// + /// 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. + /// + public object DefaultValue + { + get + { + if (MappedType == MappedType.Message) + { + throw new InvalidOperationException( + "FieldDescriptor.DefaultValue called on an embedded message field."); + } + return defaultValue; + } + } + + /// + /// Indicates whether or not this field is an extension. + /// + 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()}. + */ + + /// + /// Get the field's containing type. For extensions, this is the type being + /// extended, not the location where the extension was defined. See + /// . + /// + public MessageDescriptor ContainingType + { + get { return containingType; } + } + + /// + /// Returns the C#-specific options for this field descriptor. This will always be + /// completely filled in. + /// + public CSharpFieldOptions CSharpOptions + { + get + { + lock (optionsLock) + { + if (csharpFieldOptions == null) + { + csharpFieldOptions = BuildOrFakeCSharpOptions(); + } + } + return csharpFieldOptions; + } + } + + /// + /// For extensions defined nested within message types, gets + /// the outer type. Not valid for non-extension fields. + /// + /// + /// + /// message Foo { + /// extensions 1000 to max; + /// } + /// extend Foo { + /// optional int32 baz = 1234; + /// } + /// message Bar { + /// extend Foo { + /// optional int32 qux = 4321; + /// } + /// } + /// + /// The containing type for both baz and qux is Foo. + /// However, the extension scope for baz is null while + /// the extension scope for qux is Bar. + /// + 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; } + } + + /// + /// Compares this descriptor with another one, ordering in "canonical" order + /// which simply means ascending order by field number. + /// must be a field of the same type, i.e. the of + /// both fields must be the same. + /// + 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; + } + + /// + /// Compares this descriptor with another one, ordering in "canonical" order + /// which simply means ascending order by field number. + /// must be a field of the same type, i.e. the of + /// both fields must be the same. + /// + public int CompareTo(IFieldDescriptorLite other) + { + return FieldNumber - other.FieldNumber; + } + + IEnumLiteMap IFieldDescriptorLite.EnumType + { + get { return EnumType; } + } + + bool IFieldDescriptorLite.MessageSetWireFormat + { + get { return ContainingType.Options.MessageSetWireFormat; } + } + + /// + /// For enum fields, returns the field's type. + /// + public EnumDescriptor EnumType + { + get + { + if (MappedType != MappedType.Enum) + { + throw new InvalidOperationException("EnumType is only valid for enum fields."); + } + return enumType; + } + } + + /// + /// For embedded message and group fields, returns the field's type. + /// + public MessageDescriptor MessageType + { + get + { + if (MappedType != MappedType.Message) + { + throw new InvalidOperationException("MessageType is only valid for enum fields."); + } + return messageType; + } + } + + /// + /// Immutable mapping from field type to mapped type. Built using the attributes on + /// FieldType values. + /// + public static readonly IDictionary FieldTypeToMappedTypeMap = MapFieldTypes(); + + private static IDictionary MapFieldTypes() + { + var map = new Dictionary(); + 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); + } + + /// + /// Look up and cross-link all field types etc. + /// + 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.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."); + } + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/FieldMappingAttribute.cs b/src/ProtocolBuffers/Descriptors/FieldMappingAttribute.cs index 0c933583..1c1b9be6 100644 --- a/src/ProtocolBuffers/Descriptors/FieldMappingAttribute.cs +++ b/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 { - - /// - /// Defined specifically for the enumeration, - /// this allows each field type to specify the mapped type and wire type. - /// - [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; } - - - /// - /// Immutable mapping from field type to mapped type. Built using the attributes on - /// FieldType values. - /// - static readonly IDictionary FieldTypeToMappedTypeMap = MapFieldTypes(); - - private static IDictionary MapFieldTypes() { - var map = new Dictionary(); - 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 +{ + /// + /// Defined specifically for the enumeration, + /// this allows each field type to specify the mapped type and wire type. + /// + [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; } + + + /// + /// Immutable mapping from field type to mapped type. Built using the attributes on + /// FieldType values. + /// + private static readonly IDictionary FieldTypeToMappedTypeMap = MapFieldTypes(); + + private static IDictionary MapFieldTypes() + { + var map = new Dictionary(); + 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; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/FieldType.cs b/src/ProtocolBuffers/Descriptors/FieldType.cs index b019f888..056d3d45 100644 --- a/src/ProtocolBuffers/Descriptors/FieldType.cs +++ b/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 { - /// - /// 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. - /// - 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 +{ + /// + /// 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. + /// + 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 + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/FileDescriptor.cs b/src/ProtocolBuffers/Descriptors/FileDescriptor.cs index 1648c34f..392db9a7 100644 --- a/src/ProtocolBuffers/Descriptors/FileDescriptor.cs +++ b/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 { - /// - /// 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. - /// - public sealed class FileDescriptor : IDescriptor { - private FileDescriptorProto proto; - private readonly IList messageTypes; - private readonly IList enumTypes; - private readonly IList services; - private readonly IList extensions; - private readonly IList 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[]) 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)); - } - - - /// - /// Allows a file descriptor to be configured with a set of external options, e.g. from the - /// command-line arguments to protogen. - /// - 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(); - } - - /// - /// The descriptor in its protocol message representation. - /// - public FileDescriptorProto Proto { - get { return proto; } - } - - /// - /// The defined in descriptor.proto. - /// - public FileOptions Options { - get { return proto.Options; } - } - - /// - /// Returns the C#-specific options for this file descriptor. This will always be - /// completely filled in. - /// - public CSharpFileOptions CSharpOptions { - get { - lock (optionsLock) { - if (csharpFileOptions == null) { - csharpFileOptions = BuildOrFakeWithDefaultOptions(CSharpFileOptions.DefaultInstance); - } - } - return csharpFileOptions; - } - } - - /// - /// The file name. - /// - public string Name { - get { return proto.Name; } - } - - /// - /// The package as declared in the .proto file. This may or may not - /// be equivalent to the .NET namespace of the generated classes. - /// - public string Package { - get { return proto.Package; } - } - - /// - /// Unmodifiable list of top-level message types declared in this file. - /// - public IList MessageTypes { - get { return messageTypes; } - } - - /// - /// Unmodifiable list of top-level enum types declared in this file. - /// - public IList EnumTypes { - get { return enumTypes; } - } - - /// - /// Unmodifiable list of top-level services declared in this file. - /// - public IList Services { - get { return services; } - } - - /// - /// Unmodifiable list of top-level extensions declared in this file. - /// - public IList Extensions { - get { return extensions; } - } - - /// - /// Unmodifiable list of this file's dependencies (imports). - /// - public IList Dependencies { - get { return dependencies; } - } - - /// - /// Implementation of IDescriptor.FullName - just returns the same as Name. - /// - string IDescriptor.FullName { - get { return Name; } - } - - /// - /// Implementation of IDescriptor.File - just returns this descriptor. - /// - FileDescriptor IDescriptor.File { - get { return this; } - } - - /// - /// Protocol buffer describing this descriptor. - /// - IMessage IDescriptor.Proto { - get { return Proto; } - } - - /// - /// Pool containing symbol descriptors. - /// - internal DescriptorPool DescriptorPool { - get { return pool; } - } - - /// - /// Finds a type (message, enum, service or extension) in the file by name. Does not find nested types. - /// - /// The unqualified type name to look for. - /// The type of descriptor to look for (or ITypeDescriptor for any) - /// The type's descriptor, or null if not found. - public T FindTypeByName(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(name); - if (result != null && result.File == this) { - return result; - } - return null; - } - - /// - /// Builds a FileDescriptor from its protocol buffer representation. - /// - /// The protocol message form of the FileDescriptor. - /// 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. - /// If 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. - 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(); - } - } - - /// - /// 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). - /// - public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData, FileDescriptor[] dependencies) { - return InternalBuildGeneratedFileFrom(descriptorData, dependencies, x => null); - } - - /// - /// 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. - /// - /// - /// - 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; - } - - /// - /// 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. - /// - 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 +{ + /// + /// 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. + /// + public sealed class FileDescriptor : IDescriptor + { + private FileDescriptorProto proto; + private readonly IList messageTypes; + private readonly IList enumTypes; + private readonly IList services; + private readonly IList extensions; + private readonly IList 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[]) 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)); + } + + + /// + /// Allows a file descriptor to be configured with a set of external options, e.g. from the + /// command-line arguments to protogen. + /// + 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(); + } + + /// + /// The descriptor in its protocol message representation. + /// + public FileDescriptorProto Proto + { + get { return proto; } + } + + /// + /// The defined in descriptor.proto. + /// + public FileOptions Options + { + get { return proto.Options; } + } + + /// + /// Returns the C#-specific options for this file descriptor. This will always be + /// completely filled in. + /// + public CSharpFileOptions CSharpOptions + { + get + { + lock (optionsLock) + { + if (csharpFileOptions == null) + { + csharpFileOptions = BuildOrFakeWithDefaultOptions(CSharpFileOptions.DefaultInstance); + } + } + return csharpFileOptions; + } + } + + /// + /// The file name. + /// + public string Name + { + get { return proto.Name; } + } + + /// + /// The package as declared in the .proto file. This may or may not + /// be equivalent to the .NET namespace of the generated classes. + /// + public string Package + { + get { return proto.Package; } + } + + /// + /// Unmodifiable list of top-level message types declared in this file. + /// + public IList MessageTypes + { + get { return messageTypes; } + } + + /// + /// Unmodifiable list of top-level enum types declared in this file. + /// + public IList EnumTypes + { + get { return enumTypes; } + } + + /// + /// Unmodifiable list of top-level services declared in this file. + /// + public IList Services + { + get { return services; } + } + + /// + /// Unmodifiable list of top-level extensions declared in this file. + /// + public IList Extensions + { + get { return extensions; } + } + + /// + /// Unmodifiable list of this file's dependencies (imports). + /// + public IList Dependencies + { + get { return dependencies; } + } + + /// + /// Implementation of IDescriptor.FullName - just returns the same as Name. + /// + string IDescriptor.FullName + { + get { return Name; } + } + + /// + /// Implementation of IDescriptor.File - just returns this descriptor. + /// + FileDescriptor IDescriptor.File + { + get { return this; } + } + + /// + /// Protocol buffer describing this descriptor. + /// + IMessage IDescriptor.Proto + { + get { return Proto; } + } + + /// + /// Pool containing symbol descriptors. + /// + internal DescriptorPool DescriptorPool + { + get { return pool; } + } + + /// + /// Finds a type (message, enum, service or extension) in the file by name. Does not find nested types. + /// + /// The unqualified type name to look for. + /// The type of descriptor to look for (or ITypeDescriptor for any) + /// The type's descriptor, or null if not found. + public T FindTypeByName(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(name); + if (result != null && result.File == this) + { + return result; + } + return null; + } + + /// + /// Builds a FileDescriptor from its protocol buffer representation. + /// + /// The protocol message form of the FileDescriptor. + /// 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. + /// If 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. + 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(); + } + } + + /// + /// 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). + /// + public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData, FileDescriptor[] dependencies) + { + return InternalBuildGeneratedFileFrom(descriptorData, dependencies, x => null); + } + + /// + /// 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. + /// + /// + /// + 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; + } + + /// + /// 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. + /// + 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)); + } + } + } } \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/IDescriptor.cs b/src/ProtocolBuffers/Descriptors/IDescriptor.cs index 937dd7e7..899c1560 100644 --- a/src/ProtocolBuffers/Descriptors/IDescriptor.cs +++ b/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 { - - /// - /// The non-generic form of the IDescriptor interface. Useful for describing a general - /// descriptor. - /// - public interface IDescriptor { - string Name { get; } - string FullName { get; } - FileDescriptor File { get; } - IMessage Proto { get; } - } - - /// - /// Strongly-typed form of the IDescriptor interface. - /// - /// Protocol buffer type underlying this descriptor type - public interface IDescriptor : 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 +{ + /// + /// The non-generic form of the IDescriptor interface. Useful for describing a general + /// descriptor. + /// + public interface IDescriptor + { + string Name { get; } + string FullName { get; } + FileDescriptor File { get; } + IMessage Proto { get; } + } + + /// + /// Strongly-typed form of the IDescriptor interface. + /// + /// Protocol buffer type underlying this descriptor type + public interface IDescriptor : IDescriptor where TProto : IMessage + { + new TProto Proto { get; } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/IndexedDescriptorBase.cs b/src/ProtocolBuffers/Descriptors/IndexedDescriptorBase.cs index 50842d1f..bdb4eb82 100644 --- a/src/ProtocolBuffers/Descriptors/IndexedDescriptorBase.cs +++ b/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 { - /// - /// Base class for descriptors which are also indexed. This is all of them other than - /// . - /// - public abstract class IndexedDescriptorBase : DescriptorBase - where TProto : IMessage, IDescriptorProto { - - private readonly int index; - - protected IndexedDescriptorBase(TProto proto, FileDescriptor file, string fullName, int index) - : base(proto, file, fullName) { - this.index = index; - } - - /// - /// The index of this descriptor within its parent descriptor. - /// - /// - /// 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.) - /// - 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 +{ + /// + /// Base class for descriptors which are also indexed. This is all of them other than + /// . + /// + public abstract class IndexedDescriptorBase : DescriptorBase + where TProto : IMessage, IDescriptorProto + { + private readonly int index; + + protected IndexedDescriptorBase(TProto proto, FileDescriptor file, string fullName, int index) + : base(proto, file, fullName) + { + this.index = index; + } + + /// + /// The index of this descriptor within its parent descriptor. + /// + /// + /// 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.) + /// + public int Index + { + get { return index; } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/MappedType.cs b/src/ProtocolBuffers/Descriptors/MappedType.cs index aee3fa8d..0a555307 100644 --- a/src/ProtocolBuffers/Descriptors/MappedType.cs +++ b/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 { - /// - /// Type as it's mapped onto a .NET type. - /// - 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 +{ + /// + /// Type as it's mapped onto a .NET type. + /// + public enum MappedType + { + Int32, + Int64, + UInt32, + UInt64, + Single, + Double, + Boolean, + String, + ByteString, + Message, + Enum + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/MessageDescriptor.cs b/src/ProtocolBuffers/Descriptors/MessageDescriptor.cs index 79356170..d438c0ff 100644 --- a/src/ProtocolBuffers/Descriptors/MessageDescriptor.cs +++ b/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 { - - /// - /// Describes a message type. - /// - public sealed class MessageDescriptor : IndexedDescriptorBase { - - private readonly MessageDescriptor containingType; - private readonly IList nestedTypes; - private readonly IList enumTypes; - private readonly IList fields; - private readonly IList 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); - } - - /// - /// If this is a nested type, get the outer descriptor, otherwise null. - /// - public MessageDescriptor ContainingType { - get { return containingType; } - } - - /// - /// An unmodifiable list of this message type's fields. - /// - public IList Fields { - get { return fields; } - } - - /// - /// An unmodifiable list of this message type's extensions. - /// - public IList Extensions { - get { return extensions; } - } - - /// - /// An unmodifiable list of this message type's nested types. - /// - public IList NestedTypes { - get { return nestedTypes; } - } - - /// - /// An unmodifiable list of this message type's enum types. - /// - public IList EnumTypes { - get { return enumTypes; } - } - - /// - /// 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. - /// - internal bool HasRequiredFields { - get { return hasRequiredFields; } - } - - /// - /// Determines if the given field number is an extension. - /// - public bool IsExtensionNumber(int number) { - foreach (DescriptorProto.Types.ExtensionRange range in Proto.ExtensionRangeList) { - if (range.Start <= number && number < range.End) { - return true; - } - } - return false; - } - - /// - /// Finds a field by field name. - /// - /// The unqualified name of the field (e.g. "foo"). - /// The field's descriptor, or null if not found. - public FieldDescriptor FindFieldByName(String name) { - return File.DescriptorPool.FindSymbol(FullName + "." + name); - } - - /// - /// Finds a field by field number. - /// - /// The field number within this message type. - /// The field's descriptor, or null if not found. - public FieldDescriptor FindFieldByNumber(int number) { - return File.DescriptorPool.FindFieldByNumber(this, number); - } - - /// - /// Finds a field by its property name, as it would be generated by protogen. - /// - /// The property name within this message type. - /// The field's descriptor, or null if not found. - 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; - } - - /// - /// Finds a nested descriptor by name. The is valid for fields, nested - /// message types and enums. - /// - /// The unqualified name of the descriptor, e.g. "Foo" - /// The descriptor, or null if not found. - public T FindDescriptor(string name) - where T : class, IDescriptor { - return File.DescriptorPool.FindSymbol(FullName + "." + name); - } - - /// - /// Looks up and cross-links all fields, nested types, and extensions. - /// - 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 alreadySeen = new Dictionary(); - hasRequiredFields = CheckRequiredFields(alreadySeen); - } - - private bool CheckRequiredFields(IDictionary 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; - } - - /// - /// See FileDescriptor.ReplaceProto - /// - 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 +{ + /// + /// Describes a message type. + /// + public sealed class MessageDescriptor : IndexedDescriptorBase + { + private readonly MessageDescriptor containingType; + private readonly IList nestedTypes; + private readonly IList enumTypes; + private readonly IList fields; + private readonly IList 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); + } + + /// + /// If this is a nested type, get the outer descriptor, otherwise null. + /// + public MessageDescriptor ContainingType + { + get { return containingType; } + } + + /// + /// An unmodifiable list of this message type's fields. + /// + public IList Fields + { + get { return fields; } + } + + /// + /// An unmodifiable list of this message type's extensions. + /// + public IList Extensions + { + get { return extensions; } + } + + /// + /// An unmodifiable list of this message type's nested types. + /// + public IList NestedTypes + { + get { return nestedTypes; } + } + + /// + /// An unmodifiable list of this message type's enum types. + /// + public IList EnumTypes + { + get { return enumTypes; } + } + + /// + /// 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. + /// + internal bool HasRequiredFields + { + get { return hasRequiredFields; } + } + + /// + /// Determines if the given field number is an extension. + /// + public bool IsExtensionNumber(int number) + { + foreach (DescriptorProto.Types.ExtensionRange range in Proto.ExtensionRangeList) + { + if (range.Start <= number && number < range.End) + { + return true; + } + } + return false; + } + + /// + /// Finds a field by field name. + /// + /// The unqualified name of the field (e.g. "foo"). + /// The field's descriptor, or null if not found. + public FieldDescriptor FindFieldByName(String name) + { + return File.DescriptorPool.FindSymbol(FullName + "." + name); + } + + /// + /// Finds a field by field number. + /// + /// The field number within this message type. + /// The field's descriptor, or null if not found. + public FieldDescriptor FindFieldByNumber(int number) + { + return File.DescriptorPool.FindFieldByNumber(this, number); + } + + /// + /// Finds a field by its property name, as it would be generated by protogen. + /// + /// The property name within this message type. + /// The field's descriptor, or null if not found. + 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; + } + + /// + /// Finds a nested descriptor by name. The is valid for fields, nested + /// message types and enums. + /// + /// The unqualified name of the descriptor, e.g. "Foo" + /// The descriptor, or null if not found. + public T FindDescriptor(string name) + where T : class, IDescriptor + { + return File.DescriptorPool.FindSymbol(FullName + "." + name); + } + + /// + /// Looks up and cross-links all fields, nested types, and extensions. + /// + 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 alreadySeen = new Dictionary(); + hasRequiredFields = CheckRequiredFields(alreadySeen); + } + + private bool CheckRequiredFields(IDictionary 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; + } + + /// + /// See FileDescriptor.ReplaceProto + /// + 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)); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/MethodDescriptor.cs b/src/ProtocolBuffers/Descriptors/MethodDescriptor.cs index 45daecb7..f9ede245 100644 --- a/src/ProtocolBuffers/Descriptors/MethodDescriptor.cs +++ b/src/ProtocolBuffers/Descriptors/MethodDescriptor.cs @@ -1,86 +1,94 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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 { - /// - /// Describes a single method in a service. - /// - public sealed class MethodDescriptor : IndexedDescriptorBase { - - private readonly ServiceDescriptor service; - private MessageDescriptor inputType; - private MessageDescriptor outputType; - - /// - /// The service this method belongs to. - /// - public ServiceDescriptor Service { - get { return service; } - } - - /// - /// The method's input type. - /// - public MessageDescriptor InputType { - get { return inputType; } - } - - /// - /// The method's input type. - /// - public MessageDescriptor OutputType { - get { return outputType; } - } - - internal MethodDescriptor(MethodDescriptorProto proto, FileDescriptor file, - ServiceDescriptor parent, int index) - : base(proto, file, parent.FullName + "." + proto.Name, index) { - service = parent; - file.DescriptorPool.AddSymbol(this); - } - - internal void CrossLink() { - IDescriptor lookup = File.DescriptorPool.LookupSymbol(Proto.InputType, this); - if (!(lookup is MessageDescriptor)) { - throw new DescriptorValidationException(this, "\"" + Proto.InputType + "\" is not a message type."); - } - inputType = (MessageDescriptor) lookup; - - lookup = File.DescriptorPool.LookupSymbol(Proto.OutputType, this); - if (!(lookup is MessageDescriptor)) { - throw new DescriptorValidationException(this, "\"" + Proto.OutputType + "\" is not a message type."); - } - outputType = (MessageDescriptor) lookup; - } - } -} +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 +{ + /// + /// Describes a single method in a service. + /// + public sealed class MethodDescriptor : IndexedDescriptorBase + { + private readonly ServiceDescriptor service; + private MessageDescriptor inputType; + private MessageDescriptor outputType; + + /// + /// The service this method belongs to. + /// + public ServiceDescriptor Service + { + get { return service; } + } + + /// + /// The method's input type. + /// + public MessageDescriptor InputType + { + get { return inputType; } + } + + /// + /// The method's input type. + /// + public MessageDescriptor OutputType + { + get { return outputType; } + } + + internal MethodDescriptor(MethodDescriptorProto proto, FileDescriptor file, + ServiceDescriptor parent, int index) + : base(proto, file, parent.FullName + "." + proto.Name, index) + { + service = parent; + file.DescriptorPool.AddSymbol(this); + } + + internal void CrossLink() + { + IDescriptor lookup = File.DescriptorPool.LookupSymbol(Proto.InputType, this); + if (!(lookup is MessageDescriptor)) + { + throw new DescriptorValidationException(this, "\"" + Proto.InputType + "\" is not a message type."); + } + inputType = (MessageDescriptor) lookup; + + lookup = File.DescriptorPool.LookupSymbol(Proto.OutputType, this); + if (!(lookup is MessageDescriptor)) + { + throw new DescriptorValidationException(this, "\"" + Proto.OutputType + "\" is not a message type."); + } + outputType = (MessageDescriptor) lookup; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/PackageDescriptor.cs b/src/ProtocolBuffers/Descriptors/PackageDescriptor.cs index 81798bfd..02549f9c 100644 --- a/src/ProtocolBuffers/Descriptors/PackageDescriptor.cs +++ b/src/ProtocolBuffers/Descriptors/PackageDescriptor.cs @@ -1,67 +1,73 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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 { - /// - /// Represents a package in the symbol table. We use PackageDescriptors - /// just as placeholders so that someone cannot define, say, a message type - /// that has the same name as an existing package. - /// - internal sealed class PackageDescriptor : IDescriptor { - - private readonly string name; - private readonly string fullName; - private readonly FileDescriptor file; - - internal PackageDescriptor(string name, string fullName, FileDescriptor file) { - this.file = file; - this.fullName = fullName; - this.name = name; - } - - public IMessage Proto { - get { return file.Proto; } - } - - public string Name { - get { return name; } - } - - public string FullName { - get { return fullName; } - } - - 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. + +namespace Google.ProtocolBuffers.Descriptors +{ + /// + /// Represents a package in the symbol table. We use PackageDescriptors + /// just as placeholders so that someone cannot define, say, a message type + /// that has the same name as an existing package. + /// + internal sealed class PackageDescriptor : IDescriptor + { + private readonly string name; + private readonly string fullName; + private readonly FileDescriptor file; + + internal PackageDescriptor(string name, string fullName, FileDescriptor file) + { + this.file = file; + this.fullName = fullName; + this.name = name; + } + + public IMessage Proto + { + get { return file.Proto; } + } + + public string Name + { + get { return name; } + } + + public string FullName + { + get { return fullName; } + } + + public FileDescriptor File + { + get { return file; } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Descriptors/ServiceDescriptor.cs b/src/ProtocolBuffers/Descriptors/ServiceDescriptor.cs index 349b756d..417c0838 100644 --- a/src/ProtocolBuffers/Descriptors/ServiceDescriptor.cs +++ b/src/ProtocolBuffers/Descriptors/ServiceDescriptor.cs @@ -1,83 +1,89 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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 { - - /// - /// Describes a service type. - /// - public sealed class ServiceDescriptor : IndexedDescriptorBase { - - private readonly IList methods; - - public ServiceDescriptor(ServiceDescriptorProto proto, FileDescriptor file, int index) - : base(proto, file, ComputeFullName(file, null, proto.Name), index) { - - methods = DescriptorUtil.ConvertAndMakeReadOnly(proto.MethodList, - (method, i) => new MethodDescriptor(method, file, this, i)); - - file.DescriptorPool.AddSymbol(this); - } - - /// - /// An unmodifiable list of methods in this service. - /// - public IList Methods { - get { return methods; } - } - - /// - /// Finds a method by name. - /// - /// The unqualified name of the method (e.g. "Foo"). - /// The method's decsriptor, or null if not found. - public MethodDescriptor FindMethodByName(String name) { - return File.DescriptorPool.FindSymbol(FullName + "." + name); - } - - internal void CrossLink() { - foreach (MethodDescriptor method in methods) { - method.CrossLink(); - } - } - - internal override void ReplaceProto(ServiceDescriptorProto newProto) { - base.ReplaceProto(newProto); - for (int i = 0; i < methods.Count; i++) { - methods[i].ReplaceProto(newProto.GetMethod(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 +{ + /// + /// Describes a service type. + /// + public sealed class ServiceDescriptor : IndexedDescriptorBase + { + private readonly IList methods; + + public ServiceDescriptor(ServiceDescriptorProto proto, FileDescriptor file, int index) + : base(proto, file, ComputeFullName(file, null, proto.Name), index) + { + methods = DescriptorUtil.ConvertAndMakeReadOnly(proto.MethodList, + (method, i) => new MethodDescriptor(method, file, this, i)); + + file.DescriptorPool.AddSymbol(this); + } + + /// + /// An unmodifiable list of methods in this service. + /// + public IList Methods + { + get { return methods; } + } + + /// + /// Finds a method by name. + /// + /// The unqualified name of the method (e.g. "Foo"). + /// The method's decsriptor, or null if not found. + public MethodDescriptor FindMethodByName(String name) + { + return File.DescriptorPool.FindSymbol(FullName + "." + name); + } + + internal void CrossLink() + { + foreach (MethodDescriptor method in methods) + { + method.CrossLink(); + } + } + + internal override void ReplaceProto(ServiceDescriptorProto newProto) + { + base.ReplaceProto(newProto); + for (int i = 0; i < methods.Count; i++) + { + methods[i].ReplaceProto(newProto.GetMethod(i)); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/DynamicMessage.cs b/src/ProtocolBuffers/DynamicMessage.cs index 44fe0f39..0255b00d 100644 --- a/src/ProtocolBuffers/DynamicMessage.cs +++ b/src/ProtocolBuffers/DynamicMessage.cs @@ -1,437 +1,509 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers { - - /// - /// An implementation of IMessage that can represent arbitrary types, given a MessageaDescriptor. - /// - public sealed class DynamicMessage : AbstractMessage { - - private readonly MessageDescriptor type; - private readonly FieldSet fields; - private readonly UnknownFieldSet unknownFields; - private int memoizedSize = -1; - - /// - /// Creates a DynamicMessage with the given FieldSet. - /// - /// - /// - /// - private DynamicMessage(MessageDescriptor type, FieldSet fields, UnknownFieldSet unknownFields) { - this.type = type; - this.fields = fields; - this.unknownFields = unknownFields; - } - - /// - /// Returns a DynamicMessage representing the default instance of the given type. - /// - /// - /// - public static DynamicMessage GetDefaultInstance(MessageDescriptor type) { - return new DynamicMessage(type, FieldSet.DefaultInstance, UnknownFieldSet.DefaultInstance); - } - - /// - /// Parses a message of the given type from the given stream. - /// - public static DynamicMessage ParseFrom(MessageDescriptor type, CodedInputStream input) { - Builder builder = CreateBuilder(type); - Builder dynamicBuilder = builder.MergeFrom(input); - return dynamicBuilder.BuildParsed(); - } - - /// - /// Parse a message of the given type from the given stream and extension registry. - /// - /// - /// - /// - /// - public static DynamicMessage ParseFrom(MessageDescriptor type, CodedInputStream input, ExtensionRegistry extensionRegistry) { - Builder builder = CreateBuilder(type); - Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry); - return dynamicBuilder.BuildParsed(); - } - - /// - /// Parses a message of the given type from the given stream. - /// - public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input) { - Builder builder = CreateBuilder(type); - Builder dynamicBuilder = builder.MergeFrom(input); - return dynamicBuilder.BuildParsed(); - } - - /// - /// Parse a message of the given type from the given stream and extension registry. - /// - /// - /// - /// - /// - public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input, ExtensionRegistry extensionRegistry) { - Builder builder = CreateBuilder(type); - Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry); - return dynamicBuilder.BuildParsed(); - } - - /// - /// Parse as a message of the given type and return it. - /// - public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data) { - Builder builder = CreateBuilder(type); - Builder dynamicBuilder = builder.MergeFrom(data); - return dynamicBuilder.BuildParsed(); - } - - /// - /// Parse as a message of the given type and return it. - /// - public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data, ExtensionRegistry extensionRegistry) { - Builder builder = CreateBuilder(type); - Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry); - return dynamicBuilder.BuildParsed(); - - } - - /// - /// Parse as a message of the given type and return it. - /// - public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data) { - Builder builder = CreateBuilder(type); - Builder dynamicBuilder = builder.MergeFrom(data); - return dynamicBuilder.BuildParsed(); - } - - /// - /// Parse as a message of the given type and return it. - /// - public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data, ExtensionRegistry extensionRegistry) { - Builder builder = CreateBuilder(type); - Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry); - return dynamicBuilder.BuildParsed(); - } - - /// - /// Constructs a builder for the given type. - /// - public static Builder CreateBuilder(MessageDescriptor type) { - return new Builder(type); - } - - /// - /// Constructs a builder for a message of the same type as , - /// and initializes it with the same contents. - /// - /// - /// - public static Builder CreateBuilder(IMessage prototype) { - return new Builder(prototype.DescriptorForType).MergeFrom(prototype); - } - - // ----------------------------------------------------------------- - // Implementation of IMessage interface. - - public override MessageDescriptor DescriptorForType { - get { return type; } - } - - public override DynamicMessage DefaultInstanceForType { - get { return GetDefaultInstance(type); } - } - - public override IDictionary AllFields { - get { return fields.AllFieldDescriptors; } - } - - public override bool HasField(FieldDescriptor field) { - VerifyContainingType(field); - return fields.HasField(field); - } - - public override object this[FieldDescriptor field] { - get { - VerifyContainingType(field); - object result = fields[field]; - if (result == null) { - result = GetDefaultInstance(field.MessageType); - } - return result; - } - } - - public override int GetRepeatedFieldCount(FieldDescriptor field) { - VerifyContainingType(field); - return fields.GetRepeatedFieldCount(field); - } - - public override object this[FieldDescriptor field, int index] { - get { - VerifyContainingType(field); - return fields[field, index]; - } - } - - public override UnknownFieldSet UnknownFields { - get { return unknownFields; } - } - - public bool Initialized { - get { return fields.IsInitializedWithRespectTo(type.Fields); } - } - - public override void WriteTo(CodedOutputStream output) { - fields.WriteTo(output); - if (type.Options.MessageSetWireFormat) { - unknownFields.WriteAsMessageSetTo(output); - } else { - unknownFields.WriteTo(output); - } - } - - public override int SerializedSize { - get { - int size = memoizedSize; - if (size != -1) return size; - - size = fields.SerializedSize; - if (type.Options.MessageSetWireFormat) { - size += unknownFields.SerializedSizeAsMessageSet; - } else { - size += unknownFields.SerializedSize; - } - - memoizedSize = size; - return size; - } - } - - public override Builder CreateBuilderForType() { - return new Builder(type); - } - - public override Builder ToBuilder() { - return CreateBuilderForType().MergeFrom(this); - } - - /// - /// Verifies that the field is a field of this message. - /// - private void VerifyContainingType(FieldDescriptor field) { - if (field.ContainingType != type) { - throw new ArgumentException("FieldDescriptor does not match message type."); - } - } - - /// - /// Builder for dynamic messages. Instances are created with DynamicMessage.CreateBuilder. - /// - public sealed class Builder : AbstractBuilder { - private readonly MessageDescriptor type; - private FieldSet fields; - private UnknownFieldSet unknownFields; - - internal Builder(MessageDescriptor type) { - this.type = type; - this.fields = FieldSet.CreateInstance(); - this.unknownFields = UnknownFieldSet.DefaultInstance; - } - - protected override Builder ThisBuilder { - get { return this; } - } - - public override Builder Clear() { - fields.Clear(); - return this; - } - - public override Builder MergeFrom(IMessage other) { - if (other.DescriptorForType != type) { - throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type."); - } - fields.MergeFrom(other); - MergeUnknownFields(other.UnknownFields); - return this; - } - - public override Builder MergeFrom(DynamicMessage other) { - IMessage downcast = other; - return MergeFrom(downcast); - } - - public override DynamicMessage Build() { - if (fields != null && !IsInitialized) { - throw new UninitializedMessageException(new DynamicMessage(type, fields, unknownFields)); - } - return BuildPartial(); - } - - /// - /// Helper for DynamicMessage.ParseFrom() methods to call. Throws - /// InvalidProtocolBufferException - /// - /// - internal DynamicMessage BuildParsed() { - if (!IsInitialized) { - throw new UninitializedMessageException(new DynamicMessage(type, fields, unknownFields)).AsInvalidProtocolBufferException(); - } - return BuildPartial(); - } - - public override DynamicMessage BuildPartial() { - if (fields == null) { - throw new InvalidOperationException("Build() has already been called on this Builder."); - } - fields.MakeImmutable(); - DynamicMessage result = new DynamicMessage(type, fields, unknownFields); - fields = null; - unknownFields = null; - return result; - } - - public override Builder Clone() { - Builder result = new Builder(type); - result.fields.MergeFrom(fields); - return result; - } - - public override bool IsInitialized { - get { return fields.IsInitializedWithRespectTo(type.Fields); } - } - - public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) { - UnknownFieldSet.Builder unknownFieldsBuilder = UnknownFieldSet.CreateBuilder(unknownFields); - unknownFieldsBuilder.MergeFrom(input, extensionRegistry, this); - unknownFields = unknownFieldsBuilder.Build(); - return this; - } - - public override MessageDescriptor DescriptorForType { - get { return type; } - } - - public override DynamicMessage DefaultInstanceForType { - get { return GetDefaultInstance(type); } - } - - public override IDictionary AllFields { - get { return fields.AllFieldDescriptors; } - } - - public override IBuilder CreateBuilderForField(FieldDescriptor field) { - VerifyContainingType(field); - if (field.MappedType != MappedType.Message) { - throw new ArgumentException("CreateBuilderForField is only valid for fields with message type."); - } - return new Builder(field.MessageType); - } - - public override bool HasField(FieldDescriptor field) { - VerifyContainingType(field); - return fields.HasField(field); - } - - public override object this[FieldDescriptor field, int index] { - get { - VerifyContainingType(field); - return fields[field, index]; - } - set { - VerifyContainingType(field); - fields[field, index] = value; - } - } - - public override object this[FieldDescriptor field] { - get { - VerifyContainingType(field); - object result = fields[field]; - if (result == null) { - result = GetDefaultInstance(field.MessageType); - } - return result; - } - set { - VerifyContainingType(field); - fields[field] = value; - } - } - - public override Builder ClearField(FieldDescriptor field) { - VerifyContainingType(field); - fields.ClearField(field); - return this; - } - - public override int GetRepeatedFieldCount(FieldDescriptor field) { - VerifyContainingType(field); - return fields.GetRepeatedFieldCount(field); - } - - public override Builder AddRepeatedField(FieldDescriptor field, object value) { - VerifyContainingType(field); - fields.AddRepeatedField(field, value); - return this; - } - - public override UnknownFieldSet UnknownFields { - get { - return unknownFields; - } - set { - unknownFields = value; - } - } - - /// - /// Verifies that the field is a field of this message. - /// - /// - private void VerifyContainingType(FieldDescriptor field) { - if (field.ContainingType != type) { - throw new ArgumentException("FieldDescriptor does not match message 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 System.Collections.Generic; +using System.IO; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + /// + /// An implementation of IMessage that can represent arbitrary types, given a MessageaDescriptor. + /// + public sealed class DynamicMessage : AbstractMessage + { + private readonly MessageDescriptor type; + private readonly FieldSet fields; + private readonly UnknownFieldSet unknownFields; + private int memoizedSize = -1; + + /// + /// Creates a DynamicMessage with the given FieldSet. + /// + /// + /// + /// + private DynamicMessage(MessageDescriptor type, FieldSet fields, UnknownFieldSet unknownFields) + { + this.type = type; + this.fields = fields; + this.unknownFields = unknownFields; + } + + /// + /// Returns a DynamicMessage representing the default instance of the given type. + /// + /// + /// + public static DynamicMessage GetDefaultInstance(MessageDescriptor type) + { + return new DynamicMessage(type, FieldSet.DefaultInstance, UnknownFieldSet.DefaultInstance); + } + + /// + /// Parses a message of the given type from the given stream. + /// + public static DynamicMessage ParseFrom(MessageDescriptor type, CodedInputStream input) + { + Builder builder = CreateBuilder(type); + Builder dynamicBuilder = builder.MergeFrom(input); + return dynamicBuilder.BuildParsed(); + } + + /// + /// Parse a message of the given type from the given stream and extension registry. + /// + /// + /// + /// + /// + public static DynamicMessage ParseFrom(MessageDescriptor type, CodedInputStream input, + ExtensionRegistry extensionRegistry) + { + Builder builder = CreateBuilder(type); + Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry); + return dynamicBuilder.BuildParsed(); + } + + /// + /// Parses a message of the given type from the given stream. + /// + public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input) + { + Builder builder = CreateBuilder(type); + Builder dynamicBuilder = builder.MergeFrom(input); + return dynamicBuilder.BuildParsed(); + } + + /// + /// Parse a message of the given type from the given stream and extension registry. + /// + /// + /// + /// + /// + public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input, ExtensionRegistry extensionRegistry) + { + Builder builder = CreateBuilder(type); + Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry); + return dynamicBuilder.BuildParsed(); + } + + /// + /// Parse as a message of the given type and return it. + /// + public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data) + { + Builder builder = CreateBuilder(type); + Builder dynamicBuilder = builder.MergeFrom(data); + return dynamicBuilder.BuildParsed(); + } + + /// + /// Parse as a message of the given type and return it. + /// + public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data, + ExtensionRegistry extensionRegistry) + { + Builder builder = CreateBuilder(type); + Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry); + return dynamicBuilder.BuildParsed(); + } + + /// + /// Parse as a message of the given type and return it. + /// + public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data) + { + Builder builder = CreateBuilder(type); + Builder dynamicBuilder = builder.MergeFrom(data); + return dynamicBuilder.BuildParsed(); + } + + /// + /// Parse as a message of the given type and return it. + /// + public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data, ExtensionRegistry extensionRegistry) + { + Builder builder = CreateBuilder(type); + Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry); + return dynamicBuilder.BuildParsed(); + } + + /// + /// Constructs a builder for the given type. + /// + public static Builder CreateBuilder(MessageDescriptor type) + { + return new Builder(type); + } + + /// + /// Constructs a builder for a message of the same type as , + /// and initializes it with the same contents. + /// + /// + /// + public static Builder CreateBuilder(IMessage prototype) + { + return new Builder(prototype.DescriptorForType).MergeFrom(prototype); + } + + // ----------------------------------------------------------------- + // Implementation of IMessage interface. + + public override MessageDescriptor DescriptorForType + { + get { return type; } + } + + public override DynamicMessage DefaultInstanceForType + { + get { return GetDefaultInstance(type); } + } + + public override IDictionary AllFields + { + get { return fields.AllFieldDescriptors; } + } + + public override bool HasField(FieldDescriptor field) + { + VerifyContainingType(field); + return fields.HasField(field); + } + + public override object this[FieldDescriptor field] + { + get + { + VerifyContainingType(field); + object result = fields[field]; + if (result == null) + { + result = GetDefaultInstance(field.MessageType); + } + return result; + } + } + + public override int GetRepeatedFieldCount(FieldDescriptor field) + { + VerifyContainingType(field); + return fields.GetRepeatedFieldCount(field); + } + + public override object this[FieldDescriptor field, int index] + { + get + { + VerifyContainingType(field); + return fields[field, index]; + } + } + + public override UnknownFieldSet UnknownFields + { + get { return unknownFields; } + } + + public bool Initialized + { + get { return fields.IsInitializedWithRespectTo(type.Fields); } + } + + public override void WriteTo(CodedOutputStream output) + { + fields.WriteTo(output); + if (type.Options.MessageSetWireFormat) + { + unknownFields.WriteAsMessageSetTo(output); + } + else + { + unknownFields.WriteTo(output); + } + } + + public override int SerializedSize + { + get + { + int size = memoizedSize; + if (size != -1) return size; + + size = fields.SerializedSize; + if (type.Options.MessageSetWireFormat) + { + size += unknownFields.SerializedSizeAsMessageSet; + } + else + { + size += unknownFields.SerializedSize; + } + + memoizedSize = size; + return size; + } + } + + public override Builder CreateBuilderForType() + { + return new Builder(type); + } + + public override Builder ToBuilder() + { + return CreateBuilderForType().MergeFrom(this); + } + + /// + /// Verifies that the field is a field of this message. + /// + private void VerifyContainingType(FieldDescriptor field) + { + if (field.ContainingType != type) + { + throw new ArgumentException("FieldDescriptor does not match message type."); + } + } + + /// + /// Builder for dynamic messages. Instances are created with DynamicMessage.CreateBuilder. + /// + public sealed class Builder : AbstractBuilder + { + private readonly MessageDescriptor type; + private FieldSet fields; + private UnknownFieldSet unknownFields; + + internal Builder(MessageDescriptor type) + { + this.type = type; + this.fields = FieldSet.CreateInstance(); + this.unknownFields = UnknownFieldSet.DefaultInstance; + } + + protected override Builder ThisBuilder + { + get { return this; } + } + + public override Builder Clear() + { + fields.Clear(); + return this; + } + + public override Builder MergeFrom(IMessage other) + { + if (other.DescriptorForType != type) + { + throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type."); + } + fields.MergeFrom(other); + MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(DynamicMessage other) + { + IMessage downcast = other; + return MergeFrom(downcast); + } + + public override DynamicMessage Build() + { + if (fields != null && !IsInitialized) + { + throw new UninitializedMessageException(new DynamicMessage(type, fields, unknownFields)); + } + return BuildPartial(); + } + + /// + /// Helper for DynamicMessage.ParseFrom() methods to call. Throws + /// InvalidProtocolBufferException + /// + /// + internal DynamicMessage BuildParsed() + { + if (!IsInitialized) + { + throw new UninitializedMessageException(new DynamicMessage(type, fields, unknownFields)). + AsInvalidProtocolBufferException(); + } + return BuildPartial(); + } + + public override DynamicMessage BuildPartial() + { + if (fields == null) + { + throw new InvalidOperationException("Build() has already been called on this Builder."); + } + fields.MakeImmutable(); + DynamicMessage result = new DynamicMessage(type, fields, unknownFields); + fields = null; + unknownFields = null; + return result; + } + + public override Builder Clone() + { + Builder result = new Builder(type); + result.fields.MergeFrom(fields); + return result; + } + + public override bool IsInitialized + { + get { return fields.IsInitializedWithRespectTo(type.Fields); } + } + + public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) + { + UnknownFieldSet.Builder unknownFieldsBuilder = UnknownFieldSet.CreateBuilder(unknownFields); + unknownFieldsBuilder.MergeFrom(input, extensionRegistry, this); + unknownFields = unknownFieldsBuilder.Build(); + return this; + } + + public override MessageDescriptor DescriptorForType + { + get { return type; } + } + + public override DynamicMessage DefaultInstanceForType + { + get { return GetDefaultInstance(type); } + } + + public override IDictionary AllFields + { + get { return fields.AllFieldDescriptors; } + } + + public override IBuilder CreateBuilderForField(FieldDescriptor field) + { + VerifyContainingType(field); + if (field.MappedType != MappedType.Message) + { + throw new ArgumentException("CreateBuilderForField is only valid for fields with message type."); + } + return new Builder(field.MessageType); + } + + public override bool HasField(FieldDescriptor field) + { + VerifyContainingType(field); + return fields.HasField(field); + } + + public override object this[FieldDescriptor field, int index] + { + get + { + VerifyContainingType(field); + return fields[field, index]; + } + set + { + VerifyContainingType(field); + fields[field, index] = value; + } + } + + public override object this[FieldDescriptor field] + { + get + { + VerifyContainingType(field); + object result = fields[field]; + if (result == null) + { + result = GetDefaultInstance(field.MessageType); + } + return result; + } + set + { + VerifyContainingType(field); + fields[field] = value; + } + } + + public override Builder ClearField(FieldDescriptor field) + { + VerifyContainingType(field); + fields.ClearField(field); + return this; + } + + public override int GetRepeatedFieldCount(FieldDescriptor field) + { + VerifyContainingType(field); + return fields.GetRepeatedFieldCount(field); + } + + public override Builder AddRepeatedField(FieldDescriptor field, object value) + { + VerifyContainingType(field); + fields.AddRepeatedField(field, value); + return this; + } + + public override UnknownFieldSet UnknownFields + { + get { return unknownFields; } + set { unknownFields = value; } + } + + /// + /// Verifies that the field is a field of this message. + /// + /// + private void VerifyContainingType(FieldDescriptor field) + { + if (field.ContainingType != type) + { + throw new ArgumentException("FieldDescriptor does not match message type."); + } + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/EnumLite.cs b/src/ProtocolBuffers/EnumLite.cs index 3776297f..4c2f8b75 100644 --- a/src/ProtocolBuffers/EnumLite.cs +++ b/src/ProtocolBuffers/EnumLite.cs @@ -1,116 +1,133 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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.Reflection; -using System.Text; - -namespace Google.ProtocolBuffers { - - /// - ///Interface for an enum value or value descriptor, to be used in FieldSet. - ///The lite library stores enum values directly in FieldSets but the full - ///library stores EnumValueDescriptors in order to better support reflection. - /// - public interface IEnumLite { - int Number { get; } - string Name { get; } - } - - /// - ///Interface for an object which maps integers to {@link EnumLite}s. - ///{@link Descriptors.EnumDescriptor} implements this interface by mapping - ///numbers to {@link Descriptors.EnumValueDescriptor}s. Additionally, - ///every generated enum type has a static method internalGetValueMap() which - ///returns an implementation of this type that maps numbers to enum values. - /// - public interface IEnumLiteMap : IEnumLiteMap - where T : IEnumLite { - new T FindValueByNumber(int number); - } - - public interface IEnumLiteMap { - bool IsValidValue(IEnumLite value); - IEnumLite FindValueByNumber(int number); - } - - public class EnumLiteMap : IEnumLiteMap - where TEnum : struct, IComparable, IFormattable { - - struct EnumValue : IEnumLite { - readonly TEnum value; - public EnumValue(TEnum value) { - this.value = value; - } - int IEnumLite.Number { - get { return Convert.ToInt32(value); } - } - string IEnumLite.Name { - get { return value.ToString(); } - } - } - - private readonly SortedList items; - - public EnumLiteMap() { - items = new SortedList(); -#if SILVERLIGHT2 - // Silverlight doesn't support Enum.GetValues - // TODO(jonskeet): Validate that this reflection is permitted, e.g. in Windows Phone 7 - foreach (FieldInfo fi in typeof(TEnum).GetFields(BindingFlags.Static | BindingFlags.Public)) { - TEnum evalue = (TEnum) fi.GetValue(null); - items.Add(Convert.ToInt32(evalue), new EnumValue(evalue)); - } -#else - foreach (TEnum evalue in Enum.GetValues(typeof(TEnum))) - items.Add(Convert.ToInt32(evalue), new EnumValue(evalue)); -#endif - } - - IEnumLite IEnumLiteMap.FindValueByNumber(int number) { - return FindValueByNumber(number); - } - - public IEnumLite FindValueByNumber(int number) { - IEnumLite val; - return items.TryGetValue(number, out val) ? val : null; - } - - public bool IsValidValue(IEnumLite value) { - return items.ContainsKey(value.Number); - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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.Reflection; +using System.Text; + +namespace Google.ProtocolBuffers +{ + /// + ///Interface for an enum value or value descriptor, to be used in FieldSet. + ///The lite library stores enum values directly in FieldSets but the full + ///library stores EnumValueDescriptors in order to better support reflection. + /// + public interface IEnumLite + { + int Number { get; } + string Name { get; } + } + + /// + ///Interface for an object which maps integers to {@link EnumLite}s. + ///{@link Descriptors.EnumDescriptor} implements this interface by mapping + ///numbers to {@link Descriptors.EnumValueDescriptor}s. Additionally, + ///every generated enum type has a static method internalGetValueMap() which + ///returns an implementation of this type that maps numbers to enum values. + /// + public interface IEnumLiteMap : IEnumLiteMap + where T : IEnumLite + { + new T FindValueByNumber(int number); + } + + public interface IEnumLiteMap + { + bool IsValidValue(IEnumLite value); + IEnumLite FindValueByNumber(int number); + } + + public class EnumLiteMap : IEnumLiteMap + where TEnum : struct, IComparable, IFormattable + { + private struct EnumValue : IEnumLite + { + private readonly TEnum value; + + public EnumValue(TEnum value) + { + this.value = value; + } + + int IEnumLite.Number + { + get { return Convert.ToInt32(value); } + } + + string IEnumLite.Name + { + get { return value.ToString(); } + } + } + + private readonly SortedList items; + + public EnumLiteMap() + { + items = new SortedList(); +#if SILVERLIGHT2 + // Silverlight doesn't support Enum.GetValues + // TODO(jonskeet): Validate that this reflection is permitted, e.g. in Windows Phone 7 + foreach (FieldInfo fi in typeof (TEnum).GetFields(BindingFlags.Static | BindingFlags.Public)) + { + TEnum evalue = (TEnum) fi.GetValue(null); + items.Add(Convert.ToInt32(evalue), new EnumValue(evalue)); + } +#else + foreach (TEnum evalue in Enum.GetValues(typeof(TEnum))) + items.Add(Convert.ToInt32(evalue), new EnumValue(evalue)); +#endif + } + + IEnumLite IEnumLiteMap.FindValueByNumber(int number) + { + return FindValueByNumber(number); + } + + public IEnumLite FindValueByNumber(int number) + { + IEnumLite val; + return items.TryGetValue(number, out val) ? val : null; + } + + public bool IsValidValue(IEnumLite value) + { + return items.ContainsKey(value.Number); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/ExtendableBuilder.cs b/src/ProtocolBuffers/ExtendableBuilder.cs index ad97cdc4..532520ed 100644 --- a/src/ProtocolBuffers/ExtendableBuilder.cs +++ b/src/ProtocolBuffers/ExtendableBuilder.cs @@ -1,179 +1,213 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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 { - public abstract class ExtendableBuilder : GeneratedBuilder - where TMessage : ExtendableMessage - where TBuilder : GeneratedBuilder { - - protected ExtendableBuilder() {} - - /// - /// Checks if a singular extension is present - /// - public bool HasExtension(GeneratedExtensionBase extension) { - return MessageBeingBuilt.HasExtension(extension); - } - - /// - /// Returns the number of elements in a repeated extension. - /// - public int GetExtensionCount(GeneratedExtensionBase> extension) { - return MessageBeingBuilt.GetExtensionCount(extension); - } - - /// - /// Returns the value of an extension. - /// - public TExtension GetExtension(GeneratedExtensionBase extension) { - return MessageBeingBuilt.GetExtension(extension); - } - - /// - /// Returns one element of a repeated extension. - /// - public TExtension GetExtension(GeneratedExtensionBase> extension, int index) { - return MessageBeingBuilt.GetExtension(extension, index); - } - - /// - /// Sets the value of an extension. - /// - public TBuilder SetExtension(GeneratedExtensionBase extension, TExtension value) { - ExtendableMessage message = MessageBeingBuilt; - message.VerifyExtensionContainingType(extension); - message.Extensions[extension.Descriptor] = extension.ToReflectionType(value); - return ThisBuilder; - } - - /// - /// Sets the value of one element of a repeated extension. - /// - public TBuilder SetExtension(GeneratedExtensionBase> extension, int index, TExtension value) { - ExtendableMessage message = MessageBeingBuilt; - message.VerifyExtensionContainingType(extension); - message.Extensions[extension.Descriptor, index] = extension.SingularToReflectionType(value); - return ThisBuilder; - } - - /// - /// Appends a value to a repeated extension. - /// - public TBuilder AddExtension(GeneratedExtensionBase> extension, TExtension value) { - ExtendableMessage message = MessageBeingBuilt; - message.VerifyExtensionContainingType(extension); - message.Extensions.AddRepeatedField(extension.Descriptor, extension.SingularToReflectionType(value)); - return ThisBuilder; - } - - /// - /// Clears an extension. - /// - public TBuilder ClearExtension(GeneratedExtensionBase extension) { - ExtendableMessage message = MessageBeingBuilt; - message.VerifyExtensionContainingType(extension); - message.Extensions.ClearField(extension.Descriptor); - return ThisBuilder; - } - - /// - /// Called by subclasses to parse an unknown field or an extension. - /// - /// true unless the tag is an end-group tag - [CLSCompliant(false)] - protected override bool ParseUnknownField(CodedInputStream input, UnknownFieldSet.Builder unknownFields, - ExtensionRegistry extensionRegistry, uint tag) { - return unknownFields.MergeFieldFrom(input, extensionRegistry, this, tag); - } - - // --------------------------------------------------------------- - // Reflection - - - public override object this[FieldDescriptor field, int index] { - set { - if (field.IsExtension) { - ExtendableMessage message = MessageBeingBuilt; - message.VerifyContainingType(field); - message.Extensions[field, index] = value; - } else { - base[field, index] = value; - } - } - } - - - public override object this[FieldDescriptor field] { - set { - if (field.IsExtension) { - ExtendableMessage message = MessageBeingBuilt; - message.VerifyContainingType(field); - message.Extensions[field] = value; - } else { - base[field] = value; - } - } - } - - public override TBuilder ClearField(FieldDescriptor field) { - if (field.IsExtension) { - ExtendableMessage message = MessageBeingBuilt; - message.VerifyContainingType(field); - message.Extensions.ClearField(field); - return ThisBuilder; - } else { - return base.ClearField(field); - } - } - - public override TBuilder AddRepeatedField(FieldDescriptor field, object value) { - if (field.IsExtension) { - ExtendableMessage message = MessageBeingBuilt; - message.VerifyContainingType(field); - message.Extensions.AddRepeatedField(field, value); - return ThisBuilder; - } else { - return base.AddRepeatedField(field, value); - } - } - - protected void MergeExtensionFields(ExtendableMessage other) { - MessageBeingBuilt.Extensions.MergeFrom(other.Extensions); - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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 +{ + public abstract class ExtendableBuilder : GeneratedBuilder + where TMessage : ExtendableMessage + where TBuilder : GeneratedBuilder + { + protected ExtendableBuilder() + { + } + + /// + /// Checks if a singular extension is present + /// + public bool HasExtension(GeneratedExtensionBase extension) + { + return MessageBeingBuilt.HasExtension(extension); + } + + /// + /// Returns the number of elements in a repeated extension. + /// + public int GetExtensionCount(GeneratedExtensionBase> extension) + { + return MessageBeingBuilt.GetExtensionCount(extension); + } + + /// + /// Returns the value of an extension. + /// + public TExtension GetExtension(GeneratedExtensionBase extension) + { + return MessageBeingBuilt.GetExtension(extension); + } + + /// + /// Returns one element of a repeated extension. + /// + public TExtension GetExtension(GeneratedExtensionBase> extension, int index) + { + return MessageBeingBuilt.GetExtension(extension, index); + } + + /// + /// Sets the value of an extension. + /// + public TBuilder SetExtension(GeneratedExtensionBase extension, TExtension value) + { + ExtendableMessage message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions[extension.Descriptor] = extension.ToReflectionType(value); + return ThisBuilder; + } + + /// + /// Sets the value of one element of a repeated extension. + /// + public TBuilder SetExtension(GeneratedExtensionBase> extension, int index, + TExtension value) + { + ExtendableMessage message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions[extension.Descriptor, index] = extension.SingularToReflectionType(value); + return ThisBuilder; + } + + /// + /// Appends a value to a repeated extension. + /// + public TBuilder AddExtension(GeneratedExtensionBase> extension, TExtension value) + { + ExtendableMessage message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions.AddRepeatedField(extension.Descriptor, extension.SingularToReflectionType(value)); + return ThisBuilder; + } + + /// + /// Clears an extension. + /// + public TBuilder ClearExtension(GeneratedExtensionBase extension) + { + ExtendableMessage message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions.ClearField(extension.Descriptor); + return ThisBuilder; + } + + /// + /// Called by subclasses to parse an unknown field or an extension. + /// + /// true unless the tag is an end-group tag + [CLSCompliant(false)] + protected override bool ParseUnknownField(CodedInputStream input, UnknownFieldSet.Builder unknownFields, + ExtensionRegistry extensionRegistry, uint tag) + { + return unknownFields.MergeFieldFrom(input, extensionRegistry, this, tag); + } + + // --------------------------------------------------------------- + // Reflection + + + public override object this[FieldDescriptor field, int index] + { + set + { + if (field.IsExtension) + { + ExtendableMessage message = MessageBeingBuilt; + message.VerifyContainingType(field); + message.Extensions[field, index] = value; + } + else + { + base[field, index] = value; + } + } + } + + + public override object this[FieldDescriptor field] + { + set + { + if (field.IsExtension) + { + ExtendableMessage message = MessageBeingBuilt; + message.VerifyContainingType(field); + message.Extensions[field] = value; + } + else + { + base[field] = value; + } + } + } + + public override TBuilder ClearField(FieldDescriptor field) + { + if (field.IsExtension) + { + ExtendableMessage message = MessageBeingBuilt; + message.VerifyContainingType(field); + message.Extensions.ClearField(field); + return ThisBuilder; + } + else + { + return base.ClearField(field); + } + } + + public override TBuilder AddRepeatedField(FieldDescriptor field, object value) + { + if (field.IsExtension) + { + ExtendableMessage message = MessageBeingBuilt; + message.VerifyContainingType(field); + message.Extensions.AddRepeatedField(field, value); + return ThisBuilder; + } + else + { + return base.AddRepeatedField(field, value); + } + } + + protected void MergeExtensionFields(ExtendableMessage other) + { + MessageBeingBuilt.Extensions.MergeFrom(other.Extensions); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/ExtendableBuilderLite.cs b/src/ProtocolBuffers/ExtendableBuilderLite.cs index b3d37eda..944b246b 100644 --- a/src/ProtocolBuffers/ExtendableBuilderLite.cs +++ b/src/ProtocolBuffers/ExtendableBuilderLite.cs @@ -1,262 +1,332 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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 { - public abstract class ExtendableBuilderLite : GeneratedBuilderLite - where TMessage : ExtendableMessageLite - where TBuilder : GeneratedBuilderLite { - - protected ExtendableBuilderLite() { } - - /// - /// Checks if a singular extension is present - /// - public bool HasExtension(GeneratedExtensionLite extension) { - return MessageBeingBuilt.HasExtension(extension); - } - - /// - /// Returns the number of elements in a repeated extension. - /// - public int GetExtensionCount(GeneratedExtensionLite> extension) { - return MessageBeingBuilt.GetExtensionCount(extension); - } - - /// - /// Returns the value of an extension. - /// - public TExtension GetExtension(GeneratedExtensionLite extension) { - return MessageBeingBuilt.GetExtension(extension); - } - - /// - /// Returns one element of a repeated extension. - /// - public TExtension GetExtension(GeneratedExtensionLite> extension, int index) { - return MessageBeingBuilt.GetExtension(extension, index); - } - - /// - /// Sets the value of an extension. - /// - public TBuilder SetExtension(GeneratedExtensionLite extension, TExtension value) { - ExtendableMessageLite message = MessageBeingBuilt; - message.VerifyExtensionContainingType(extension); - message.Extensions[extension.Descriptor] = extension.ToReflectionType(value); - return ThisBuilder; - } - - /// - /// Sets the value of one element of a repeated extension. - /// - public TBuilder SetExtension(GeneratedExtensionLite> extension, int index, TExtension value) { - ExtendableMessageLite message = MessageBeingBuilt; - message.VerifyExtensionContainingType(extension); - message.Extensions[extension.Descriptor, index] = extension.SingularToReflectionType(value); - return ThisBuilder; - } - - /// - /// Appends a value to a repeated extension. - /// - public TBuilder AddExtension(GeneratedExtensionLite> extension, TExtension value) { - ExtendableMessageLite message = MessageBeingBuilt; - message.VerifyExtensionContainingType(extension); - message.Extensions.AddRepeatedField(extension.Descriptor, extension.SingularToReflectionType(value)); - return ThisBuilder; - } - - /// - /// Clears an extension. - /// - public TBuilder ClearExtension(GeneratedExtensionLite extension) { - ExtendableMessageLite message = MessageBeingBuilt; - message.VerifyExtensionContainingType(extension); - message.Extensions.ClearField(extension.Descriptor); - return ThisBuilder; - } - - /// - /// Called by subclasses to parse an unknown field or an extension. - /// - /// true unless the tag is an end-group tag - [CLSCompliant(false)] - protected override bool ParseUnknownField(CodedInputStream input, - ExtensionRegistry extensionRegistry, uint tag) { - FieldSet extensions = MessageBeingBuilt.Extensions; - - WireFormat.WireType wireType = WireFormat.GetTagWireType(tag); - int fieldNumber = WireFormat.GetTagFieldNumber(tag); - IGeneratedExtensionLite extension = extensionRegistry[DefaultInstanceForType, fieldNumber]; - - bool unknown = false; - bool packed = false; - if (extension == null) { - unknown = true; // Unknown field. - } else if (wireType == FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, false /* isPacked */)) { - packed = false; // Normal, unpacked value. - } else if (extension.Descriptor.IsRepeated && - //?? just returns true ?? extension.Descriptor.type.isPackable() && - wireType == FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, true /* isPacked */)) { - packed = true; // Packed value. - } else { - unknown = true; // Wrong wire type. - } - - if (unknown) { // Unknown field or wrong wire type. Skip. - return input.SkipField(tag); - } - - if (packed) { - int length = (int)Math.Min(int.MaxValue, input.ReadRawVarint32()); - int limit = input.PushLimit(length); - if (extension.Descriptor.FieldType == FieldType.Enum) { - while (!input.ReachedLimit) { - int rawValue = input.ReadEnum(); - Object value = - extension.Descriptor.EnumType.FindValueByNumber(rawValue); - if (value == null) { - // If the number isn't recognized as a valid value for this - // enum, drop it (don't even add it to unknownFields). - return true; - } - extensions.AddRepeatedField(extension.Descriptor, value); - } - } else { - while (!input.ReachedLimit) { - Object value = input.ReadPrimitiveField(extension.Descriptor.FieldType); - extensions.AddRepeatedField(extension.Descriptor, value); - } - } - input.PopLimit(limit); - } else { - Object value; - switch (extension.Descriptor.MappedType) { - case MappedType.Message: { - IBuilderLite subBuilder = null; - if (!extension.Descriptor.IsRepeated) { - IMessageLite existingValue = extensions[extension.Descriptor] as IMessageLite; - if (existingValue != null) { - subBuilder = existingValue.WeakToBuilder(); - } - } - if (subBuilder == null) { - subBuilder = extension.MessageDefaultInstance.WeakCreateBuilderForType(); - } - if (extension.Descriptor.FieldType == FieldType.Group) { - input.ReadGroup(extension.Number, subBuilder, extensionRegistry); - } else { - input.ReadMessage(subBuilder, extensionRegistry); - } - value = subBuilder.WeakBuild(); - break; - } - case MappedType.Enum: - int rawValue = input.ReadEnum(); - value = extension.Descriptor.EnumType.FindValueByNumber(rawValue); - // If the number isn't recognized as a valid value for this enum, - // drop it. - if (value == null) { - return true; - } - break; - default: - value = input.ReadPrimitiveField(extension.Descriptor.FieldType); - break; - } - - if (extension.Descriptor.IsRepeated) { - extensions.AddRepeatedField(extension.Descriptor, value); - } else { - extensions[extension.Descriptor] = value; - } - } - - return true; - } - - #region Reflection - - public object this[IFieldDescriptorLite field, int index] { - set { - if (field.IsExtension) { - ExtendableMessageLite message = MessageBeingBuilt; - message.Extensions[field, index] = value; - } else { - throw new NotSupportedException("Not supported in the lite runtime."); - } - } - } - - public object this[IFieldDescriptorLite field] { - set { - if (field.IsExtension) { - ExtendableMessageLite message = MessageBeingBuilt; - message.Extensions[field] = value; - } else { - throw new NotSupportedException("Not supported in the lite runtime."); - } - } - } - - public TBuilder ClearField(IFieldDescriptorLite field) { - if (field.IsExtension) { - ExtendableMessageLite message = MessageBeingBuilt; - message.Extensions.ClearField(field); - return ThisBuilder; - } else { - throw new NotSupportedException("Not supported in the lite runtime."); - } - } - - public TBuilder AddRepeatedField(IFieldDescriptorLite field, object value) { - if (field.IsExtension) { - ExtendableMessageLite message = MessageBeingBuilt; - message.Extensions.AddRepeatedField(field, value); - return ThisBuilder; - } else { - throw new NotSupportedException("Not supported in the lite runtime."); - } - } - - protected void MergeExtensionFields(ExtendableMessageLite other) { - MessageBeingBuilt.Extensions.MergeFrom(other.Extensions); - } - #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 Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + public abstract class ExtendableBuilderLite : GeneratedBuilderLite + where TMessage : ExtendableMessageLite + where TBuilder : GeneratedBuilderLite + { + protected ExtendableBuilderLite() + { + } + + /// + /// Checks if a singular extension is present + /// + public bool HasExtension(GeneratedExtensionLite extension) + { + return MessageBeingBuilt.HasExtension(extension); + } + + /// + /// Returns the number of elements in a repeated extension. + /// + public int GetExtensionCount(GeneratedExtensionLite> extension) + { + return MessageBeingBuilt.GetExtensionCount(extension); + } + + /// + /// Returns the value of an extension. + /// + public TExtension GetExtension(GeneratedExtensionLite extension) + { + return MessageBeingBuilt.GetExtension(extension); + } + + /// + /// Returns one element of a repeated extension. + /// + public TExtension GetExtension(GeneratedExtensionLite> extension, + int index) + { + return MessageBeingBuilt.GetExtension(extension, index); + } + + /// + /// Sets the value of an extension. + /// + public TBuilder SetExtension(GeneratedExtensionLite extension, + TExtension value) + { + ExtendableMessageLite message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions[extension.Descriptor] = extension.ToReflectionType(value); + return ThisBuilder; + } + + /// + /// Sets the value of one element of a repeated extension. + /// + public TBuilder SetExtension(GeneratedExtensionLite> extension, + int index, TExtension value) + { + ExtendableMessageLite message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions[extension.Descriptor, index] = extension.SingularToReflectionType(value); + return ThisBuilder; + } + + /// + /// Appends a value to a repeated extension. + /// + public TBuilder AddExtension(GeneratedExtensionLite> extension, + TExtension value) + { + ExtendableMessageLite message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions.AddRepeatedField(extension.Descriptor, extension.SingularToReflectionType(value)); + return ThisBuilder; + } + + /// + /// Clears an extension. + /// + public TBuilder ClearExtension(GeneratedExtensionLite extension) + { + ExtendableMessageLite message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions.ClearField(extension.Descriptor); + return ThisBuilder; + } + + /// + /// Called by subclasses to parse an unknown field or an extension. + /// + /// true unless the tag is an end-group tag + [CLSCompliant(false)] + protected override bool ParseUnknownField(CodedInputStream input, + ExtensionRegistry extensionRegistry, uint tag) + { + FieldSet extensions = MessageBeingBuilt.Extensions; + + WireFormat.WireType wireType = WireFormat.GetTagWireType(tag); + int fieldNumber = WireFormat.GetTagFieldNumber(tag); + IGeneratedExtensionLite extension = extensionRegistry[DefaultInstanceForType, fieldNumber]; + + bool unknown = false; + bool packed = false; + if (extension == null) + { + unknown = true; // Unknown field. + } + else if (wireType == + FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, false /* isPacked */)) + { + packed = false; // Normal, unpacked value. + } + else if (extension.Descriptor.IsRepeated && + //?? just returns true ?? extension.Descriptor.type.isPackable() && + wireType == + FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, true /* isPacked */)) + { + packed = true; // Packed value. + } + else + { + unknown = true; // Wrong wire type. + } + + if (unknown) + { + // Unknown field or wrong wire type. Skip. + return input.SkipField(tag); + } + + if (packed) + { + int length = (int) Math.Min(int.MaxValue, input.ReadRawVarint32()); + int limit = input.PushLimit(length); + if (extension.Descriptor.FieldType == FieldType.Enum) + { + while (!input.ReachedLimit) + { + int rawValue = input.ReadEnum(); + Object value = + extension.Descriptor.EnumType.FindValueByNumber(rawValue); + if (value == null) + { + // If the number isn't recognized as a valid value for this + // enum, drop it (don't even add it to unknownFields). + return true; + } + extensions.AddRepeatedField(extension.Descriptor, value); + } + } + else + { + while (!input.ReachedLimit) + { + Object value = input.ReadPrimitiveField(extension.Descriptor.FieldType); + extensions.AddRepeatedField(extension.Descriptor, value); + } + } + input.PopLimit(limit); + } + else + { + Object value; + switch (extension.Descriptor.MappedType) + { + case MappedType.Message: + { + IBuilderLite subBuilder = null; + if (!extension.Descriptor.IsRepeated) + { + IMessageLite existingValue = extensions[extension.Descriptor] as IMessageLite; + if (existingValue != null) + { + subBuilder = existingValue.WeakToBuilder(); + } + } + if (subBuilder == null) + { + subBuilder = extension.MessageDefaultInstance.WeakCreateBuilderForType(); + } + if (extension.Descriptor.FieldType == FieldType.Group) + { + input.ReadGroup(extension.Number, subBuilder, extensionRegistry); + } + else + { + input.ReadMessage(subBuilder, extensionRegistry); + } + value = subBuilder.WeakBuild(); + break; + } + case MappedType.Enum: + int rawValue = input.ReadEnum(); + value = extension.Descriptor.EnumType.FindValueByNumber(rawValue); + // If the number isn't recognized as a valid value for this enum, + // drop it. + if (value == null) + { + return true; + } + break; + default: + value = input.ReadPrimitiveField(extension.Descriptor.FieldType); + break; + } + + if (extension.Descriptor.IsRepeated) + { + extensions.AddRepeatedField(extension.Descriptor, value); + } + else + { + extensions[extension.Descriptor] = value; + } + } + + return true; + } + + #region Reflection + + public object this[IFieldDescriptorLite field, int index] + { + set + { + if (field.IsExtension) + { + ExtendableMessageLite message = MessageBeingBuilt; + message.Extensions[field, index] = value; + } + else + { + throw new NotSupportedException("Not supported in the lite runtime."); + } + } + } + + public object this[IFieldDescriptorLite field] + { + set + { + if (field.IsExtension) + { + ExtendableMessageLite message = MessageBeingBuilt; + message.Extensions[field] = value; + } + else + { + throw new NotSupportedException("Not supported in the lite runtime."); + } + } + } + + public TBuilder ClearField(IFieldDescriptorLite field) + { + if (field.IsExtension) + { + ExtendableMessageLite message = MessageBeingBuilt; + message.Extensions.ClearField(field); + return ThisBuilder; + } + else + { + throw new NotSupportedException("Not supported in the lite runtime."); + } + } + + public TBuilder AddRepeatedField(IFieldDescriptorLite field, object value) + { + if (field.IsExtension) + { + ExtendableMessageLite message = MessageBeingBuilt; + message.Extensions.AddRepeatedField(field, value); + return ThisBuilder; + } + else + { + throw new NotSupportedException("Not supported in the lite runtime."); + } + } + + protected void MergeExtensionFields(ExtendableMessageLite other) + { + MessageBeingBuilt.Extensions.MergeFrom(other.Extensions); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/ExtendableMessage.cs b/src/ProtocolBuffers/ExtendableMessage.cs index c67b5a1d..7e988c49 100644 --- a/src/ProtocolBuffers/ExtendableMessage.cs +++ b/src/ProtocolBuffers/ExtendableMessage.cs @@ -1,219 +1,274 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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.Descriptors; - -namespace Google.ProtocolBuffers { - public abstract class ExtendableMessage : GeneratedMessage - where TMessage : GeneratedMessage - where TBuilder : GeneratedBuilder { - - protected ExtendableMessage() {} - private readonly FieldSet extensions = FieldSet.CreateInstance(); - - /// - /// Access for the builder. - /// - internal FieldSet Extensions { - get { return extensions; } - } - - /// - /// Checks if a singular extension is present. - /// - public bool HasExtension(GeneratedExtensionBase extension) { - return extensions.HasField(extension.Descriptor); - } - - /// - /// Returns the number of elements in a repeated extension. - /// - public int GetExtensionCount(GeneratedExtensionBase> extension) { - return extensions.GetRepeatedFieldCount(extension.Descriptor); - } - - /// - /// Returns the value of an extension. - /// - public TExtension GetExtension(GeneratedExtensionBase extension) { - object value = extensions[extension.Descriptor]; - if (value == null) { - return (TExtension) extension.MessageDefaultInstance; - } else { - return (TExtension) extension.FromReflectionType(value); - } - } - - /// - /// Returns one element of a repeated extension. - /// - public TExtension GetExtension(GeneratedExtensionBase> extension, int index) { - return (TExtension) extension.SingularFromReflectionType(extensions[extension.Descriptor, index]); - } - - /// - /// Called to check if all extensions are initialized. - /// - protected bool ExtensionsAreInitialized { - get { return extensions.IsInitialized; } - } - - public override bool IsInitialized { - get { - return base.IsInitialized && ExtensionsAreInitialized; - } - } - - #region Reflection - public override IDictionary AllFields { - get { - IDictionary result = GetMutableFieldMap(); - foreach(KeyValuePair entry in extensions.AllFields) { - result[(FieldDescriptor)entry.Key] = entry.Value; - } - return Dictionaries.AsReadOnly(result); - } - } - - public override bool HasField(FieldDescriptor field) { - if (field.IsExtension) { - VerifyContainingType(field); - return extensions.HasField(field); - } else { - return base.HasField(field); - } - } - - public override object this[FieldDescriptor field] { - get { - if (field.IsExtension) { - VerifyContainingType(field); - object value = extensions[field]; - if (value == null) { - // Lacking an ExtensionRegistry, we have no way to determine the - // extension's real type, so we return a DynamicMessage. - // TODO(jonskeet): Work out what this means - return DynamicMessage.GetDefaultInstance(field.MessageType); - } else { - return value; - } - } else { - return base[field]; - } - } - } - - public override int GetRepeatedFieldCount(FieldDescriptor field) { - if (field.IsExtension) { - VerifyContainingType(field); - return extensions.GetRepeatedFieldCount(field); - } else { - return base.GetRepeatedFieldCount(field); - } - } - - public override object this[FieldDescriptor field, int index] { - get { - if (field.IsExtension) { - VerifyContainingType(field); - return extensions[field, index]; - } else { - return base[field, index]; - } - } - } - - internal void VerifyContainingType(FieldDescriptor field) { - if (field.ContainingType != DescriptorForType) { - throw new ArgumentException("FieldDescriptor does not match message type."); - } - } - #endregion - - /// - /// Used by subclasses to serialize extensions. Extension ranges may be - /// interleaves with field numbers, but we must write them in canonical - /// (sorted by field number) order. This class helps us to write individual - /// ranges of extensions at once. - /// - /// TODO(jonskeet): See if we can improve this in terms of readability. - /// - protected class ExtensionWriter { - readonly IEnumerator> iterator; - readonly FieldSet extensions; - KeyValuePair? next = null; - - internal ExtensionWriter(ExtendableMessage message) { - extensions = message.extensions; - iterator = message.extensions.GetEnumerator(); - if (iterator.MoveNext()) { - next = iterator.Current; - } - } - - public void WriteUntil(int end, CodedOutputStream output) { - while (next != null && next.Value.Key.FieldNumber < end) { - extensions.WriteField(next.Value.Key, next.Value.Value, output); - if (iterator.MoveNext()) { - next = iterator.Current; - } else { - next = null; - } - } - } - } - - protected ExtensionWriter CreateExtensionWriter(ExtendableMessage message) { - return new ExtensionWriter(message); - } - - /// - /// Called by subclasses to compute the size of extensions. - /// - protected int ExtensionsSerializedSize { - get { return extensions.SerializedSize; } - } - - internal void VerifyExtensionContainingType(GeneratedExtensionBase extension) { - if (extension.Descriptor.ContainingType != DescriptorForType) { - // This can only happen if someone uses unchecked operations. - throw new ArgumentException("Extension is for type \"" + extension.Descriptor.ContainingType.FullName - + "\" which does not match message type \"" + DescriptorForType.FullName + "\"."); - } - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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.Descriptors; + +namespace Google.ProtocolBuffers +{ + public abstract class ExtendableMessage : GeneratedMessage + where TMessage : GeneratedMessage + where TBuilder : GeneratedBuilder + { + protected ExtendableMessage() + { + } + + private readonly FieldSet extensions = FieldSet.CreateInstance(); + + /// + /// Access for the builder. + /// + internal FieldSet Extensions + { + get { return extensions; } + } + + /// + /// Checks if a singular extension is present. + /// + public bool HasExtension(GeneratedExtensionBase extension) + { + return extensions.HasField(extension.Descriptor); + } + + /// + /// Returns the number of elements in a repeated extension. + /// + public int GetExtensionCount(GeneratedExtensionBase> extension) + { + return extensions.GetRepeatedFieldCount(extension.Descriptor); + } + + /// + /// Returns the value of an extension. + /// + public TExtension GetExtension(GeneratedExtensionBase extension) + { + object value = extensions[extension.Descriptor]; + if (value == null) + { + return (TExtension) extension.MessageDefaultInstance; + } + else + { + return (TExtension) extension.FromReflectionType(value); + } + } + + /// + /// Returns one element of a repeated extension. + /// + public TExtension GetExtension(GeneratedExtensionBase> extension, int index) + { + return (TExtension) extension.SingularFromReflectionType(extensions[extension.Descriptor, index]); + } + + /// + /// Called to check if all extensions are initialized. + /// + protected bool ExtensionsAreInitialized + { + get { return extensions.IsInitialized; } + } + + public override bool IsInitialized + { + get { return base.IsInitialized && ExtensionsAreInitialized; } + } + + #region Reflection + + public override IDictionary AllFields + { + get + { + IDictionary result = GetMutableFieldMap(); + foreach (KeyValuePair entry in extensions.AllFields) + { + result[(FieldDescriptor) entry.Key] = entry.Value; + } + return Dictionaries.AsReadOnly(result); + } + } + + public override bool HasField(FieldDescriptor field) + { + if (field.IsExtension) + { + VerifyContainingType(field); + return extensions.HasField(field); + } + else + { + return base.HasField(field); + } + } + + public override object this[FieldDescriptor field] + { + get + { + if (field.IsExtension) + { + VerifyContainingType(field); + object value = extensions[field]; + if (value == null) + { + // Lacking an ExtensionRegistry, we have no way to determine the + // extension's real type, so we return a DynamicMessage. + // TODO(jonskeet): Work out what this means + return DynamicMessage.GetDefaultInstance(field.MessageType); + } + else + { + return value; + } + } + else + { + return base[field]; + } + } + } + + public override int GetRepeatedFieldCount(FieldDescriptor field) + { + if (field.IsExtension) + { + VerifyContainingType(field); + return extensions.GetRepeatedFieldCount(field); + } + else + { + return base.GetRepeatedFieldCount(field); + } + } + + public override object this[FieldDescriptor field, int index] + { + get + { + if (field.IsExtension) + { + VerifyContainingType(field); + return extensions[field, index]; + } + else + { + return base[field, index]; + } + } + } + + internal void VerifyContainingType(FieldDescriptor field) + { + if (field.ContainingType != DescriptorForType) + { + throw new ArgumentException("FieldDescriptor does not match message type."); + } + } + + #endregion + + /// + /// Used by subclasses to serialize extensions. Extension ranges may be + /// interleaves with field numbers, but we must write them in canonical + /// (sorted by field number) order. This class helps us to write individual + /// ranges of extensions at once. + /// + /// TODO(jonskeet): See if we can improve this in terms of readability. + /// + protected class ExtensionWriter + { + private readonly IEnumerator> iterator; + private readonly FieldSet extensions; + private KeyValuePair? next = null; + + internal ExtensionWriter(ExtendableMessage message) + { + extensions = message.extensions; + iterator = message.extensions.GetEnumerator(); + if (iterator.MoveNext()) + { + next = iterator.Current; + } + } + + public void WriteUntil(int end, CodedOutputStream output) + { + while (next != null && next.Value.Key.FieldNumber < end) + { + extensions.WriteField(next.Value.Key, next.Value.Value, output); + if (iterator.MoveNext()) + { + next = iterator.Current; + } + else + { + next = null; + } + } + } + } + + protected ExtensionWriter CreateExtensionWriter(ExtendableMessage message) + { + return new ExtensionWriter(message); + } + + /// + /// Called by subclasses to compute the size of extensions. + /// + protected int ExtensionsSerializedSize + { + get { return extensions.SerializedSize; } + } + + internal void VerifyExtensionContainingType(GeneratedExtensionBase extension) + { + if (extension.Descriptor.ContainingType != DescriptorForType) + { + // This can only happen if someone uses unchecked operations. + throw new ArgumentException("Extension is for type \"" + extension.Descriptor.ContainingType.FullName + + "\" which does not match message type \"" + DescriptorForType.FullName + + "\"."); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/ExtendableMessageLite.cs b/src/ProtocolBuffers/ExtendableMessageLite.cs index aed8545d..8c330bb9 100644 --- a/src/ProtocolBuffers/ExtendableMessageLite.cs +++ b/src/ProtocolBuffers/ExtendableMessageLite.cs @@ -1,184 +1,218 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using Google.ProtocolBuffers.Collections; - -namespace Google.ProtocolBuffers { - public abstract class ExtendableMessageLite : GeneratedMessageLite - where TMessage : GeneratedMessageLite - where TBuilder : GeneratedBuilderLite { - - protected ExtendableMessageLite() { } - private readonly FieldSet extensions = FieldSet.CreateInstance(); - - /// - /// Access for the builder. - /// - internal FieldSet Extensions { - get { return extensions; } - } - - public override bool Equals(object obj) { - ExtendableMessageLite other = obj as ExtendableMessageLite; - return !ReferenceEquals(null, other) && - Dictionaries.Equals(extensions.AllFields, other.extensions.AllFields); - } - - public override int GetHashCode() { - return Dictionaries.GetHashCode(extensions.AllFields); - } - - /// - /// writes the extensions to the text stream - /// - public override void PrintTo(System.IO.TextWriter writer) { - foreach (KeyValuePair entry in extensions.AllFields) { - string fn = string.Format("[{0}]", entry.Key.FullName); - if (entry.Key.IsRepeated) { - foreach (object o in ((IEnumerable)entry.Value)) - PrintField(fn, true, o, writer); - } else { - PrintField(fn, true, entry.Value, writer); - } - } - } - - /// - /// Checks if a singular extension is present. - /// - public bool HasExtension(GeneratedExtensionLite extension) { - VerifyExtensionContainingType(extension); - return extensions.HasField(extension.Descriptor); - } - - /// - /// Returns the number of elements in a repeated extension. - /// - public int GetExtensionCount(GeneratedExtensionLite> extension) { - VerifyExtensionContainingType(extension); - return extensions.GetRepeatedFieldCount(extension.Descriptor); - } - - /// - /// Returns the value of an extension. - /// - public TExtension GetExtension(GeneratedExtensionLite extension) { - VerifyExtensionContainingType(extension); - object value = extensions[extension.Descriptor]; - if (value == null) { - return extension.DefaultValue; - } else { - return (TExtension)extension.FromReflectionType(value); - } - } - - /// - /// Returns one element of a repeated extension. - /// - public TExtension GetExtension(GeneratedExtensionLite> extension, int index) { - VerifyExtensionContainingType(extension); - return (TExtension)extension.SingularFromReflectionType(extensions[extension.Descriptor, index]); - } - - /// - /// Called to check if all extensions are initialized. - /// - protected bool ExtensionsAreInitialized { - get { return extensions.IsInitialized; } - } - - public override bool IsInitialized { - get { - return ExtensionsAreInitialized; - } - } - - /// - /// Used by subclasses to serialize extensions. Extension ranges may be - /// interleaves with field numbers, but we must write them in canonical - /// (sorted by field number) order. This class helps us to write individual - /// ranges of extensions at once. - /// - /// TODO(jonskeet): See if we can improve this in terms of readability. - /// - protected class ExtensionWriter { - readonly IEnumerator> iterator; - readonly FieldSet extensions; - KeyValuePair? next = null; - - internal ExtensionWriter(ExtendableMessageLite message) { - extensions = message.extensions; - iterator = message.extensions.GetEnumerator(); - if (iterator.MoveNext()) { - next = iterator.Current; - } - } - - public void WriteUntil(int end, CodedOutputStream output) { - while (next != null && next.Value.Key.FieldNumber < end) { - extensions.WriteField(next.Value.Key, next.Value.Value, output); - if (iterator.MoveNext()) { - next = iterator.Current; - } else { - next = null; - } - } - } - } - - protected ExtensionWriter CreateExtensionWriter(ExtendableMessageLite message) { - return new ExtensionWriter(message); - } - - /// - /// Called by subclasses to compute the size of extensions. - /// - protected int ExtensionsSerializedSize { - get { return extensions.SerializedSize; } - } - - internal void VerifyExtensionContainingType(GeneratedExtensionLite extension) { - if (!ReferenceEquals(extension.ContainingTypeDefaultInstance, DefaultInstanceForType)) { - // This can only happen if someone uses unchecked operations. - throw new ArgumentException( - String.Format("Extension is for type \"{0}\" which does not match message type \"{1}\".", - extension.ContainingTypeDefaultInstance, DefaultInstanceForType - )); - } - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using Google.ProtocolBuffers.Collections; + +namespace Google.ProtocolBuffers +{ + public abstract class ExtendableMessageLite : GeneratedMessageLite + where TMessage : GeneratedMessageLite + where TBuilder : GeneratedBuilderLite + { + protected ExtendableMessageLite() + { + } + + private readonly FieldSet extensions = FieldSet.CreateInstance(); + + /// + /// Access for the builder. + /// + internal FieldSet Extensions + { + get { return extensions; } + } + + public override bool Equals(object obj) + { + ExtendableMessageLite other = obj as ExtendableMessageLite; + return !ReferenceEquals(null, other) && + Dictionaries.Equals(extensions.AllFields, other.extensions.AllFields); + } + + public override int GetHashCode() + { + return Dictionaries.GetHashCode(extensions.AllFields); + } + + /// + /// writes the extensions to the text stream + /// + public override void PrintTo(System.IO.TextWriter writer) + { + foreach (KeyValuePair entry in extensions.AllFields) + { + string fn = string.Format("[{0}]", entry.Key.FullName); + if (entry.Key.IsRepeated) + { + foreach (object o in ((IEnumerable) entry.Value)) + PrintField(fn, true, o, writer); + } + else + { + PrintField(fn, true, entry.Value, writer); + } + } + } + + /// + /// Checks if a singular extension is present. + /// + public bool HasExtension(GeneratedExtensionLite extension) + { + VerifyExtensionContainingType(extension); + return extensions.HasField(extension.Descriptor); + } + + /// + /// Returns the number of elements in a repeated extension. + /// + public int GetExtensionCount(GeneratedExtensionLite> extension) + { + VerifyExtensionContainingType(extension); + return extensions.GetRepeatedFieldCount(extension.Descriptor); + } + + /// + /// Returns the value of an extension. + /// + public TExtension GetExtension(GeneratedExtensionLite extension) + { + VerifyExtensionContainingType(extension); + object value = extensions[extension.Descriptor]; + if (value == null) + { + return extension.DefaultValue; + } + else + { + return (TExtension) extension.FromReflectionType(value); + } + } + + /// + /// Returns one element of a repeated extension. + /// + public TExtension GetExtension(GeneratedExtensionLite> extension, + int index) + { + VerifyExtensionContainingType(extension); + return (TExtension) extension.SingularFromReflectionType(extensions[extension.Descriptor, index]); + } + + /// + /// Called to check if all extensions are initialized. + /// + protected bool ExtensionsAreInitialized + { + get { return extensions.IsInitialized; } + } + + public override bool IsInitialized + { + get { return ExtensionsAreInitialized; } + } + + /// + /// Used by subclasses to serialize extensions. Extension ranges may be + /// interleaves with field numbers, but we must write them in canonical + /// (sorted by field number) order. This class helps us to write individual + /// ranges of extensions at once. + /// + /// TODO(jonskeet): See if we can improve this in terms of readability. + /// + protected class ExtensionWriter + { + private readonly IEnumerator> iterator; + private readonly FieldSet extensions; + private KeyValuePair? next = null; + + internal ExtensionWriter(ExtendableMessageLite message) + { + extensions = message.extensions; + iterator = message.extensions.GetEnumerator(); + if (iterator.MoveNext()) + { + next = iterator.Current; + } + } + + public void WriteUntil(int end, CodedOutputStream output) + { + while (next != null && next.Value.Key.FieldNumber < end) + { + extensions.WriteField(next.Value.Key, next.Value.Value, output); + if (iterator.MoveNext()) + { + next = iterator.Current; + } + else + { + next = null; + } + } + } + } + + protected ExtensionWriter CreateExtensionWriter(ExtendableMessageLite message) + { + return new ExtensionWriter(message); + } + + /// + /// Called by subclasses to compute the size of extensions. + /// + protected int ExtensionsSerializedSize + { + get { return extensions.SerializedSize; } + } + + internal void VerifyExtensionContainingType(GeneratedExtensionLite extension) + { + if (!ReferenceEquals(extension.ContainingTypeDefaultInstance, DefaultInstanceForType)) + { + // This can only happen if someone uses unchecked operations. + throw new ArgumentException( + String.Format("Extension is for type \"{0}\" which does not match message type \"{1}\".", + extension.ContainingTypeDefaultInstance, DefaultInstanceForType + )); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/ExtensionInfo.cs b/src/ProtocolBuffers/ExtensionInfo.cs index 5d99b8ff..8ea1f9eb 100644 --- a/src/ProtocolBuffers/ExtensionInfo.cs +++ b/src/ProtocolBuffers/ExtensionInfo.cs @@ -1,77 +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 Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers -{ - public sealed class ExtensionInfo : IGeneratedExtensionLite { - /// - /// The extension's descriptor - /// - public FieldDescriptor Descriptor { get; private set; } - - IFieldDescriptorLite IGeneratedExtensionLite.Descriptor { get { return Descriptor; } } - - /// - /// A default instance of the extensions's type, if it has a message type, - /// or null otherwise. - /// - public IMessageLite DefaultInstance { get; private set; } - - internal ExtensionInfo(FieldDescriptor descriptor) : this(descriptor, null) { - } - - internal ExtensionInfo(FieldDescriptor descriptor, IMessageLite defaultInstance) { - Descriptor = descriptor; - DefaultInstance = defaultInstance; - } - - #region IGeneratedExtensionLite Members - - int IGeneratedExtensionLite.Number { - get { return Descriptor.FieldNumber; } - } - - object IGeneratedExtensionLite.ContainingType { - get { return Descriptor; } - } - - IMessageLite IGeneratedExtensionLite.MessageDefaultInstance { - get { return DefaultInstance; } - } - - #endregion - } +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + public sealed class ExtensionInfo : IGeneratedExtensionLite + { + /// + /// The extension's descriptor + /// + public FieldDescriptor Descriptor { get; private set; } + + IFieldDescriptorLite IGeneratedExtensionLite.Descriptor + { + get { return Descriptor; } + } + + /// + /// A default instance of the extensions's type, if it has a message type, + /// or null otherwise. + /// + public IMessageLite DefaultInstance { get; private set; } + + internal ExtensionInfo(FieldDescriptor descriptor) : this(descriptor, null) + { + } + + internal ExtensionInfo(FieldDescriptor descriptor, IMessageLite defaultInstance) + { + Descriptor = descriptor; + DefaultInstance = defaultInstance; + } + + #region IGeneratedExtensionLite Members + + int IGeneratedExtensionLite.Number + { + get { return Descriptor.FieldNumber; } + } + + object IGeneratedExtensionLite.ContainingType + { + get { return Descriptor; } + } + + IMessageLite IGeneratedExtensionLite.MessageDefaultInstance + { + get { return DefaultInstance; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/ProtocolBuffers/ExtensionRegistry.cs b/src/ProtocolBuffers/ExtensionRegistry.cs index b7690731..60f2633b 100644 --- a/src/ProtocolBuffers/ExtensionRegistry.cs +++ b/src/ProtocolBuffers/ExtensionRegistry.cs @@ -1,207 +1,230 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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; -using System; - -namespace Google.ProtocolBuffers { - /// - /// A table of known extensions, searchable by name or field number. When - /// parsing a protocol message that might have extensions, you must provide - /// an in which you have registered any extensions - /// that you want to be able to parse. Otherwise, those extensions will just - /// be treated like unknown fields. - /// - /// - /// For example, if you had the .proto file: - /// - /// option java_class = "MyProto"; - /// - /// message Foo { - /// extensions 1000 to max; - /// } - /// - /// extend Foo { - /// optional int32 bar; - /// } - /// - /// - /// Then you might write code like: - /// - /// - /// ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - /// registry.Add(MyProto.Bar); - /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry); - /// - /// - /// - /// - /// You might wonder why this is necessary. Two alternatives might come to - /// mind. First, you might imagine a system where generated extensions are - /// automatically registered when their containing classes are loaded. This - /// is a popular technique, but is bad design; among other things, it creates a - /// situation where behavior can change depending on what classes happen to be - /// loaded. It also introduces a security vulnerability, because an - /// unprivileged class could cause its code to be called unexpectedly from a - /// privileged class by registering itself as an extension of the right type. - /// - /// Another option you might consider is lazy parsing: do not parse an - /// extension until it is first requested, at which point the caller must - /// provide a type to use. This introduces a different set of problems. First, - /// it would require a mutex lock any time an extension was accessed, which - /// would be slow. Second, corrupt data would not be detected until first - /// access, at which point it would be much harder to deal with it. Third, it - /// could violate the expectation that message objects are immutable, since the - /// type provided could be any arbitrary message class. An unprivileged user - /// could take advantage of this to inject a mutable object into a message - /// belonging to privileged code and create mischief. - /// - public sealed partial class ExtensionRegistry { -#if !LITE - private static readonly ExtensionRegistry empty = new ExtensionRegistry( - new Dictionary(), - new Dictionary(), - true); - - private readonly IDictionary extensionsByName; - - private ExtensionRegistry(IDictionary extensionsByName, - IDictionary extensionsByNumber, - bool readOnly) - : this(extensionsByNumber, readOnly) { - this.extensionsByName = extensionsByName; - } - - /// - /// Construct a new, empty instance. - /// - public static ExtensionRegistry CreateInstance() { - return new ExtensionRegistry(new Dictionary(), - new Dictionary(), false); - } - - public ExtensionRegistry AsReadOnly() { - return new ExtensionRegistry(extensionsByName, extensionsByNumber, true); - } -#endif - - /// - /// Finds an extension by fully-qualified field name, in the - /// proto namespace, i.e. result.Descriptor.FullName will match - /// if a match is found. A null - /// reference is returned if the extension can't be found. - /// - public ExtensionInfo this[string fullName] { - get { - ExtensionInfo ret; - extensionsByName.TryGetValue(fullName, out ret); - return ret; - } - } - - /// - /// Finds an extension by containing type and field number. - /// A null reference is returned if the extension can't be found. - /// - public ExtensionInfo this[MessageDescriptor containingType, int fieldNumber] { - get { - IGeneratedExtensionLite ret; - extensionsByNumber.TryGetValue(new ExtensionIntPair(containingType, fieldNumber), out ret); - return ret as ExtensionInfo; - } - } - - /// - /// Add an extension from a generated file to the registry. - /// - public void Add (GeneratedExtensionBase extension) { - if (extension.Descriptor.MappedType == MappedType.Message) { - Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance)); - } else { - Add(new ExtensionInfo(extension.Descriptor, null)); - } - } - - /// - /// Adds a non-message-type extension to the registry by descriptor. - /// - /// - public void Add(FieldDescriptor type) { - if (type.MappedType == MappedType.Message) { - throw new ArgumentException("ExtensionRegistry.Add() must be provided a default instance " - + "when adding an embedded message extension."); - } - Add(new ExtensionInfo(type, null)); - } - - /// - /// Adds a message-type-extension to the registry by descriptor. - /// - /// - /// - public void Add(FieldDescriptor type, IMessage defaultInstance) { - if (type.MappedType != MappedType.Message) { - throw new ArgumentException("ExtensionRegistry.Add() provided a default instance for a " - + "non-message extension."); - } - Add(new ExtensionInfo(type, defaultInstance)); - } - - private void Add(ExtensionInfo extension) { - if (readOnly) { - throw new InvalidOperationException("Cannot add entries to a read-only extension registry"); - } - if (!extension.Descriptor.IsExtension) { - throw new ArgumentException("ExtensionRegistry.add() was given a FieldDescriptor for a " - + "regular (non-extension) field."); - } - - extensionsByName[extension.Descriptor.FullName] = extension; - extensionsByNumber[new ExtensionIntPair(extension.Descriptor.ContainingType, - extension.Descriptor.FieldNumber)] = extension; - - FieldDescriptor field = extension.Descriptor; - if (field.ContainingType.Options.MessageSetWireFormat - && field.FieldType == FieldType.Message - && field.IsOptional - && field.ExtensionScope == field.MessageType) { - // This is an extension of a MessageSet type defined within the extension - // type's own scope. For backwards-compatibility, allow it to be looked - // up by type name. - extensionsByName[field.MessageType.FullName] = extension; - } - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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; +using System; + +namespace Google.ProtocolBuffers +{ + /// + /// A table of known extensions, searchable by name or field number. When + /// parsing a protocol message that might have extensions, you must provide + /// an in which you have registered any extensions + /// that you want to be able to parse. Otherwise, those extensions will just + /// be treated like unknown fields. + /// + /// + /// For example, if you had the .proto file: + /// + /// option java_class = "MyProto"; + /// + /// message Foo { + /// extensions 1000 to max; + /// } + /// + /// extend Foo { + /// optional int32 bar; + /// } + /// + /// + /// Then you might write code like: + /// + /// + /// ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + /// registry.Add(MyProto.Bar); + /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry); + /// + /// + /// + /// + /// You might wonder why this is necessary. Two alternatives might come to + /// mind. First, you might imagine a system where generated extensions are + /// automatically registered when their containing classes are loaded. This + /// is a popular technique, but is bad design; among other things, it creates a + /// situation where behavior can change depending on what classes happen to be + /// loaded. It also introduces a security vulnerability, because an + /// unprivileged class could cause its code to be called unexpectedly from a + /// privileged class by registering itself as an extension of the right type. + /// + /// Another option you might consider is lazy parsing: do not parse an + /// extension until it is first requested, at which point the caller must + /// provide a type to use. This introduces a different set of problems. First, + /// it would require a mutex lock any time an extension was accessed, which + /// would be slow. Second, corrupt data would not be detected until first + /// access, at which point it would be much harder to deal with it. Third, it + /// could violate the expectation that message objects are immutable, since the + /// type provided could be any arbitrary message class. An unprivileged user + /// could take advantage of this to inject a mutable object into a message + /// belonging to privileged code and create mischief. + /// + public sealed partial class ExtensionRegistry + { +#if !LITE + private static readonly ExtensionRegistry empty = new ExtensionRegistry( + new Dictionary(), + new Dictionary(), + true); + + private readonly IDictionary extensionsByName; + + private ExtensionRegistry(IDictionary extensionsByName, + IDictionary extensionsByNumber, + bool readOnly) + : this(extensionsByNumber, readOnly) + { + this.extensionsByName = extensionsByName; + } + + /// + /// Construct a new, empty instance. + /// + public static ExtensionRegistry CreateInstance() + { + return new ExtensionRegistry(new Dictionary(), + new Dictionary(), false); + } + + public ExtensionRegistry AsReadOnly() + { + return new ExtensionRegistry(extensionsByName, extensionsByNumber, true); + } +#endif + + /// + /// Finds an extension by fully-qualified field name, in the + /// proto namespace, i.e. result.Descriptor.FullName will match + /// if a match is found. A null + /// reference is returned if the extension can't be found. + /// + public ExtensionInfo this[string fullName] + { + get + { + ExtensionInfo ret; + extensionsByName.TryGetValue(fullName, out ret); + return ret; + } + } + + /// + /// Finds an extension by containing type and field number. + /// A null reference is returned if the extension can't be found. + /// + public ExtensionInfo this[MessageDescriptor containingType, int fieldNumber] + { + get + { + IGeneratedExtensionLite ret; + extensionsByNumber.TryGetValue(new ExtensionIntPair(containingType, fieldNumber), out ret); + return ret as ExtensionInfo; + } + } + + /// + /// Add an extension from a generated file to the registry. + /// + public void Add(GeneratedExtensionBase extension) + { + if (extension.Descriptor.MappedType == MappedType.Message) + { + Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance)); + } + else + { + Add(new ExtensionInfo(extension.Descriptor, null)); + } + } + + /// + /// Adds a non-message-type extension to the registry by descriptor. + /// + /// + public void Add(FieldDescriptor type) + { + if (type.MappedType == MappedType.Message) + { + throw new ArgumentException("ExtensionRegistry.Add() must be provided a default instance " + + "when adding an embedded message extension."); + } + Add(new ExtensionInfo(type, null)); + } + + /// + /// Adds a message-type-extension to the registry by descriptor. + /// + /// + /// + public void Add(FieldDescriptor type, IMessage defaultInstance) + { + if (type.MappedType != MappedType.Message) + { + throw new ArgumentException("ExtensionRegistry.Add() provided a default instance for a " + + "non-message extension."); + } + Add(new ExtensionInfo(type, defaultInstance)); + } + + private void Add(ExtensionInfo extension) + { + if (readOnly) + { + throw new InvalidOperationException("Cannot add entries to a read-only extension registry"); + } + if (!extension.Descriptor.IsExtension) + { + throw new ArgumentException("ExtensionRegistry.add() was given a FieldDescriptor for a " + + "regular (non-extension) field."); + } + + extensionsByName[extension.Descriptor.FullName] = extension; + extensionsByNumber[new ExtensionIntPair(extension.Descriptor.ContainingType, + extension.Descriptor.FieldNumber)] = extension; + + FieldDescriptor field = extension.Descriptor; + if (field.ContainingType.Options.MessageSetWireFormat + && field.FieldType == FieldType.Message + && field.IsOptional + && field.ExtensionScope == field.MessageType) + { + // This is an extension of a MessageSet type defined within the extension + // type's own scope. For backwards-compatibility, allow it to be looked + // up by type name. + extensionsByName[field.MessageType.FullName] = extension; + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/ExtensionRegistryLite.cs b/src/ProtocolBuffers/ExtensionRegistryLite.cs index 8e420a81..fc662f68 100644 --- a/src/ProtocolBuffers/ExtensionRegistryLite.cs +++ b/src/ProtocolBuffers/ExtensionRegistryLite.cs @@ -1,179 +1,197 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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; - -namespace Google.ProtocolBuffers { - - /// - /// A table of known extensions, searchable by name or field number. When - /// parsing a protocol message that might have extensions, you must provide - /// an in which you have registered any extensions - /// that you want to be able to parse. Otherwise, those extensions will just - /// be treated like unknown fields. - /// - /// - /// For example, if you had the .proto file: - /// - /// option java_class = "MyProto"; - /// - /// message Foo { - /// extensions 1000 to max; - /// } - /// - /// extend Foo { - /// optional int32 bar; - /// } - /// - /// - /// Then you might write code like: - /// - /// - /// extensionRegistry registry = extensionRegistry.CreateInstance(); - /// registry.Add(MyProto.Bar); - /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry); - /// - /// - /// - /// - /// You might wonder why this is necessary. Two alternatives might come to - /// mind. First, you might imagine a system where generated extensions are - /// automatically registered when their containing classes are loaded. This - /// is a popular technique, but is bad design; among other things, it creates a - /// situation where behavior can change depending on what classes happen to be - /// loaded. It also introduces a security vulnerability, because an - /// unprivileged class could cause its code to be called unexpectedly from a - /// privileged class by registering itself as an extension of the right type. - /// - /// Another option you might consider is lazy parsing: do not parse an - /// extension until it is first requested, at which point the caller must - /// provide a type to use. This introduces a different set of problems. First, - /// it would require a mutex lock any time an extension was accessed, which - /// would be slow. Second, corrupt data would not be detected until first - /// access, at which point it would be much harder to deal with it. Third, it - /// could violate the expectation that message objects are immutable, since the - /// type provided could be any arbitrary message class. An unprivileged user - /// could take advantage of this to inject a mutable object into a message - /// belonging to privileged code and create mischief. - /// - public sealed partial class ExtensionRegistry { - private readonly IDictionary extensionsByNumber; - private readonly bool readOnly; - - private ExtensionRegistry(IDictionary extensionsByNumber, - bool readOnly) { - this.extensionsByNumber = extensionsByNumber; - this.readOnly = readOnly; - } - -#if LITE - private static readonly ExtensionRegistry empty = new ExtensionRegistry( - new Dictionary(), - true); - - /// - /// Construct a new, empty instance. - /// - public static ExtensionRegistry CreateInstance() { - return new ExtensionRegistry( - new Dictionary(), false); - } - public ExtensionRegistry AsReadOnly() { - return new ExtensionRegistry(extensionsByNumber, true); - } - -#endif - - /// - /// Get the unmodifiable singleton empty instance. - /// - public static ExtensionRegistry Empty { - get { return empty; } - } - - /// - /// Finds an extension by containing type and field number. - /// A null reference is returned if the extension can't be found. - /// - public IGeneratedExtensionLite this[IMessageLite containingType, int fieldNumber] { - get { - IGeneratedExtensionLite ret; - extensionsByNumber.TryGetValue(new ExtensionIntPair(containingType, fieldNumber), out ret); - return ret; - } - } - - /// - /// Add an extension from a generated file to the registry. - /// - public void Add(IGeneratedExtensionLite extension) { - if (readOnly) { - throw new InvalidOperationException("Cannot add entries to a read-only extension registry"); - } - extensionsByNumber.Add( - new ExtensionIntPair(extension.ContainingType, extension.Number), - extension); - } - - /// - /// Nested type just used to represent a pair of MessageDescriptor and int, as - /// the key into the "by number" map. - /// - private struct ExtensionIntPair : IEquatable { - readonly object msgType; - readonly int number; - - internal ExtensionIntPair(object msgType, int number) { - this.msgType = msgType; - this.number = number; - } - - public override int GetHashCode() { - return msgType.GetHashCode() * ((1 << 16) - 1) + number; - } - - public override bool Equals(object obj) { - if (!(obj is ExtensionIntPair)) { - return false; - } - return Equals((ExtensionIntPair)obj); - } - - public bool Equals(ExtensionIntPair other) { - return msgType.Equals(other.msgType) && number == other.number; - } - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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; + +namespace Google.ProtocolBuffers +{ + /// + /// A table of known extensions, searchable by name or field number. When + /// parsing a protocol message that might have extensions, you must provide + /// an in which you have registered any extensions + /// that you want to be able to parse. Otherwise, those extensions will just + /// be treated like unknown fields. + /// + /// + /// For example, if you had the .proto file: + /// + /// option java_class = "MyProto"; + /// + /// message Foo { + /// extensions 1000 to max; + /// } + /// + /// extend Foo { + /// optional int32 bar; + /// } + /// + /// + /// Then you might write code like: + /// + /// + /// extensionRegistry registry = extensionRegistry.CreateInstance(); + /// registry.Add(MyProto.Bar); + /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry); + /// + /// + /// + /// + /// You might wonder why this is necessary. Two alternatives might come to + /// mind. First, you might imagine a system where generated extensions are + /// automatically registered when their containing classes are loaded. This + /// is a popular technique, but is bad design; among other things, it creates a + /// situation where behavior can change depending on what classes happen to be + /// loaded. It also introduces a security vulnerability, because an + /// unprivileged class could cause its code to be called unexpectedly from a + /// privileged class by registering itself as an extension of the right type. + /// + /// Another option you might consider is lazy parsing: do not parse an + /// extension until it is first requested, at which point the caller must + /// provide a type to use. This introduces a different set of problems. First, + /// it would require a mutex lock any time an extension was accessed, which + /// would be slow. Second, corrupt data would not be detected until first + /// access, at which point it would be much harder to deal with it. Third, it + /// could violate the expectation that message objects are immutable, since the + /// type provided could be any arbitrary message class. An unprivileged user + /// could take advantage of this to inject a mutable object into a message + /// belonging to privileged code and create mischief. + /// + public sealed partial class ExtensionRegistry + { + private readonly IDictionary extensionsByNumber; + private readonly bool readOnly; + + private ExtensionRegistry(IDictionary extensionsByNumber, + bool readOnly) + { + this.extensionsByNumber = extensionsByNumber; + this.readOnly = readOnly; + } + +#if LITE + private static readonly ExtensionRegistry empty = new ExtensionRegistry( + new Dictionary(), + true); + + /// + /// Construct a new, empty instance. + /// + public static ExtensionRegistry CreateInstance() + { + return new ExtensionRegistry( + new Dictionary(), false); + } + + public ExtensionRegistry AsReadOnly() + { + return new ExtensionRegistry(extensionsByNumber, true); + } + +#endif + + /// + /// Get the unmodifiable singleton empty instance. + /// + public static ExtensionRegistry Empty + { + get { return empty; } + } + + /// + /// Finds an extension by containing type and field number. + /// A null reference is returned if the extension can't be found. + /// + public IGeneratedExtensionLite this[IMessageLite containingType, int fieldNumber] + { + get + { + IGeneratedExtensionLite ret; + extensionsByNumber.TryGetValue(new ExtensionIntPair(containingType, fieldNumber), out ret); + return ret; + } + } + + /// + /// Add an extension from a generated file to the registry. + /// + public void Add(IGeneratedExtensionLite extension) + { + if (readOnly) + { + throw new InvalidOperationException("Cannot add entries to a read-only extension registry"); + } + extensionsByNumber.Add( + new ExtensionIntPair(extension.ContainingType, extension.Number), + extension); + } + + /// + /// Nested type just used to represent a pair of MessageDescriptor and int, as + /// the key into the "by number" map. + /// + private struct ExtensionIntPair : IEquatable + { + private readonly object msgType; + private readonly int number; + + internal ExtensionIntPair(object msgType, int number) + { + this.msgType = msgType; + this.number = number; + } + + public override int GetHashCode() + { + return msgType.GetHashCode()*((1 << 16) - 1) + number; + } + + public override bool Equals(object obj) + { + if (!(obj is ExtensionIntPair)) + { + return false; + } + return Equals((ExtensionIntPair) obj); + } + + public bool Equals(ExtensionIntPair other) + { + return msgType.Equals(other.msgType) && number == other.number; + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs b/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs index 3de0ff79..6ba039c1 100644 --- a/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs +++ b/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs @@ -1,105 +1,126 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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 Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers.FieldAccess { - /// - /// Provides access to fields in generated messages via reflection. - /// This type is public to allow it to be used by generated messages, which - /// create appropriate instances in the .proto file description class. - /// TODO(jonskeet): See if we can hide it somewhere... - /// - public sealed class FieldAccessorTable - where TMessage : IMessage - where TBuilder : IBuilder { - - readonly IFieldAccessor[] accessors; - - readonly MessageDescriptor descriptor; - - public MessageDescriptor Descriptor { - get { return descriptor; } - } - - /// - /// Constructs a FieldAccessorTable for a particular message class. - /// Only one FieldAccessorTable should be constructed per class. - /// The property names should all actually correspond with the field descriptor's - /// CSharpOptions.PropertyName property, but bootstrapping issues currently - /// prevent us from using that. This may be addressed at a future time, in which case - /// we can keep this constructor for backwards compatibility, just ignoring the parameter. - /// TODO(jonskeet): Make it so. - /// - /// The type's descriptor - /// The Pascal-case names of all the field-based properties in the message. - public FieldAccessorTable(MessageDescriptor descriptor, String[] propertyNames) { - this.descriptor = descriptor; - accessors = new IFieldAccessor[descriptor.Fields.Count]; - for (int i=0; i < accessors.Length; i++) { - accessors[i] = CreateAccessor(descriptor.Fields[i], propertyNames[i]); - } - } - - /// - /// Creates an accessor for a single field - /// - private static IFieldAccessor CreateAccessor(FieldDescriptor field, string name) { - if (field.IsRepeated) { - switch (field.MappedType) { - case MappedType.Message: return new RepeatedMessageAccessor(name); - case MappedType.Enum: return new RepeatedEnumAccessor(field, name); - default: return new RepeatedPrimitiveAccessor(name); - } - } else { - switch (field.MappedType) { - case MappedType.Message: return new SingleMessageAccessor(name); - case MappedType.Enum: return new SingleEnumAccessor(field, name); - default: return new SinglePrimitiveAccessor(name); - } - } - } - - internal IFieldAccessor this[FieldDescriptor field] { - get { - if (field.ContainingType != descriptor) { - throw new ArgumentException("FieldDescriptor does not match message type."); - } else if (field.IsExtension) { - // If this type had extensions, it would subclass ExtendableMessage, - // which overrides the reflection interface to handle extensions. - throw new ArgumentException("This type does not have extensions."); - } - return accessors[field.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 System; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers.FieldAccess +{ + /// + /// Provides access to fields in generated messages via reflection. + /// This type is public to allow it to be used by generated messages, which + /// create appropriate instances in the .proto file description class. + /// TODO(jonskeet): See if we can hide it somewhere... + /// + public sealed class FieldAccessorTable + where TMessage : IMessage + where TBuilder : IBuilder + { + private readonly IFieldAccessor[] accessors; + + private readonly MessageDescriptor descriptor; + + public MessageDescriptor Descriptor + { + get { return descriptor; } + } + + /// + /// Constructs a FieldAccessorTable for a particular message class. + /// Only one FieldAccessorTable should be constructed per class. + /// The property names should all actually correspond with the field descriptor's + /// CSharpOptions.PropertyName property, but bootstrapping issues currently + /// prevent us from using that. This may be addressed at a future time, in which case + /// we can keep this constructor for backwards compatibility, just ignoring the parameter. + /// TODO(jonskeet): Make it so. + /// + /// The type's descriptor + /// The Pascal-case names of all the field-based properties in the message. + public FieldAccessorTable(MessageDescriptor descriptor, String[] propertyNames) + { + this.descriptor = descriptor; + accessors = new IFieldAccessor[descriptor.Fields.Count]; + for (int i = 0; i < accessors.Length; i++) + { + accessors[i] = CreateAccessor(descriptor.Fields[i], propertyNames[i]); + } + } + + /// + /// Creates an accessor for a single field + /// + private static IFieldAccessor CreateAccessor(FieldDescriptor field, string name) + { + if (field.IsRepeated) + { + switch (field.MappedType) + { + case MappedType.Message: + return new RepeatedMessageAccessor(name); + case MappedType.Enum: + return new RepeatedEnumAccessor(field, name); + default: + return new RepeatedPrimitiveAccessor(name); + } + } + else + { + switch (field.MappedType) + { + case MappedType.Message: + return new SingleMessageAccessor(name); + case MappedType.Enum: + return new SingleEnumAccessor(field, name); + default: + return new SinglePrimitiveAccessor(name); + } + } + } + + internal IFieldAccessor this[FieldDescriptor field] + { + get + { + if (field.ContainingType != descriptor) + { + throw new ArgumentException("FieldDescriptor does not match message type."); + } + else if (field.IsExtension) + { + // If this type had extensions, it would subclass ExtendableMessage, + // which overrides the reflection interface to handle extensions. + throw new ArgumentException("This type does not have extensions."); + } + return accessors[field.Index]; + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/IFieldAccessor.cs b/src/ProtocolBuffers/FieldAccess/IFieldAccessor.cs index 80ec0638..39d3b85b 100644 --- a/src/ProtocolBuffers/FieldAccess/IFieldAccessor.cs +++ b/src/ProtocolBuffers/FieldAccess/IFieldAccessor.cs @@ -1,91 +1,95 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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.FieldAccess { - - /// - /// Allows fields to be reflectively accessed in a smart manner. - /// The property descriptors for each field are created once and then cached. - /// In addition, this interface holds knowledge of repeated fields, builders etc. - /// - internal interface IFieldAccessor - where TMessage : IMessage - where TBuilder : IBuilder { - - /// - /// Indicates whether the specified message contains the field. - /// - bool Has(TMessage message); - - /// - /// Gets the count of the repeated field in the specified message. - /// - int GetRepeatedCount(TMessage message); - - /// - /// Clears the field in the specified builder. - /// - /// - void Clear(TBuilder builder); - - /// - /// Creates a builder for the type of this field (which must be a message field). - /// - IBuilder CreateBuilder(); - - /// - /// Accessor for single fields - /// - object GetValue(TMessage message); - /// - /// Mutator for single fields - /// - void SetValue(TBuilder builder, object value); - - /// - /// Accessor for repeated fields - /// - object GetRepeatedValue(TMessage message, int index); - /// - /// Mutator for repeated fields - /// - void SetRepeated(TBuilder builder, int index, object value); - /// - /// Adds the specified value to the field in the given builder. - /// - void AddRepeated(TBuilder builder, object value); - /// - /// Returns a read-only wrapper around the value of a repeated field. - /// - object GetRepeatedWrapper(TBuilder builder); - } -} +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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.FieldAccess +{ + /// + /// Allows fields to be reflectively accessed in a smart manner. + /// The property descriptors for each field are created once and then cached. + /// In addition, this interface holds knowledge of repeated fields, builders etc. + /// + internal interface IFieldAccessor + where TMessage : IMessage + where TBuilder : IBuilder + { + /// + /// Indicates whether the specified message contains the field. + /// + bool Has(TMessage message); + + /// + /// Gets the count of the repeated field in the specified message. + /// + int GetRepeatedCount(TMessage message); + + /// + /// Clears the field in the specified builder. + /// + /// + void Clear(TBuilder builder); + + /// + /// Creates a builder for the type of this field (which must be a message field). + /// + IBuilder CreateBuilder(); + + /// + /// Accessor for single fields + /// + object GetValue(TMessage message); + + /// + /// Mutator for single fields + /// + void SetValue(TBuilder builder, object value); + + /// + /// Accessor for repeated fields + /// + object GetRepeatedValue(TMessage message, int index); + + /// + /// Mutator for repeated fields + /// + void SetRepeated(TBuilder builder, int index, object value); + + /// + /// Adds the specified value to the field in the given builder. + /// + void AddRepeated(TBuilder builder, object value); + + /// + /// Returns a read-only wrapper around the value of a repeated field. + /// + object GetRepeatedWrapper(TBuilder builder); + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/ReflectionUtil.cs b/src/ProtocolBuffers/FieldAccess/ReflectionUtil.cs index 43036f94..31ebde06 100644 --- a/src/ProtocolBuffers/FieldAccess/ReflectionUtil.cs +++ b/src/ProtocolBuffers/FieldAccess/ReflectionUtil.cs @@ -1,124 +1,136 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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.Reflection; - -namespace Google.ProtocolBuffers.FieldAccess { - - /// - /// The methods in this class are somewhat evil, and should not be tampered with lightly. - /// Basically they allow the creation of relatively weakly typed delegates from MethodInfos - /// which are more strongly typed. They do this by creating an appropriate strongly typed - /// delegate from the MethodInfo, and then calling that within an anonymous method. - /// Mind-bending stuff (at least to your humble narrator) but the resulting delegates are - /// very fast compared with calling Invoke later on. - /// - internal static class ReflectionUtil { - - /// - /// Creates a delegate which will execute the given method and then return - /// the result as an object. - /// - public static Func CreateUpcastDelegate(MethodInfo method) { - - // The tricky bit is invoking CreateCreateUpcastDelegateImpl with the right type parameters - MethodInfo openImpl = typeof(ReflectionUtil).GetMethod("CreateUpcastDelegateImpl"); - MethodInfo closedImpl = openImpl.MakeGenericMethod(typeof(T), method.ReturnType); - return (Func) closedImpl.Invoke(null, new object[] { method }); - } - - /// - /// Method used solely for implementing CreateUpcastDelegate. Public to avoid trust issues - /// in low-trust scenarios, e.g. Silverlight. - /// TODO(jonskeet): Check any of this actually works in Silverlight... - /// - public static Func CreateUpcastDelegateImpl(MethodInfo method) { - // Convert the reflection call into an open delegate, i.e. instead of calling x.Method() - // we'll call getter(x). - Func getter = (Func)Delegate.CreateDelegate(typeof(Func), null, method); - - // Implicit upcast to object (within the delegate) - return delegate(TSource source) { return getter(source); }; - } - - /// - /// Creates a delegate which will execute the given method after casting the parameter - /// down from object to the required parameter type. - /// - public static Action CreateDowncastDelegate(MethodInfo method) { - MethodInfo openImpl = typeof(ReflectionUtil).GetMethod("CreateDowncastDelegateImpl"); - MethodInfo closedImpl = openImpl.MakeGenericMethod(typeof(T), method.GetParameters()[0].ParameterType); - return (Action) closedImpl.Invoke(null, new object[] { method }); - } - - public static Action CreateDowncastDelegateImpl(MethodInfo method) { - // Convert the reflection call into an open delegate, i.e. instead of calling x.Method(y) we'll - // call Method(x, y) - Action call = (Action) Delegate.CreateDelegate(typeof(Action), null, method); - - return delegate(TSource source, object parameter) { call(source, (TParam)parameter); }; - } - - /// - /// Creates a delegate which will execute the given method after casting the parameter - /// down from object to the required parameter type. - /// - public static Action CreateDowncastDelegateIgnoringReturn(MethodInfo method) { - MethodInfo openImpl = typeof(ReflectionUtil).GetMethod("CreateDowncastDelegateIgnoringReturnImpl"); - MethodInfo closedImpl = openImpl.MakeGenericMethod(typeof(T), method.GetParameters()[0].ParameterType, method.ReturnType); - return (Action)closedImpl.Invoke(null, new object[] { method }); - } - - public static Action CreateDowncastDelegateIgnoringReturnImpl(MethodInfo method) { - // Convert the reflection call into an open delegate, i.e. instead of calling x.Method(y) we'll - // call Method(x, y) - Func call = (Func) - Delegate.CreateDelegate(typeof(Func), null, method); - - return delegate(TSource source, object parameter) { call(source, (TParam)parameter); }; - } - - /// - /// Creates a delegate which will execute the given static method and cast the result up to IBuilder. - /// - public static Func CreateStaticUpcastDelegate(MethodInfo method) { - MethodInfo openImpl = typeof(ReflectionUtil).GetMethod("CreateStaticUpcastDelegateImpl"); - MethodInfo closedImpl = openImpl.MakeGenericMethod(method.ReturnType); - return (Func)closedImpl.Invoke(null, new object[] { method }); - } - - public static Func CreateStaticUpcastDelegateImpl(MethodInfo method) { - Func call = (Func)Delegate.CreateDelegate(typeof(Func), null, method); - return delegate { return (IBuilder)call(); }; - } - } -} +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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.Reflection; + +namespace Google.ProtocolBuffers.FieldAccess +{ + /// + /// The methods in this class are somewhat evil, and should not be tampered with lightly. + /// Basically they allow the creation of relatively weakly typed delegates from MethodInfos + /// which are more strongly typed. They do this by creating an appropriate strongly typed + /// delegate from the MethodInfo, and then calling that within an anonymous method. + /// Mind-bending stuff (at least to your humble narrator) but the resulting delegates are + /// very fast compared with calling Invoke later on. + /// + internal static class ReflectionUtil + { + /// + /// Creates a delegate which will execute the given method and then return + /// the result as an object. + /// + public static Func CreateUpcastDelegate(MethodInfo method) + { + // The tricky bit is invoking CreateCreateUpcastDelegateImpl with the right type parameters + MethodInfo openImpl = typeof (ReflectionUtil).GetMethod("CreateUpcastDelegateImpl"); + MethodInfo closedImpl = openImpl.MakeGenericMethod(typeof (T), method.ReturnType); + return (Func) closedImpl.Invoke(null, new object[] {method}); + } + + /// + /// Method used solely for implementing CreateUpcastDelegate. Public to avoid trust issues + /// in low-trust scenarios, e.g. Silverlight. + /// TODO(jonskeet): Check any of this actually works in Silverlight... + /// + public static Func CreateUpcastDelegateImpl(MethodInfo method) + { + // Convert the reflection call into an open delegate, i.e. instead of calling x.Method() + // we'll call getter(x). + Func getter = + (Func) Delegate.CreateDelegate(typeof (Func), null, method); + + // Implicit upcast to object (within the delegate) + return delegate(TSource source) { return getter(source); }; + } + + /// + /// Creates a delegate which will execute the given method after casting the parameter + /// down from object to the required parameter type. + /// + public static Action CreateDowncastDelegate(MethodInfo method) + { + MethodInfo openImpl = typeof (ReflectionUtil).GetMethod("CreateDowncastDelegateImpl"); + MethodInfo closedImpl = openImpl.MakeGenericMethod(typeof (T), method.GetParameters()[0].ParameterType); + return (Action) closedImpl.Invoke(null, new object[] {method}); + } + + public static Action CreateDowncastDelegateImpl(MethodInfo method) + { + // Convert the reflection call into an open delegate, i.e. instead of calling x.Method(y) we'll + // call Method(x, y) + Action call = + (Action) Delegate.CreateDelegate(typeof (Action), null, method); + + return delegate(TSource source, object parameter) { call(source, (TParam) parameter); }; + } + + /// + /// Creates a delegate which will execute the given method after casting the parameter + /// down from object to the required parameter type. + /// + public static Action CreateDowncastDelegateIgnoringReturn(MethodInfo method) + { + MethodInfo openImpl = typeof (ReflectionUtil).GetMethod("CreateDowncastDelegateIgnoringReturnImpl"); + MethodInfo closedImpl = openImpl.MakeGenericMethod(typeof (T), method.GetParameters()[0].ParameterType, + method.ReturnType); + return (Action) closedImpl.Invoke(null, new object[] {method}); + } + + public static Action CreateDowncastDelegateIgnoringReturnImpl( + MethodInfo method) + { + // Convert the reflection call into an open delegate, i.e. instead of calling x.Method(y) we'll + // call Method(x, y) + Func call = (Func) + Delegate.CreateDelegate(typeof (Func), null, + method); + + return delegate(TSource source, object parameter) { call(source, (TParam) parameter); }; + } + + /// + /// Creates a delegate which will execute the given static method and cast the result up to IBuilder. + /// + public static Func CreateStaticUpcastDelegate(MethodInfo method) + { + MethodInfo openImpl = typeof (ReflectionUtil).GetMethod("CreateStaticUpcastDelegateImpl"); + MethodInfo closedImpl = openImpl.MakeGenericMethod(method.ReturnType); + return (Func) closedImpl.Invoke(null, new object[] {method}); + } + + public static Func CreateStaticUpcastDelegateImpl(MethodInfo method) + { + Func call = (Func) Delegate.CreateDelegate(typeof (Func), null, method); + return delegate { return (IBuilder) call(); }; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/RepeatedEnumAccessor.cs b/src/ProtocolBuffers/FieldAccess/RepeatedEnumAccessor.cs index 85811a5e..152c2e0a 100644 --- a/src/ProtocolBuffers/FieldAccess/RepeatedEnumAccessor.cs +++ b/src/ProtocolBuffers/FieldAccess/RepeatedEnumAccessor.cs @@ -1,77 +1,83 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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; -using System.Collections.Generic; -using Google.ProtocolBuffers.Collections; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers.FieldAccess { - - /// - /// Accessor for a repeated enum field. - /// - internal sealed class RepeatedEnumAccessor : RepeatedPrimitiveAccessor - where TMessage : IMessage - where TBuilder : IBuilder { - - private readonly EnumDescriptor enumDescriptor; - - internal RepeatedEnumAccessor(FieldDescriptor field, string name) : base(name) { - enumDescriptor = field.EnumType; - } - - public override object GetValue(TMessage message) { - List ret = new List(); - foreach (int rawValue in (IEnumerable) base.GetValue(message)) { - ret.Add(enumDescriptor.FindValueByNumber(rawValue)); - } - return Lists.AsReadOnly(ret); - } - - public override object GetRepeatedValue(TMessage message, int index) { - // Note: This relies on the fact that the CLR allows unboxing from an enum to - // its underlying value - int rawValue = (int) base.GetRepeatedValue(message, index); - return enumDescriptor.FindValueByNumber(rawValue); - } - - public override void AddRepeated(TBuilder builder, object value) { - ThrowHelper.ThrowIfNull(value, "value"); - base.AddRepeated(builder, ((EnumValueDescriptor)value).Number); - } - - public override void SetRepeated(TBuilder builder, int index, object value) { - ThrowHelper.ThrowIfNull(value, "value"); - base.SetRepeated(builder, index, ((EnumValueDescriptor) value).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; +using System.Collections.Generic; +using Google.ProtocolBuffers.Collections; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers.FieldAccess +{ + /// + /// Accessor for a repeated enum field. + /// + internal sealed class RepeatedEnumAccessor : RepeatedPrimitiveAccessor + where TMessage : IMessage + where TBuilder : IBuilder + { + private readonly EnumDescriptor enumDescriptor; + + internal RepeatedEnumAccessor(FieldDescriptor field, string name) : base(name) + { + enumDescriptor = field.EnumType; + } + + public override object GetValue(TMessage message) + { + List ret = new List(); + foreach (int rawValue in (IEnumerable) base.GetValue(message)) + { + ret.Add(enumDescriptor.FindValueByNumber(rawValue)); + } + return Lists.AsReadOnly(ret); + } + + public override object GetRepeatedValue(TMessage message, int index) + { + // Note: This relies on the fact that the CLR allows unboxing from an enum to + // its underlying value + int rawValue = (int) base.GetRepeatedValue(message, index); + return enumDescriptor.FindValueByNumber(rawValue); + } + + public override void AddRepeated(TBuilder builder, object value) + { + ThrowHelper.ThrowIfNull(value, "value"); + base.AddRepeated(builder, ((EnumValueDescriptor) value).Number); + } + + public override void SetRepeated(TBuilder builder, int index, object value) + { + ThrowHelper.ThrowIfNull(value, "value"); + base.SetRepeated(builder, index, ((EnumValueDescriptor) value).Number); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/RepeatedMessageAccessor.cs b/src/ProtocolBuffers/FieldAccess/RepeatedMessageAccessor.cs index df6680cb..fd18b904 100644 --- a/src/ProtocolBuffers/FieldAccess/RepeatedMessageAccessor.cs +++ b/src/ProtocolBuffers/FieldAccess/RepeatedMessageAccessor.cs @@ -1,90 +1,97 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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.Reflection; - -namespace Google.ProtocolBuffers.FieldAccess { - - /// - /// Accessor for a repeated message field. - /// - /// TODO(jonskeet): Try to extract the commonality between this and SingleMessageAccessor. - /// We almost want multiple inheritance... - /// - internal sealed class RepeatedMessageAccessor : RepeatedPrimitiveAccessor - where TMessage : IMessage - where TBuilder : IBuilder { - - /// - /// The static method to create a builder for the property type. For example, - /// in a message type "Foo", a field called "bar" might be of type "Baz". This - /// method is Baz.CreateBuilder. - /// - private readonly Func createBuilderDelegate; - - internal RepeatedMessageAccessor(string name) : base(name) { - MethodInfo createBuilderMethod = ClrType.GetMethod("CreateBuilder", EmptyTypes); - if (createBuilderMethod == null) { - throw new ArgumentException("No public static CreateBuilder method declared in " + ClrType.Name); - } - createBuilderDelegate = ReflectionUtil.CreateStaticUpcastDelegate(createBuilderMethod); - } - - /// - /// Creates a message of the appropriate CLR type from the given value, - /// which may already be of the right type or may be a dynamic message. - /// - private object CoerceType(object value) { - ThrowHelper.ThrowIfNull(value, "value"); - // If it's already of the right type, we're done - if (ClrType.IsInstanceOfType(value)) { - return value; - } - - // No... so let's create a builder of the right type, and merge the value in. - IMessageLite message = (IMessageLite) value; - return CreateBuilder().WeakMergeFrom(message).WeakBuild(); - } - - public override void SetRepeated(TBuilder builder, int index, object value) { - base.SetRepeated(builder, index, CoerceType(value)); - } - - public override IBuilder CreateBuilder() { - return createBuilderDelegate(); - } - - public override void AddRepeated(TBuilder builder, object value) { - base.AddRepeated(builder, CoerceType(value)); - } - } -} +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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.Reflection; + +namespace Google.ProtocolBuffers.FieldAccess +{ + /// + /// Accessor for a repeated message field. + /// + /// TODO(jonskeet): Try to extract the commonality between this and SingleMessageAccessor. + /// We almost want multiple inheritance... + /// + internal sealed class RepeatedMessageAccessor : RepeatedPrimitiveAccessor + where TMessage : IMessage + where TBuilder : IBuilder + { + /// + /// The static method to create a builder for the property type. For example, + /// in a message type "Foo", a field called "bar" might be of type "Baz". This + /// method is Baz.CreateBuilder. + /// + private readonly Func createBuilderDelegate; + + internal RepeatedMessageAccessor(string name) : base(name) + { + MethodInfo createBuilderMethod = ClrType.GetMethod("CreateBuilder", EmptyTypes); + if (createBuilderMethod == null) + { + throw new ArgumentException("No public static CreateBuilder method declared in " + ClrType.Name); + } + createBuilderDelegate = ReflectionUtil.CreateStaticUpcastDelegate(createBuilderMethod); + } + + /// + /// Creates a message of the appropriate CLR type from the given value, + /// which may already be of the right type or may be a dynamic message. + /// + private object CoerceType(object value) + { + ThrowHelper.ThrowIfNull(value, "value"); + // If it's already of the right type, we're done + if (ClrType.IsInstanceOfType(value)) + { + return value; + } + + // No... so let's create a builder of the right type, and merge the value in. + IMessageLite message = (IMessageLite) value; + return CreateBuilder().WeakMergeFrom(message).WeakBuild(); + } + + public override void SetRepeated(TBuilder builder, int index, object value) + { + base.SetRepeated(builder, index, CoerceType(value)); + } + + public override IBuilder CreateBuilder() + { + return createBuilderDelegate(); + } + + public override void AddRepeated(TBuilder builder, object value) + { + base.AddRepeated(builder, CoerceType(value)); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs b/src/ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs index 6bae59cb..0c2cdfcf 100644 --- a/src/ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs +++ b/src/ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs @@ -1,144 +1,160 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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.Reflection; - -namespace Google.ProtocolBuffers.FieldAccess { - /// - /// Accessor for a repeated field of type int, ByteString etc. - /// - internal class RepeatedPrimitiveAccessor : IFieldAccessor - where TMessage : IMessage - where TBuilder : IBuilder { - - private readonly Type clrType; - private readonly Func getValueDelegate; - private readonly Func clearDelegate; - private readonly Action addValueDelegate; - private readonly Func getRepeatedWrapperDelegate; - private readonly Func countDelegate; - private readonly MethodInfo getElementMethod; - private readonly MethodInfo setElementMethod; - - // Replacement for Type.EmptyTypes which apparently isn't available on the compact framework - internal static readonly Type[] EmptyTypes = new Type[0]; - - /// - /// The CLR type of the field (int, the enum type, ByteString, the message etc). - /// This is taken from the return type of the method used to retrieve a single - /// value. - /// - protected Type ClrType { - get { return clrType; } - } - - internal RepeatedPrimitiveAccessor(string name) { - PropertyInfo messageProperty = typeof(TMessage).GetProperty(name + "List"); - PropertyInfo builderProperty = typeof(TBuilder).GetProperty(name + "List"); - PropertyInfo countProperty = typeof(TMessage).GetProperty(name + "Count"); - MethodInfo clearMethod = typeof(TBuilder).GetMethod("Clear" + name, EmptyTypes); - getElementMethod = typeof(TMessage).GetMethod("Get" + name, new Type[] { typeof(int) }); - clrType = getElementMethod.ReturnType; - MethodInfo addMethod = typeof(TBuilder).GetMethod("Add" + name, new Type[] { ClrType }); - setElementMethod = typeof(TBuilder).GetMethod("Set" + name, new Type[] { typeof(int), ClrType }); - if (messageProperty == null - || builderProperty == null - || countProperty == null - || clearMethod == null - || addMethod == null - || getElementMethod == null - || setElementMethod == null) { - throw new ArgumentException("Not all required properties/methods available"); - } - clearDelegate = (Func)Delegate.CreateDelegate(typeof(Func), null, clearMethod); - countDelegate = (Func)Delegate.CreateDelegate - (typeof(Func), null, countProperty.GetGetMethod()); - getValueDelegate = ReflectionUtil.CreateUpcastDelegate(messageProperty.GetGetMethod()); - addValueDelegate = ReflectionUtil.CreateDowncastDelegateIgnoringReturn(addMethod); - getRepeatedWrapperDelegate = ReflectionUtil.CreateUpcastDelegate(builderProperty.GetGetMethod()); - } - - public bool Has(TMessage message) { - throw new InvalidOperationException(); - } - - public virtual IBuilder CreateBuilder() { - throw new InvalidOperationException(); - } - - public virtual object GetValue(TMessage message) { - return getValueDelegate(message); - } - - public void SetValue(TBuilder builder, object value) { - // Add all the elements individually. This serves two purposes: - // 1) Verifies that each element has the correct type. - // 2) Insures that the caller cannot modify the list later on and - // have the modifications be reflected in the message. - Clear(builder); - foreach (object element in (IEnumerable) value) { - AddRepeated(builder, element); - } - } - - public void Clear(TBuilder builder) { - clearDelegate(builder); - } - - public int GetRepeatedCount(TMessage message) { - return countDelegate(message); - } - - public virtual object GetRepeatedValue(TMessage message, int index) { - return getElementMethod.Invoke(message, new object[] {index } ); - } - - public virtual void SetRepeated(TBuilder builder, int index, object value) { - ThrowHelper.ThrowIfNull(value, "value"); - setElementMethod.Invoke(builder, new object[] { index, value }); - } - - public virtual void AddRepeated(TBuilder builder, object value) { - ThrowHelper.ThrowIfNull(value, "value"); - addValueDelegate(builder, value); - } - - /// - /// The builder class's accessor already builds a read-only wrapper for - /// us, which is exactly what we want. - /// - public object GetRepeatedWrapper(TBuilder builder) { - return getRepeatedWrapperDelegate(builder); - } - } +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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.Reflection; + +namespace Google.ProtocolBuffers.FieldAccess +{ + /// + /// Accessor for a repeated field of type int, ByteString etc. + /// + internal class RepeatedPrimitiveAccessor : IFieldAccessor + where TMessage : IMessage + where TBuilder : IBuilder + { + private readonly Type clrType; + private readonly Func getValueDelegate; + private readonly Func clearDelegate; + private readonly Action addValueDelegate; + private readonly Func getRepeatedWrapperDelegate; + private readonly Func countDelegate; + private readonly MethodInfo getElementMethod; + private readonly MethodInfo setElementMethod; + + // Replacement for Type.EmptyTypes which apparently isn't available on the compact framework + internal static readonly Type[] EmptyTypes = new Type[0]; + + /// + /// The CLR type of the field (int, the enum type, ByteString, the message etc). + /// This is taken from the return type of the method used to retrieve a single + /// value. + /// + protected Type ClrType + { + get { return clrType; } + } + + internal RepeatedPrimitiveAccessor(string name) + { + PropertyInfo messageProperty = typeof (TMessage).GetProperty(name + "List"); + PropertyInfo builderProperty = typeof (TBuilder).GetProperty(name + "List"); + PropertyInfo countProperty = typeof (TMessage).GetProperty(name + "Count"); + MethodInfo clearMethod = typeof (TBuilder).GetMethod("Clear" + name, EmptyTypes); + getElementMethod = typeof (TMessage).GetMethod("Get" + name, new Type[] {typeof (int)}); + clrType = getElementMethod.ReturnType; + MethodInfo addMethod = typeof (TBuilder).GetMethod("Add" + name, new Type[] {ClrType}); + setElementMethod = typeof (TBuilder).GetMethod("Set" + name, new Type[] {typeof (int), ClrType}); + if (messageProperty == null + || builderProperty == null + || countProperty == null + || clearMethod == null + || addMethod == null + || getElementMethod == null + || setElementMethod == null) + { + throw new ArgumentException("Not all required properties/methods available"); + } + clearDelegate = + (Func) Delegate.CreateDelegate(typeof (Func), null, clearMethod); + countDelegate = (Func) Delegate.CreateDelegate + (typeof (Func), null, countProperty.GetGetMethod()); + getValueDelegate = ReflectionUtil.CreateUpcastDelegate(messageProperty.GetGetMethod()); + addValueDelegate = ReflectionUtil.CreateDowncastDelegateIgnoringReturn(addMethod); + getRepeatedWrapperDelegate = ReflectionUtil.CreateUpcastDelegate(builderProperty.GetGetMethod()); + } + + public bool Has(TMessage message) + { + throw new InvalidOperationException(); + } + + public virtual IBuilder CreateBuilder() + { + throw new InvalidOperationException(); + } + + public virtual object GetValue(TMessage message) + { + return getValueDelegate(message); + } + + public void SetValue(TBuilder builder, object value) + { + // Add all the elements individually. This serves two purposes: + // 1) Verifies that each element has the correct type. + // 2) Insures that the caller cannot modify the list later on and + // have the modifications be reflected in the message. + Clear(builder); + foreach (object element in (IEnumerable) value) + { + AddRepeated(builder, element); + } + } + + public void Clear(TBuilder builder) + { + clearDelegate(builder); + } + + public int GetRepeatedCount(TMessage message) + { + return countDelegate(message); + } + + public virtual object GetRepeatedValue(TMessage message, int index) + { + return getElementMethod.Invoke(message, new object[] {index}); + } + + public virtual void SetRepeated(TBuilder builder, int index, object value) + { + ThrowHelper.ThrowIfNull(value, "value"); + setElementMethod.Invoke(builder, new object[] {index, value}); + } + + public virtual void AddRepeated(TBuilder builder, object value) + { + ThrowHelper.ThrowIfNull(value, "value"); + addValueDelegate(builder, value); + } + + /// + /// The builder class's accessor already builds a read-only wrapper for + /// us, which is exactly what we want. + /// + public object GetRepeatedWrapper(TBuilder builder) + { + return getRepeatedWrapperDelegate(builder); + } + } } \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs b/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs index 59e573b1..6327cc55 100644 --- a/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs +++ b/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs @@ -1,70 +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 Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers.FieldAccess { - /// - /// Accessor for fields representing a non-repeated enum value. - /// - internal sealed class SingleEnumAccessor : SinglePrimitiveAccessor - where TMessage : IMessage - where TBuilder : IBuilder { - - private readonly EnumDescriptor enumDescriptor; - - internal SingleEnumAccessor(FieldDescriptor field, string name) : base(name) { - enumDescriptor = field.EnumType; - } - - /// - /// Returns an EnumValueDescriptor representing the value in the builder. - /// Note that if an enum has multiple values for the same number, the descriptor - /// for the first value with that number will be returned. - /// - public override object GetValue(TMessage message) { - // Note: This relies on the fact that the CLR allows unboxing from an enum to - // its underlying value - int rawValue = (int) base.GetValue(message); - return enumDescriptor.FindValueByNumber(rawValue); - } - - /// - /// Sets the value as an enum (via an int) in the builder, - /// from an EnumValueDescriptor parameter. - /// - public override void SetValue(TBuilder builder, object value) { - ThrowHelper.ThrowIfNull(value, "value"); - EnumValueDescriptor valueDescriptor = (EnumValueDescriptor) value; - base.SetValue(builder, valueDescriptor.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 Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers.FieldAccess +{ + /// + /// Accessor for fields representing a non-repeated enum value. + /// + internal sealed class SingleEnumAccessor : SinglePrimitiveAccessor + where TMessage : IMessage + where TBuilder : IBuilder + { + private readonly EnumDescriptor enumDescriptor; + + internal SingleEnumAccessor(FieldDescriptor field, string name) : base(name) + { + enumDescriptor = field.EnumType; + } + + /// + /// Returns an EnumValueDescriptor representing the value in the builder. + /// Note that if an enum has multiple values for the same number, the descriptor + /// for the first value with that number will be returned. + /// + public override object GetValue(TMessage message) + { + // Note: This relies on the fact that the CLR allows unboxing from an enum to + // its underlying value + int rawValue = (int) base.GetValue(message); + return enumDescriptor.FindValueByNumber(rawValue); + } + + /// + /// Sets the value as an enum (via an int) in the builder, + /// from an EnumValueDescriptor parameter. + /// + public override void SetValue(TBuilder builder, object value) + { + ThrowHelper.ThrowIfNull(value, "value"); + EnumValueDescriptor valueDescriptor = (EnumValueDescriptor) value; + base.SetValue(builder, valueDescriptor.Number); + } + } } \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs b/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs index 838bc5a2..54b99c2b 100644 --- a/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs +++ b/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs @@ -1,82 +1,89 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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.Reflection; - -namespace Google.ProtocolBuffers.FieldAccess { - /// - /// Accessor for fields representing a non-repeated message value. - /// - internal sealed class SingleMessageAccessor : SinglePrimitiveAccessor - where TMessage : IMessage - where TBuilder : IBuilder { - - /// - /// The static method to create a builder for the property type. For example, - /// in a message type "Foo", a field called "bar" might be of type "Baz". This - /// method is Baz.CreateBuilder. - /// - private readonly Func createBuilderDelegate; - - internal SingleMessageAccessor(string name) : base(name) { - MethodInfo createBuilderMethod = ClrType.GetMethod("CreateBuilder", EmptyTypes); - if (createBuilderMethod == null) { - throw new ArgumentException("No public static CreateBuilder method declared in " + ClrType.Name); - } - createBuilderDelegate = ReflectionUtil.CreateStaticUpcastDelegate(createBuilderMethod); - } - - /// - /// Creates a message of the appropriate CLR type from the given value, - /// which may already be of the right type or may be a dynamic message. - /// - private object CoerceType(object value) { - ThrowHelper.ThrowIfNull(value, "value"); - // If it's already of the right type, we're done - if (ClrType.IsInstanceOfType(value)) { - return value; - } - - // No... so let's create a builder of the right type, and merge the value in. - IMessageLite message = (IMessageLite) value; - return CreateBuilder().WeakMergeFrom(message).WeakBuild(); - } - - public override void SetValue(TBuilder builder, object value) { - base.SetValue(builder, CoerceType(value)); - } - - public override IBuilder CreateBuilder() { - return createBuilderDelegate(); - } - } +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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.Reflection; + +namespace Google.ProtocolBuffers.FieldAccess +{ + /// + /// Accessor for fields representing a non-repeated message value. + /// + internal sealed class SingleMessageAccessor : SinglePrimitiveAccessor + where TMessage : IMessage + where TBuilder : IBuilder + { + /// + /// The static method to create a builder for the property type. For example, + /// in a message type "Foo", a field called "bar" might be of type "Baz". This + /// method is Baz.CreateBuilder. + /// + private readonly Func createBuilderDelegate; + + internal SingleMessageAccessor(string name) : base(name) + { + MethodInfo createBuilderMethod = ClrType.GetMethod("CreateBuilder", EmptyTypes); + if (createBuilderMethod == null) + { + throw new ArgumentException("No public static CreateBuilder method declared in " + ClrType.Name); + } + createBuilderDelegate = ReflectionUtil.CreateStaticUpcastDelegate(createBuilderMethod); + } + + /// + /// Creates a message of the appropriate CLR type from the given value, + /// which may already be of the right type or may be a dynamic message. + /// + private object CoerceType(object value) + { + ThrowHelper.ThrowIfNull(value, "value"); + // If it's already of the right type, we're done + if (ClrType.IsInstanceOfType(value)) + { + return value; + } + + // No... so let's create a builder of the right type, and merge the value in. + IMessageLite message = (IMessageLite) value; + return CreateBuilder().WeakMergeFrom(message).WeakBuild(); + } + + public override void SetValue(TBuilder builder, object value) + { + base.SetValue(builder, CoerceType(value)); + } + + public override IBuilder CreateBuilder() + { + return createBuilderDelegate(); + } + } } \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs b/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs index 1bc1d8ee..25239da5 100644 --- a/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs +++ b/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs @@ -1,120 +1,139 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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.Reflection; - -namespace Google.ProtocolBuffers.FieldAccess { - /// - /// Access for a non-repeated field of a "primitive" type (i.e. not another message or an enum). - /// - internal class SinglePrimitiveAccessor : IFieldAccessor - where TMessage : IMessage - where TBuilder : IBuilder { - - private readonly Type clrType; - private readonly Func getValueDelegate; - private readonly Action setValueDelegate; - private readonly Func hasDelegate; - private readonly Func clearDelegate; - - internal static readonly Type[] EmptyTypes = new Type[0]; - - /// - /// The CLR type of the field (int, the enum type, ByteString, the message etc). - /// As declared by the property. - /// - protected Type ClrType { - get { return clrType; } - } - - internal SinglePrimitiveAccessor(string name) { - PropertyInfo messageProperty = typeof(TMessage).GetProperty(name); - PropertyInfo builderProperty = typeof(TBuilder).GetProperty(name); - if (builderProperty == null) builderProperty = typeof(TBuilder).GetProperty(name); - PropertyInfo hasProperty = typeof(TMessage).GetProperty("Has" + name); - MethodInfo clearMethod = typeof(TBuilder).GetMethod("Clear" + name, EmptyTypes); - if (messageProperty == null || builderProperty == null || hasProperty == null || clearMethod == null) { - throw new ArgumentException("Not all required properties/methods available"); - } - clrType = messageProperty.PropertyType; - hasDelegate = (Func)Delegate.CreateDelegate(typeof(Func), null, hasProperty.GetGetMethod()); - clearDelegate = (Func)Delegate.CreateDelegate(typeof(Func), null ,clearMethod); - getValueDelegate = ReflectionUtil.CreateUpcastDelegate(messageProperty.GetGetMethod()); - setValueDelegate = ReflectionUtil.CreateDowncastDelegate(builderProperty.GetSetMethod()); - } - - public bool Has(TMessage message) { - return hasDelegate(message); - } - - public void Clear(TBuilder builder) { - clearDelegate(builder); - } - - /// - /// Only valid for message types - this implementation throws InvalidOperationException. - /// - public virtual IBuilder CreateBuilder() { - throw new InvalidOperationException(); - } - - public virtual object GetValue(TMessage message) { - return getValueDelegate(message); - } - - public virtual void SetValue(TBuilder builder, object value) { - setValueDelegate(builder, value); - } - - #region Methods only related to repeated values - public int GetRepeatedCount(TMessage message) { - throw new InvalidOperationException(); - } - - public object GetRepeatedValue(TMessage message, int index) { - throw new InvalidOperationException(); - } - - public void SetRepeated(TBuilder builder, int index, object value) { - throw new InvalidOperationException(); - } - - public void AddRepeated(TBuilder builder, object value) { - throw new InvalidOperationException(); - } - - public object GetRepeatedWrapper(TBuilder builder) { - throw new InvalidOperationException(); - } - #endregion - } +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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.Reflection; + +namespace Google.ProtocolBuffers.FieldAccess +{ + /// + /// Access for a non-repeated field of a "primitive" type (i.e. not another message or an enum). + /// + internal class SinglePrimitiveAccessor : IFieldAccessor + where TMessage : IMessage + where TBuilder : IBuilder + { + private readonly Type clrType; + private readonly Func getValueDelegate; + private readonly Action setValueDelegate; + private readonly Func hasDelegate; + private readonly Func clearDelegate; + + internal static readonly Type[] EmptyTypes = new Type[0]; + + /// + /// The CLR type of the field (int, the enum type, ByteString, the message etc). + /// As declared by the property. + /// + protected Type ClrType + { + get { return clrType; } + } + + internal SinglePrimitiveAccessor(string name) + { + PropertyInfo messageProperty = typeof (TMessage).GetProperty(name); + PropertyInfo builderProperty = typeof (TBuilder).GetProperty(name); + if (builderProperty == null) builderProperty = typeof (TBuilder).GetProperty(name); + PropertyInfo hasProperty = typeof (TMessage).GetProperty("Has" + name); + MethodInfo clearMethod = typeof (TBuilder).GetMethod("Clear" + name, EmptyTypes); + if (messageProperty == null || builderProperty == null || hasProperty == null || clearMethod == null) + { + throw new ArgumentException("Not all required properties/methods available"); + } + clrType = messageProperty.PropertyType; + hasDelegate = + (Func) + Delegate.CreateDelegate(typeof (Func), null, hasProperty.GetGetMethod()); + clearDelegate = + (Func) Delegate.CreateDelegate(typeof (Func), null, clearMethod); + getValueDelegate = ReflectionUtil.CreateUpcastDelegate(messageProperty.GetGetMethod()); + setValueDelegate = ReflectionUtil.CreateDowncastDelegate(builderProperty.GetSetMethod()); + } + + public bool Has(TMessage message) + { + return hasDelegate(message); + } + + public void Clear(TBuilder builder) + { + clearDelegate(builder); + } + + /// + /// Only valid for message types - this implementation throws InvalidOperationException. + /// + public virtual IBuilder CreateBuilder() + { + throw new InvalidOperationException(); + } + + public virtual object GetValue(TMessage message) + { + return getValueDelegate(message); + } + + public virtual void SetValue(TBuilder builder, object value) + { + setValueDelegate(builder, value); + } + + #region Methods only related to repeated values + + public int GetRepeatedCount(TMessage message) + { + throw new InvalidOperationException(); + } + + public object GetRepeatedValue(TMessage message, int index) + { + throw new InvalidOperationException(); + } + + public void SetRepeated(TBuilder builder, int index, object value) + { + throw new InvalidOperationException(); + } + + public void AddRepeated(TBuilder builder, object value) + { + throw new InvalidOperationException(); + } + + public object GetRepeatedWrapper(TBuilder builder) + { + throw new InvalidOperationException(); + } + + #endregion + } } \ No newline at end of file diff --git a/src/ProtocolBuffers/FieldSet.cs b/src/ProtocolBuffers/FieldSet.cs index c3e3d740..5704d63e 100644 --- a/src/ProtocolBuffers/FieldSet.cs +++ b/src/ProtocolBuffers/FieldSet.cs @@ -1,515 +1,642 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using Google.ProtocolBuffers.Collections; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers { - - public interface IFieldDescriptorLite : IComparable { - bool IsRepeated { get; } - bool IsRequired { get; } - bool IsPacked { get; } - bool IsExtension { get; } - bool MessageSetWireFormat { get; } //field.ContainingType.Options.MessageSetWireFormat - int FieldNumber { get; } - string FullName { get; } - IEnumLiteMap EnumType { get; } - FieldType FieldType { get; } - MappedType MappedType { get; } - object DefaultValue { get; } - } - - /// - /// A class which represents an arbitrary set of fields of some message type. - /// This is used to implement DynamicMessage, and also to represent extensions - /// in GeneratedMessage. This class is internal, since outside users should probably - /// be using DynamicMessage. - /// - /// As in the Java implementation, this class goes against the rest of the framework - /// in terms of mutability. Instead of having a mutable Builder class and an immutable - /// FieldSet class, FieldSet just has a MakeImmutable() method. This is safe so long as - /// all callers are careful not to let a mutable FieldSet escape into the open. This would - /// be impossible to guarantee if this were a public class, of course. - /// - /// All repeated fields are stored as IList[object] even - /// TODO(jonskeet): Finish this comment! - /// - internal sealed class FieldSet { - - private static readonly FieldSet defaultInstance = new FieldSet(new Dictionary()).MakeImmutable(); - - private IDictionary fields; - - private FieldSet(IDictionary fields) { - this.fields = fields; - } - - public static FieldSet CreateInstance() { - // Use SortedList to keep fields in the canonical order - return new FieldSet(new SortedList()); - } - - /// - /// Makes this FieldSet immutable, and returns it for convenience. Any - /// mutable repeated fields are made immutable, as well as the map itself. - /// - internal FieldSet MakeImmutable() { - // First check if we have any repeated values - bool hasRepeats = false; - foreach (object value in fields.Values) { - IList list = value as IList; - if (list != null && !list.IsReadOnly) { - hasRepeats = true; - break; - } - } - - if (hasRepeats) { - var tmp = new SortedList(); - foreach (KeyValuePair entry in fields) { - IList list = entry.Value as IList; - tmp[entry.Key] = list == null ? entry.Value : Lists.AsReadOnly(list); - } - fields = tmp; - } - - fields = Dictionaries.AsReadOnly(fields); - - return this; - } - - /// - /// Returns the default, immutable instance with no fields defined. - /// - internal static FieldSet DefaultInstance { - get { return defaultInstance; } - } - - /// - /// Returns an immutable mapping of fields. Note that although the mapping itself - /// is immutable, the entries may not be (i.e. any repeated values are represented by - /// mutable lists). The behaviour is not specified if the contents are mutated. - /// - internal IDictionary AllFields { - get { return Dictionaries.AsReadOnly(fields); } - } -#if !LITE - /// - /// Force coercion to full descriptor dictionary. - /// - internal IDictionary AllFieldDescriptors { - get { - SortedList copy = new SortedList(); - foreach (KeyValuePair fd in fields) - copy.Add((Descriptors.FieldDescriptor)fd.Key, fd.Value); - return Dictionaries.AsReadOnly(copy); - } - } -#endif - /// - /// See . - /// - public bool HasField(IFieldDescriptorLite field) { - if (field.IsRepeated) { - throw new ArgumentException("HasField() can only be called on non-repeated fields."); - } - - return fields.ContainsKey(field); - } - - /// - /// Clears all fields. - /// - internal void Clear() { - fields.Clear(); - } - - /// - /// See - /// - /// - /// If the field is not set, the behaviour when fetching this property varies by field type: - /// - /// For singular message values, null is returned. - /// For singular non-message values, the default value of the field is returned. - /// For repeated values, an empty immutable list is returned. This will be compatible - /// with IList[object], regardless of the type of the repeated item. - /// - /// This method returns null if the field is a singular message type - /// and is not set; in this case it is up to the caller to fetch the - /// message's default instance. For repeated fields of message types, - /// an empty collection is returned. For repeated fields of non-message - /// types, null is returned. - /// - /// When setting this property, any list values are copied, and each element is checked - /// to ensure it is of an appropriate type. - /// - /// - internal object this[IFieldDescriptorLite field] { - get { - object result; - if (fields.TryGetValue(field, out result)) { - return result; - } - if (field.MappedType == MappedType.Message) { - if (field.IsRepeated) { - return new List(); - } else { - return null; - } - } - return field.DefaultValue; - } - set { - if (field.IsRepeated) { - List list = value as List; - if (list == null) { - throw new ArgumentException("Wrong object type used with protocol message reflection."); - } - - // Wrap the contents in a new list so that the caller cannot change - // the list's contents after setting it. - List newList = new List(list); - foreach (object element in newList) { - VerifyType(field, element); - } - value = newList; - } - else { - VerifyType(field, value); - } - fields[field] = value; - } - } - - /// - /// See - /// - internal object this[IFieldDescriptorLite field, int index] { - get { - if (!field.IsRepeated) { - throw new ArgumentException("Indexer specifying field and index can only be called on repeated fields."); - } - - return ((IList) this[field])[index]; - } - set { - if (!field.IsRepeated) { - throw new ArgumentException("Indexer specifying field and index can only be called on repeated fields."); - } - VerifyType(field, value); - object list; - if (!fields.TryGetValue(field, out list)) { - throw new ArgumentOutOfRangeException(); - } - ((IList) list)[index] = value; - } - } - - /// - /// See - /// - internal void AddRepeatedField(IFieldDescriptorLite field, object value) { - if (!field.IsRepeated) { - throw new ArgumentException("AddRepeatedField can only be called on repeated fields."); - } - VerifyType(field, value); - object list; - if (!fields.TryGetValue(field, out list)) { - list = new List(); - fields[field] = list; - } - ((IList) list).Add(value); - } - - /// - /// Returns an enumerator for the field map. Used to write the fields out. - /// - internal IEnumerator> GetEnumerator() { - return fields.GetEnumerator(); - } - - /// - /// See - /// - /// - /// Since FieldSet itself does not have any way of knowing about - /// required fields that aren't actually present in the set, it is up - /// to the caller to check for genuinely required fields. This property - /// merely checks that any messages present are themselves initialized. - /// - internal bool IsInitialized { - get { - foreach (KeyValuePair entry in fields) { - IFieldDescriptorLite field = entry.Key; - if (field.MappedType == MappedType.Message) { - if (field.IsRepeated) { - foreach(IMessageLite message in (IEnumerable) entry.Value) { - if (!message.IsInitialized) { - return false; - } - } - } else { - if (!((IMessageLite)entry.Value).IsInitialized) { - return false; - } - } - } - } - return true; - } - } - - /// - /// Verifies whether all the required fields in the specified message - /// descriptor are present in this field set, as well as whether - /// all the embedded messages are themselves initialized. - /// - internal bool IsInitializedWithRespectTo(IEnumerable typeFields) { - foreach (IFieldDescriptorLite field in typeFields) { - if (field.IsRequired && !HasField(field)) { - return false; - } - } - return IsInitialized; - } - - /// - /// See - /// - public void ClearField(IFieldDescriptorLite field) { - fields.Remove(field); - } - - /// - /// See - /// - public int GetRepeatedFieldCount(IFieldDescriptorLite field) { - if (!field.IsRepeated) { - throw new ArgumentException("GetRepeatedFieldCount() can only be called on repeated fields."); - } - - return ((IList) this[field]).Count; - } - -#if !LITE - /// - /// See - /// - public void MergeFrom(IMessage other) { - foreach (KeyValuePair fd in other.AllFields) - MergeField(fd.Key, fd.Value); - } -#endif - - /// - /// Implementation of both MergeFrom methods. - /// - /// - public void MergeFrom(FieldSet other) { - // 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 IMessageLite 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 entry in other.fields) { - MergeField(entry.Key, entry.Value); - } - } - - private void MergeField(IFieldDescriptorLite field, object mergeValue) { - object existingValue; - fields.TryGetValue(field, out existingValue); - if (field.IsRepeated) { - if (existingValue == null) { - existingValue = new List(); - fields[field] = existingValue; - } - IList list = (IList) existingValue; - foreach (object otherValue in (IEnumerable)mergeValue) { - list.Add(otherValue); - } - } else if (field.MappedType == MappedType.Message && existingValue != null) { - IMessageLite existingMessage = (IMessageLite)existingValue; - IMessageLite merged = existingMessage.WeakToBuilder() - .WeakMergeFrom((IMessageLite)mergeValue) - .WeakBuild(); - this[field] = merged; - } else { - this[field] = mergeValue; - } - } - - /// - /// See . - /// - public void WriteTo(CodedOutputStream output) { - foreach (KeyValuePair entry in fields) { - WriteField(entry.Key, entry.Value, output); - } - } - - /// - /// Writes a single field to a CodedOutputStream. - /// - public void WriteField(IFieldDescriptorLite field, Object value, CodedOutputStream output) { - if (field.IsExtension && field.MessageSetWireFormat) { - output.WriteMessageSetExtension(field.FieldNumber, (IMessageLite) value); - } else { - if (field.IsRepeated) { - IEnumerable valueList = (IEnumerable) value; - if (field.IsPacked) { - output.WriteTag(field.FieldNumber, WireFormat.WireType.LengthDelimited); - // Compute the total data size so the length can be written. - int dataSize = 0; - foreach (object element in valueList) { - dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element); - } - output.WriteRawVarint32((uint)dataSize); - // Write the data itself, without any tags. - 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, value); - } - } - } - - /// - /// See . It's up to the caller to - /// cache the resulting size if desired. - /// - public int SerializedSize { - get { - int size = 0; - foreach (KeyValuePair entry in fields) { - IFieldDescriptorLite field = entry.Key; - object value = entry.Value; - - if (field.IsExtension && field.MessageSetWireFormat) { - size += CodedOutputStream.ComputeMessageSetExtensionSize(field.FieldNumber, (IMessageLite)value); - } else { - if (field.IsRepeated) { - IEnumerable valueList = (IEnumerable)value; - if (field.IsPacked) { - int dataSize = 0; - foreach (object element in valueList) { - dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element); - } - size += dataSize + CodedOutputStream.ComputeTagSize(field.FieldNumber) + 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, value); - } - } - } - return size; - } - } - - /// - /// Verifies that the given object is of the correct type to be a valid - /// value for the given field. - /// - /// - /// For repeated fields, this checks if the object is of the right - /// element type, not whether it's a list. - /// - /// The value is not of the right type. - /// The value is null. - private static void VerifyType(IFieldDescriptorLite field, object value) { - ThrowHelper.ThrowIfNull(value, "value"); - bool isValid = false; - switch (field.MappedType) { - case MappedType.Int32: isValid = value is int; break; - case MappedType.Int64: isValid = value is long; break; - case MappedType.UInt32: isValid = value is uint; break; - case MappedType.UInt64: isValid = value is ulong; break; - case MappedType.Single: isValid = value is float; break; - case MappedType.Double: isValid = value is double; break; - case MappedType.Boolean: isValid = value is bool; break; - case MappedType.String: isValid = value is string; break; - case MappedType.ByteString: isValid = value is ByteString; break; - case MappedType.Enum: - IEnumLite enumValue = value as IEnumLite; - isValid = enumValue != null && field.EnumType.IsValidValue(enumValue); - break; - case MappedType.Message: - IMessageLite messageValue = value as IMessageLite; - isValid = messageValue != null; -#if !LITE - if (isValid && messageValue is IMessage && field is FieldDescriptor) { - isValid = ((IMessage) messageValue).DescriptorForType == ((FieldDescriptor) field).MessageType; - } -#endif - break; - } - - if (!isValid) { - // When chaining calls to SetField(), it can be hard to tell from - // the stack trace which exact call failed, since the whole chain is - // considered one line of code. So, let's make sure to include the - // field name and other useful info in the exception. - string message = "Wrong object type used with protocol message reflection."; -#if !LITE - Google.ProtocolBuffers.Descriptors.FieldDescriptor fieldinfo = field as Google.ProtocolBuffers.Descriptors.FieldDescriptor; - if (fieldinfo != null) { - message += "Message type \"" + fieldinfo.ContainingType.FullName; - message += "\", field \"" + (fieldinfo.IsExtension ? fieldinfo.FullName : fieldinfo.Name); - message += "\", value was type \"" + value.GetType().Name + "\"."; - } -#endif - throw new ArgumentException(message); - } - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using Google.ProtocolBuffers.Collections; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + public interface IFieldDescriptorLite : IComparable + { + bool IsRepeated { get; } + bool IsRequired { get; } + bool IsPacked { get; } + bool IsExtension { get; } + bool MessageSetWireFormat { get; } //field.ContainingType.Options.MessageSetWireFormat + int FieldNumber { get; } + string FullName { get; } + IEnumLiteMap EnumType { get; } + FieldType FieldType { get; } + MappedType MappedType { get; } + object DefaultValue { get; } + } + + /// + /// A class which represents an arbitrary set of fields of some message type. + /// This is used to implement DynamicMessage, and also to represent extensions + /// in GeneratedMessage. This class is internal, since outside users should probably + /// be using DynamicMessage. + /// + /// As in the Java implementation, this class goes against the rest of the framework + /// in terms of mutability. Instead of having a mutable Builder class and an immutable + /// FieldSet class, FieldSet just has a MakeImmutable() method. This is safe so long as + /// all callers are careful not to let a mutable FieldSet escape into the open. This would + /// be impossible to guarantee if this were a public class, of course. + /// + /// All repeated fields are stored as IList[object] even + /// TODO(jonskeet): Finish this comment! + /// + internal sealed class FieldSet + { + private static readonly FieldSet defaultInstance = + new FieldSet(new Dictionary()).MakeImmutable(); + + private IDictionary fields; + + private FieldSet(IDictionary fields) + { + this.fields = fields; + } + + public static FieldSet CreateInstance() + { + // Use SortedList to keep fields in the canonical order + return new FieldSet(new SortedList()); + } + + /// + /// Makes this FieldSet immutable, and returns it for convenience. Any + /// mutable repeated fields are made immutable, as well as the map itself. + /// + internal FieldSet MakeImmutable() + { + // First check if we have any repeated values + bool hasRepeats = false; + foreach (object value in fields.Values) + { + IList list = value as IList; + if (list != null && !list.IsReadOnly) + { + hasRepeats = true; + break; + } + } + + if (hasRepeats) + { + var tmp = new SortedList(); + foreach (KeyValuePair entry in fields) + { + IList list = entry.Value as IList; + tmp[entry.Key] = list == null ? entry.Value : Lists.AsReadOnly(list); + } + fields = tmp; + } + + fields = Dictionaries.AsReadOnly(fields); + + return this; + } + + /// + /// Returns the default, immutable instance with no fields defined. + /// + internal static FieldSet DefaultInstance + { + get { return defaultInstance; } + } + + /// + /// Returns an immutable mapping of fields. Note that although the mapping itself + /// is immutable, the entries may not be (i.e. any repeated values are represented by + /// mutable lists). The behaviour is not specified if the contents are mutated. + /// + internal IDictionary AllFields + { + get { return Dictionaries.AsReadOnly(fields); } + } + +#if !LITE + /// + /// Force coercion to full descriptor dictionary. + /// + internal IDictionary AllFieldDescriptors + { + get + { + SortedList copy = + new SortedList(); + foreach (KeyValuePair fd in fields) + copy.Add((Descriptors.FieldDescriptor) fd.Key, fd.Value); + return Dictionaries.AsReadOnly(copy); + } + } +#endif + + /// + /// See . + /// + public bool HasField(IFieldDescriptorLite field) + { + if (field.IsRepeated) + { + throw new ArgumentException("HasField() can only be called on non-repeated fields."); + } + + return fields.ContainsKey(field); + } + + /// + /// Clears all fields. + /// + internal void Clear() + { + fields.Clear(); + } + + /// + /// See + /// + /// + /// If the field is not set, the behaviour when fetching this property varies by field type: + /// + /// For singular message values, null is returned. + /// For singular non-message values, the default value of the field is returned. + /// For repeated values, an empty immutable list is returned. This will be compatible + /// with IList[object], regardless of the type of the repeated item. + /// + /// This method returns null if the field is a singular message type + /// and is not set; in this case it is up to the caller to fetch the + /// message's default instance. For repeated fields of message types, + /// an empty collection is returned. For repeated fields of non-message + /// types, null is returned. + /// + /// When setting this property, any list values are copied, and each element is checked + /// to ensure it is of an appropriate type. + /// + /// + internal object this[IFieldDescriptorLite field] + { + get + { + object result; + if (fields.TryGetValue(field, out result)) + { + return result; + } + if (field.MappedType == MappedType.Message) + { + if (field.IsRepeated) + { + return new List(); + } + else + { + return null; + } + } + return field.DefaultValue; + } + set + { + if (field.IsRepeated) + { + List list = value as List; + if (list == null) + { + throw new ArgumentException("Wrong object type used with protocol message reflection."); + } + + // Wrap the contents in a new list so that the caller cannot change + // the list's contents after setting it. + List newList = new List(list); + foreach (object element in newList) + { + VerifyType(field, element); + } + value = newList; + } + else + { + VerifyType(field, value); + } + fields[field] = value; + } + } + + /// + /// See + /// + internal object this[IFieldDescriptorLite field, int index] + { + get + { + if (!field.IsRepeated) + { + throw new ArgumentException( + "Indexer specifying field and index can only be called on repeated fields."); + } + + return ((IList) this[field])[index]; + } + set + { + if (!field.IsRepeated) + { + throw new ArgumentException( + "Indexer specifying field and index can only be called on repeated fields."); + } + VerifyType(field, value); + object list; + if (!fields.TryGetValue(field, out list)) + { + throw new ArgumentOutOfRangeException(); + } + ((IList) list)[index] = value; + } + } + + /// + /// See + /// + internal void AddRepeatedField(IFieldDescriptorLite field, object value) + { + if (!field.IsRepeated) + { + throw new ArgumentException("AddRepeatedField can only be called on repeated fields."); + } + VerifyType(field, value); + object list; + if (!fields.TryGetValue(field, out list)) + { + list = new List(); + fields[field] = list; + } + ((IList) list).Add(value); + } + + /// + /// Returns an enumerator for the field map. Used to write the fields out. + /// + internal IEnumerator> GetEnumerator() + { + return fields.GetEnumerator(); + } + + /// + /// See + /// + /// + /// Since FieldSet itself does not have any way of knowing about + /// required fields that aren't actually present in the set, it is up + /// to the caller to check for genuinely required fields. This property + /// merely checks that any messages present are themselves initialized. + /// + internal bool IsInitialized + { + get + { + foreach (KeyValuePair entry in fields) + { + IFieldDescriptorLite field = entry.Key; + if (field.MappedType == MappedType.Message) + { + if (field.IsRepeated) + { + foreach (IMessageLite message in (IEnumerable) entry.Value) + { + if (!message.IsInitialized) + { + return false; + } + } + } + else + { + if (!((IMessageLite) entry.Value).IsInitialized) + { + return false; + } + } + } + } + return true; + } + } + + /// + /// Verifies whether all the required fields in the specified message + /// descriptor are present in this field set, as well as whether + /// all the embedded messages are themselves initialized. + /// + internal bool IsInitializedWithRespectTo(IEnumerable typeFields) + { + foreach (IFieldDescriptorLite field in typeFields) + { + if (field.IsRequired && !HasField(field)) + { + return false; + } + } + return IsInitialized; + } + + /// + /// See + /// + public void ClearField(IFieldDescriptorLite field) + { + fields.Remove(field); + } + + /// + /// See + /// + public int GetRepeatedFieldCount(IFieldDescriptorLite field) + { + if (!field.IsRepeated) + { + throw new ArgumentException("GetRepeatedFieldCount() can only be called on repeated fields."); + } + + return ((IList) this[field]).Count; + } + +#if !LITE + /// + /// See + /// + public void MergeFrom(IMessage other) + { + foreach (KeyValuePair fd in other.AllFields) + MergeField(fd.Key, fd.Value); + } +#endif + + /// + /// Implementation of both MergeFrom methods. + /// + /// + public void MergeFrom(FieldSet other) + { + // 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 IMessageLite 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 entry in other.fields) + { + MergeField(entry.Key, entry.Value); + } + } + + private void MergeField(IFieldDescriptorLite field, object mergeValue) + { + object existingValue; + fields.TryGetValue(field, out existingValue); + if (field.IsRepeated) + { + if (existingValue == null) + { + existingValue = new List(); + fields[field] = existingValue; + } + IList list = (IList) existingValue; + foreach (object otherValue in (IEnumerable) mergeValue) + { + list.Add(otherValue); + } + } + else if (field.MappedType == MappedType.Message && existingValue != null) + { + IMessageLite existingMessage = (IMessageLite) existingValue; + IMessageLite merged = existingMessage.WeakToBuilder() + .WeakMergeFrom((IMessageLite) mergeValue) + .WeakBuild(); + this[field] = merged; + } + else + { + this[field] = mergeValue; + } + } + + /// + /// See . + /// + public void WriteTo(CodedOutputStream output) + { + foreach (KeyValuePair entry in fields) + { + WriteField(entry.Key, entry.Value, output); + } + } + + /// + /// Writes a single field to a CodedOutputStream. + /// + public void WriteField(IFieldDescriptorLite field, Object value, CodedOutputStream output) + { + if (field.IsExtension && field.MessageSetWireFormat) + { + output.WriteMessageSetExtension(field.FieldNumber, (IMessageLite) value); + } + else + { + if (field.IsRepeated) + { + IEnumerable valueList = (IEnumerable) value; + if (field.IsPacked) + { + output.WriteTag(field.FieldNumber, WireFormat.WireType.LengthDelimited); + // Compute the total data size so the length can be written. + int dataSize = 0; + foreach (object element in valueList) + { + dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element); + } + output.WriteRawVarint32((uint) dataSize); + // Write the data itself, without any tags. + 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, value); + } + } + } + + /// + /// See . It's up to the caller to + /// cache the resulting size if desired. + /// + public int SerializedSize + { + get + { + int size = 0; + foreach (KeyValuePair entry in fields) + { + IFieldDescriptorLite field = entry.Key; + object value = entry.Value; + + if (field.IsExtension && field.MessageSetWireFormat) + { + size += CodedOutputStream.ComputeMessageSetExtensionSize(field.FieldNumber, (IMessageLite) value); + } + else + { + if (field.IsRepeated) + { + IEnumerable valueList = (IEnumerable) value; + if (field.IsPacked) + { + int dataSize = 0; + foreach (object element in valueList) + { + dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element); + } + size += dataSize + CodedOutputStream.ComputeTagSize(field.FieldNumber) + + 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, value); + } + } + } + return size; + } + } + + /// + /// Verifies that the given object is of the correct type to be a valid + /// value for the given field. + /// + /// + /// For repeated fields, this checks if the object is of the right + /// element type, not whether it's a list. + /// + /// The value is not of the right type. + /// The value is null. + private static void VerifyType(IFieldDescriptorLite field, object value) + { + ThrowHelper.ThrowIfNull(value, "value"); + bool isValid = false; + switch (field.MappedType) + { + case MappedType.Int32: + isValid = value is int; + break; + case MappedType.Int64: + isValid = value is long; + break; + case MappedType.UInt32: + isValid = value is uint; + break; + case MappedType.UInt64: + isValid = value is ulong; + break; + case MappedType.Single: + isValid = value is float; + break; + case MappedType.Double: + isValid = value is double; + break; + case MappedType.Boolean: + isValid = value is bool; + break; + case MappedType.String: + isValid = value is string; + break; + case MappedType.ByteString: + isValid = value is ByteString; + break; + case MappedType.Enum: + IEnumLite enumValue = value as IEnumLite; + isValid = enumValue != null && field.EnumType.IsValidValue(enumValue); + break; + case MappedType.Message: + IMessageLite messageValue = value as IMessageLite; + isValid = messageValue != null; +#if !LITE + if (isValid && messageValue is IMessage && field is FieldDescriptor) + { + isValid = ((IMessage) messageValue).DescriptorForType == ((FieldDescriptor) field).MessageType; + } +#endif + break; + } + + if (!isValid) + { + // When chaining calls to SetField(), it can be hard to tell from + // the stack trace which exact call failed, since the whole chain is + // considered one line of code. So, let's make sure to include the + // field name and other useful info in the exception. + string message = "Wrong object type used with protocol message reflection."; +#if !LITE + Google.ProtocolBuffers.Descriptors.FieldDescriptor fieldinfo = + field as Google.ProtocolBuffers.Descriptors.FieldDescriptor; + if (fieldinfo != null) + { + message += "Message type \"" + fieldinfo.ContainingType.FullName; + message += "\", field \"" + (fieldinfo.IsExtension ? fieldinfo.FullName : fieldinfo.Name); + message += "\", value was type \"" + value.GetType().Name + "\"."; + } +#endif + throw new ArgumentException(message); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedBuilder.cs b/src/ProtocolBuffers/GeneratedBuilder.cs index 2ec2762f..b44cd639 100644 --- a/src/ProtocolBuffers/GeneratedBuilder.cs +++ b/src/ProtocolBuffers/GeneratedBuilder.cs @@ -1,210 +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; -using System.Collections; -using System.Collections.Generic; -using Google.ProtocolBuffers.Descriptors; -using Google.ProtocolBuffers.FieldAccess; - -namespace Google.ProtocolBuffers { - /// - /// All generated protocol message builder classes extend this class. It implements - /// most of the IBuilder interface using reflection. Users can ignore this class - /// as an implementation detail. - /// - public abstract class GeneratedBuilder : AbstractBuilder - where TMessage : GeneratedMessage - where TBuilder : GeneratedBuilder { - - /// - /// Returns the message being built at the moment. - /// - protected abstract TMessage MessageBeingBuilt { get; } - - protected internal FieldAccessorTable InternalFieldAccessors { - get { return MessageBeingBuilt.FieldAccessorsFromBuilder; } - } - - public override bool IsInitialized { - get { return MessageBeingBuilt.IsInitialized; } - } - - public override IDictionary AllFields { - get { return MessageBeingBuilt.AllFields; } - } - - public override object this[FieldDescriptor field] { - get { - // For repeated fields, the underlying list object is still modifiable at this point. - // Make sure not to expose the modifiable list to the caller. - return field.IsRepeated - ? InternalFieldAccessors[field].GetRepeatedWrapper(ThisBuilder) - : MessageBeingBuilt[field]; - } - set { - InternalFieldAccessors[field].SetValue(ThisBuilder, value); - } - } - - /// - /// Adds all of the specified values to the given collection. - /// - /// Any element of the list is null - protected void AddRange(IEnumerable source, IList destination) { - ThrowHelper.ThrowIfNull(source); - // We only need to check this for nullable types. - if (default(T) == null) { - ThrowHelper.ThrowIfAnyNull(source); - } - List list = destination as List; - if (list != null) { - list.AddRange(source); - } else { - foreach (T element in source) { - destination.Add(element); - } - } - } - - /// - /// Called by derived classes to parse an unknown field. - /// - /// true unless the tag is an end-group tag - [CLSCompliant(false)] - protected virtual bool ParseUnknownField(CodedInputStream input, UnknownFieldSet.Builder unknownFields, - ExtensionRegistry extensionRegistry, uint tag) { - return unknownFields.MergeFieldFrom(tag, input); - } - - public override MessageDescriptor DescriptorForType { - get { return MessageBeingBuilt.DescriptorForType; } - } - - public override int GetRepeatedFieldCount(FieldDescriptor field) { - return MessageBeingBuilt.GetRepeatedFieldCount(field); - } - - public override object this[FieldDescriptor field, int index] { - get { return MessageBeingBuilt[field, index]; } - set { InternalFieldAccessors[field].SetRepeated(ThisBuilder, index, value); } - } - - public override bool HasField(FieldDescriptor field) { - return MessageBeingBuilt.HasField(field); - } - - public override IBuilder CreateBuilderForField(FieldDescriptor field) { - return InternalFieldAccessors[field].CreateBuilder(); - } - - public override TBuilder ClearField(FieldDescriptor field) { - InternalFieldAccessors[field].Clear(ThisBuilder); - return ThisBuilder; - } - - public override TBuilder MergeFrom(TMessage other) { - if (other.DescriptorForType != InternalFieldAccessors.Descriptor) { - throw new ArgumentException("Message type mismatch"); - } - - foreach (KeyValuePair 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 && HasField(field)) { - // Merge singular embedded messages - IMessageLite oldValue = (IMessageLite)this[field]; - this[field] = oldValue.WeakCreateBuilderForType() - .WeakMergeFrom(oldValue) - .WeakMergeFrom((IMessageLite)entry.Value) - .WeakBuildPartial(); - } else { - // Just overwrite - this[field] = entry.Value; - } - } - - //Fix for unknown fields not merging, see java's AbstractMessage.Builder line 236 - MergeUnknownFields(other.UnknownFields); - - return ThisBuilder; - } - - public override TBuilder MergeUnknownFields(UnknownFieldSet unknownFields) { - if (unknownFields != UnknownFieldSet.DefaultInstance) { - TMessage result = MessageBeingBuilt; - result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields) - .MergeFrom(unknownFields) - .Build()); - } - return ThisBuilder; - } - - public override TBuilder AddRepeatedField(FieldDescriptor field, object value) { - InternalFieldAccessors[field].AddRepeated(ThisBuilder, value); - return ThisBuilder; - } - - /// - /// Like Build(), but will wrap UninitializedMessageException in - /// InvalidProtocolBufferException. - /// - public TMessage BuildParsed() { - if (!IsInitialized) { - throw new UninitializedMessageException(MessageBeingBuilt).AsInvalidProtocolBufferException(); - } - return BuildPartial(); - } - - /// - /// Implementation of . - /// - public override TMessage Build() { - // If the message is null, we'll throw a more appropriate exception in BuildPartial. - if (MessageBeingBuilt != null && !IsInitialized) { - throw new UninitializedMessageException(MessageBeingBuilt); - } - return BuildPartial(); - } - - public override UnknownFieldSet UnknownFields { - get { return MessageBeingBuilt.UnknownFields; } - set { MessageBeingBuilt.SetUnknownFields(value); } - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using Google.ProtocolBuffers.Descriptors; +using Google.ProtocolBuffers.FieldAccess; + +namespace Google.ProtocolBuffers +{ + /// + /// All generated protocol message builder classes extend this class. It implements + /// most of the IBuilder interface using reflection. Users can ignore this class + /// as an implementation detail. + /// + public abstract class GeneratedBuilder : AbstractBuilder + where TMessage : GeneratedMessage + where TBuilder : GeneratedBuilder + { + /// + /// Returns the message being built at the moment. + /// + protected abstract TMessage MessageBeingBuilt { get; } + + protected internal FieldAccessorTable InternalFieldAccessors + { + get { return MessageBeingBuilt.FieldAccessorsFromBuilder; } + } + + public override bool IsInitialized + { + get { return MessageBeingBuilt.IsInitialized; } + } + + public override IDictionary AllFields + { + get { return MessageBeingBuilt.AllFields; } + } + + public override object this[FieldDescriptor field] + { + get + { + // For repeated fields, the underlying list object is still modifiable at this point. + // Make sure not to expose the modifiable list to the caller. + return field.IsRepeated + ? InternalFieldAccessors[field].GetRepeatedWrapper(ThisBuilder) + : MessageBeingBuilt[field]; + } + set { InternalFieldAccessors[field].SetValue(ThisBuilder, value); } + } + + /// + /// Adds all of the specified values to the given collection. + /// + /// Any element of the list is null + protected void AddRange(IEnumerable source, IList destination) + { + ThrowHelper.ThrowIfNull(source); + // We only need to check this for nullable types. + if (default(T) == null) + { + ThrowHelper.ThrowIfAnyNull(source); + } + List list = destination as List; + if (list != null) + { + list.AddRange(source); + } + else + { + foreach (T element in source) + { + destination.Add(element); + } + } + } + + /// + /// Called by derived classes to parse an unknown field. + /// + /// true unless the tag is an end-group tag + [CLSCompliant(false)] + protected virtual bool ParseUnknownField(CodedInputStream input, UnknownFieldSet.Builder unknownFields, + ExtensionRegistry extensionRegistry, uint tag) + { + return unknownFields.MergeFieldFrom(tag, input); + } + + public override MessageDescriptor DescriptorForType + { + get { return MessageBeingBuilt.DescriptorForType; } + } + + public override int GetRepeatedFieldCount(FieldDescriptor field) + { + return MessageBeingBuilt.GetRepeatedFieldCount(field); + } + + public override object this[FieldDescriptor field, int index] + { + get { return MessageBeingBuilt[field, index]; } + set { InternalFieldAccessors[field].SetRepeated(ThisBuilder, index, value); } + } + + public override bool HasField(FieldDescriptor field) + { + return MessageBeingBuilt.HasField(field); + } + + public override IBuilder CreateBuilderForField(FieldDescriptor field) + { + return InternalFieldAccessors[field].CreateBuilder(); + } + + public override TBuilder ClearField(FieldDescriptor field) + { + InternalFieldAccessors[field].Clear(ThisBuilder); + return ThisBuilder; + } + + public override TBuilder MergeFrom(TMessage other) + { + if (other.DescriptorForType != InternalFieldAccessors.Descriptor) + { + throw new ArgumentException("Message type mismatch"); + } + + foreach (KeyValuePair 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 && HasField(field)) + { + // Merge singular embedded messages + IMessageLite oldValue = (IMessageLite) this[field]; + this[field] = oldValue.WeakCreateBuilderForType() + .WeakMergeFrom(oldValue) + .WeakMergeFrom((IMessageLite) entry.Value) + .WeakBuildPartial(); + } + else + { + // Just overwrite + this[field] = entry.Value; + } + } + + //Fix for unknown fields not merging, see java's AbstractMessage.Builder line 236 + MergeUnknownFields(other.UnknownFields); + + return ThisBuilder; + } + + public override TBuilder MergeUnknownFields(UnknownFieldSet unknownFields) + { + if (unknownFields != UnknownFieldSet.DefaultInstance) + { + TMessage result = MessageBeingBuilt; + result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields) + .MergeFrom(unknownFields) + .Build()); + } + return ThisBuilder; + } + + public override TBuilder AddRepeatedField(FieldDescriptor field, object value) + { + InternalFieldAccessors[field].AddRepeated(ThisBuilder, value); + return ThisBuilder; + } + + /// + /// Like Build(), but will wrap UninitializedMessageException in + /// InvalidProtocolBufferException. + /// + public TMessage BuildParsed() + { + if (!IsInitialized) + { + throw new UninitializedMessageException(MessageBeingBuilt).AsInvalidProtocolBufferException(); + } + return BuildPartial(); + } + + /// + /// Implementation of . + /// + public override TMessage Build() + { + // If the message is null, we'll throw a more appropriate exception in BuildPartial. + if (MessageBeingBuilt != null && !IsInitialized) + { + throw new UninitializedMessageException(MessageBeingBuilt); + } + return BuildPartial(); + } + + public override UnknownFieldSet UnknownFields + { + get { return MessageBeingBuilt.UnknownFields; } + set { MessageBeingBuilt.SetUnknownFields(value); } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedBuilderLite.cs b/src/ProtocolBuffers/GeneratedBuilderLite.cs index d721fddd..1641b28a 100644 --- a/src/ProtocolBuffers/GeneratedBuilderLite.cs +++ b/src/ProtocolBuffers/GeneratedBuilderLite.cs @@ -1,117 +1,133 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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; - -namespace Google.ProtocolBuffers { - /// - /// All generated protocol message builder classes extend this class. It implements - /// most of the IBuilder interface using reflection. Users can ignore this class - /// as an implementation detail. - /// - public abstract class GeneratedBuilderLite : AbstractBuilderLite - where TMessage : GeneratedMessageLite - where TBuilder : GeneratedBuilderLite { - - /// - /// Returns the message being built at the moment. - /// - protected abstract TMessage MessageBeingBuilt { get; } - - public override TBuilder MergeFrom(IMessageLite other) { - //do nothing, Lite runtime does not support cross-message merges - return ThisBuilder; - } - - public abstract TBuilder MergeFrom(TMessage other); - - public override bool IsInitialized { - get { return MessageBeingBuilt.IsInitialized; } - } - - /// - /// Adds all of the specified values to the given collection. - /// - /// Any element of the list is null - protected void AddRange(IEnumerable source, IList destination) { - ThrowHelper.ThrowIfNull(source); - // We only need to check this for nullable types. - if (default(T) == null) { - ThrowHelper.ThrowIfAnyNull(source); - } - List list = destination as List; - if (list != null) { - list.AddRange(source); - } else { - foreach (T element in source) { - destination.Add(element); - } - } - } - - /// - /// Called by derived classes to parse an unknown field. - /// - /// true unless the tag is an end-group tag - [CLSCompliant(false)] - protected virtual bool ParseUnknownField(CodedInputStream input, - ExtensionRegistry extensionRegistry, uint tag) { - return input.SkipField(tag); - } - - /// - /// Like Build(), but will wrap UninitializedMessageException in - /// InvalidProtocolBufferException. - /// - public TMessage BuildParsed() { - if (!IsInitialized) { - throw new UninitializedMessageException(MessageBeingBuilt).AsInvalidProtocolBufferException(); - } - return BuildPartial(); - } - - /// - /// Implementation of . - /// - public override TMessage Build() { - // If the message is null, we'll throw a more appropriate exception in BuildPartial. - if (MessageBeingBuilt != null && !IsInitialized) { - throw new UninitializedMessageException(MessageBeingBuilt); - } - return BuildPartial(); - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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; + +namespace Google.ProtocolBuffers +{ + /// + /// All generated protocol message builder classes extend this class. It implements + /// most of the IBuilder interface using reflection. Users can ignore this class + /// as an implementation detail. + /// + public abstract class GeneratedBuilderLite : AbstractBuilderLite + where TMessage : GeneratedMessageLite + where TBuilder : GeneratedBuilderLite + { + /// + /// Returns the message being built at the moment. + /// + protected abstract TMessage MessageBeingBuilt { get; } + + public override TBuilder MergeFrom(IMessageLite other) + { + //do nothing, Lite runtime does not support cross-message merges + return ThisBuilder; + } + + public abstract TBuilder MergeFrom(TMessage other); + + public override bool IsInitialized + { + get { return MessageBeingBuilt.IsInitialized; } + } + + /// + /// Adds all of the specified values to the given collection. + /// + /// Any element of the list is null + protected void AddRange(IEnumerable source, IList destination) + { + ThrowHelper.ThrowIfNull(source); + // We only need to check this for nullable types. + if (default(T) == null) + { + ThrowHelper.ThrowIfAnyNull(source); + } + List list = destination as List; + if (list != null) + { + list.AddRange(source); + } + else + { + foreach (T element in source) + { + destination.Add(element); + } + } + } + + /// + /// Called by derived classes to parse an unknown field. + /// + /// true unless the tag is an end-group tag + [CLSCompliant(false)] + protected virtual bool ParseUnknownField(CodedInputStream input, + ExtensionRegistry extensionRegistry, uint tag) + { + return input.SkipField(tag); + } + + /// + /// Like Build(), but will wrap UninitializedMessageException in + /// InvalidProtocolBufferException. + /// + public TMessage BuildParsed() + { + if (!IsInitialized) + { + throw new UninitializedMessageException(MessageBeingBuilt).AsInvalidProtocolBufferException(); + } + return BuildPartial(); + } + + /// + /// Implementation of . + /// + public override TMessage Build() + { + // If the message is null, we'll throw a more appropriate exception in BuildPartial. + if (MessageBeingBuilt != null && !IsInitialized) + { + throw new UninitializedMessageException(MessageBeingBuilt); + } + return BuildPartial(); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedExtensionBase.cs b/src/ProtocolBuffers/GeneratedExtensionBase.cs index aacc0655..53a43de0 100644 --- a/src/ProtocolBuffers/GeneratedExtensionBase.cs +++ b/src/ProtocolBuffers/GeneratedExtensionBase.cs @@ -1,161 +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 System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers { - - /// - /// Base type for all generated extensions. - /// - /// - /// The protocol compiler generates a static singleton instance of this - /// class for each extension. For exmaple, imagine a .proto file with: - /// - /// message Foo { - /// extensions 1000 to max - /// } - /// - /// extend Foo { - /// optional int32 bar; - /// } - /// - /// Then MyProto.Foo.Bar has type GeneratedExtensionBase<MyProto.Foo,int>. - /// - /// In general, users should ignore the details of this type, and - /// simply use the static singletons as parameters to the extension accessors - /// in ExtendableMessage and ExtendableBuilder. - /// The interface implemented by both GeneratedException and GeneratedRepeatException, - /// to make it easier to cope with repeats separately. - /// - public abstract class GeneratedExtensionBase { - - private readonly FieldDescriptor descriptor; - private readonly IMessageLite messageDefaultInstance; - - protected GeneratedExtensionBase(FieldDescriptor descriptor, Type singularExtensionType) { - if (!descriptor.IsExtension) { - throw new ArgumentException("GeneratedExtension given a regular (non-extension) field."); - } - - this.descriptor = descriptor; - if (descriptor.MappedType == MappedType.Message) { - PropertyInfo defaultInstanceProperty = singularExtensionType - .GetProperty("DefaultInstance", BindingFlags.Static | BindingFlags.Public); - if (defaultInstanceProperty == null) { - throw new ArgumentException("No public static DefaultInstance property for type " + typeof(TExtension).Name); - } - - messageDefaultInstance = (IMessageLite)defaultInstanceProperty.GetValue(null, null); - } - } - - public FieldDescriptor Descriptor { - get { return descriptor; } - } - - public int Number { - get { return Descriptor.FieldNumber; } - } - - /// - /// Returns the default message instance for extensions which are message types. - /// - public IMessageLite MessageDefaultInstance { - get { return messageDefaultInstance; } - } - - public object SingularFromReflectionType(object value) { - switch (Descriptor.MappedType) { - case MappedType.Message: - if (value is TExtension) { - return value; - } else { - // It seems the copy of the embedded message stored inside the - // extended message is not of the exact type the user was - // expecting. This can happen if a user defines a - // GeneratedExtension manually and gives it a different type. - // This should not happen in normal use. But, to be nice, we'll - // copy the message to whatever type the caller was expecting. - return MessageDefaultInstance.WeakCreateBuilderForType() - .WeakMergeFrom((IMessageLite)value).WeakBuild(); - } - case MappedType.Enum: - // Just return a boxed int - that can be unboxed to the enum - EnumValueDescriptor enumValue = (EnumValueDescriptor) value; - return enumValue.Number; - default: - return value; - } - } - - /// - /// Converts from the type used by the native accessors to the type - /// used by reflection accessors. For example, the reflection accessors - /// for enums use EnumValueDescriptors but the native accessors use - /// the generated enum type. - /// - public object ToReflectionType(object value) { - if (descriptor.IsRepeated) { - if (descriptor.MappedType == MappedType.Enum) { - // Must convert the whole list. - IList result = new List(); - foreach (object element in (IEnumerable) value) { - result.Add(SingularToReflectionType(element)); - } - return result; - } else { - return value; - } - } else { - return SingularToReflectionType(value); - } - } - - /// - /// Like ToReflectionType(object) but for a single element. - /// - internal Object SingularToReflectionType(object value) { - return descriptor.MappedType == MappedType.Enum - ? descriptor.EnumType.FindValueByNumber((int) value) - : value; - } - - public abstract object FromReflectionType(object value); - } +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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.Reflection; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + /// + /// Base type for all generated extensions. + /// + /// + /// The protocol compiler generates a static singleton instance of this + /// class for each extension. For exmaple, imagine a .proto file with: + /// + /// message Foo { + /// extensions 1000 to max + /// } + /// + /// extend Foo { + /// optional int32 bar; + /// } + /// + /// Then MyProto.Foo.Bar has type GeneratedExtensionBase<MyProto.Foo,int>. + /// + /// In general, users should ignore the details of this type, and + /// simply use the static singletons as parameters to the extension accessors + /// in ExtendableMessage and ExtendableBuilder. + /// The interface implemented by both GeneratedException and GeneratedRepeatException, + /// to make it easier to cope with repeats separately. + /// + public abstract class GeneratedExtensionBase + { + private readonly FieldDescriptor descriptor; + private readonly IMessageLite messageDefaultInstance; + + protected GeneratedExtensionBase(FieldDescriptor descriptor, Type singularExtensionType) + { + if (!descriptor.IsExtension) + { + throw new ArgumentException("GeneratedExtension given a regular (non-extension) field."); + } + + this.descriptor = descriptor; + if (descriptor.MappedType == MappedType.Message) + { + PropertyInfo defaultInstanceProperty = singularExtensionType + .GetProperty("DefaultInstance", BindingFlags.Static | BindingFlags.Public); + if (defaultInstanceProperty == null) + { + throw new ArgumentException("No public static DefaultInstance property for type " + + typeof (TExtension).Name); + } + + messageDefaultInstance = (IMessageLite) defaultInstanceProperty.GetValue(null, null); + } + } + + public FieldDescriptor Descriptor + { + get { return descriptor; } + } + + public int Number + { + get { return Descriptor.FieldNumber; } + } + + /// + /// Returns the default message instance for extensions which are message types. + /// + public IMessageLite MessageDefaultInstance + { + get { return messageDefaultInstance; } + } + + public object SingularFromReflectionType(object value) + { + switch (Descriptor.MappedType) + { + case MappedType.Message: + if (value is TExtension) + { + return value; + } + else + { + // It seems the copy of the embedded message stored inside the + // extended message is not of the exact type the user was + // expecting. This can happen if a user defines a + // GeneratedExtension manually and gives it a different type. + // This should not happen in normal use. But, to be nice, we'll + // copy the message to whatever type the caller was expecting. + return MessageDefaultInstance.WeakCreateBuilderForType() + .WeakMergeFrom((IMessageLite) value).WeakBuild(); + } + case MappedType.Enum: + // Just return a boxed int - that can be unboxed to the enum + EnumValueDescriptor enumValue = (EnumValueDescriptor) value; + return enumValue.Number; + default: + return value; + } + } + + /// + /// Converts from the type used by the native accessors to the type + /// used by reflection accessors. For example, the reflection accessors + /// for enums use EnumValueDescriptors but the native accessors use + /// the generated enum type. + /// + public object ToReflectionType(object value) + { + if (descriptor.IsRepeated) + { + if (descriptor.MappedType == MappedType.Enum) + { + // Must convert the whole list. + IList result = new List(); + foreach (object element in (IEnumerable) value) + { + result.Add(SingularToReflectionType(element)); + } + return result; + } + else + { + return value; + } + } + else + { + return SingularToReflectionType(value); + } + } + + /// + /// Like ToReflectionType(object) but for a single element. + /// + internal Object SingularToReflectionType(object value) + { + return descriptor.MappedType == MappedType.Enum + ? descriptor.EnumType.FindValueByNumber((int) value) + : value; + } + + public abstract object FromReflectionType(object value); + } } \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedExtensionLite.cs b/src/ProtocolBuffers/GeneratedExtensionLite.cs index 33969f4b..faca1b09 100644 --- a/src/ProtocolBuffers/GeneratedExtensionLite.cs +++ b/src/ProtocolBuffers/GeneratedExtensionLite.cs @@ -1,294 +1,342 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using Google.ProtocolBuffers.Collections; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers { - - public interface IGeneratedExtensionLite { - int Number { get; } - object ContainingType { get; } - IMessageLite MessageDefaultInstance { get; } - IFieldDescriptorLite Descriptor { get; } - } - - public class ExtensionDescriptorLite : IFieldDescriptorLite { - private readonly string fullName; - private readonly IEnumLiteMap enumTypeMap; - private readonly int number; - private readonly FieldType type; - private readonly bool isRepeated; - private readonly bool isPacked; - private readonly MappedType mapType; - private readonly object defaultValue; - - public ExtensionDescriptorLite(string fullName, IEnumLiteMap enumTypeMap, int number, FieldType type, object defaultValue, bool isRepeated, bool isPacked) { - this.fullName = fullName; - this.enumTypeMap = enumTypeMap; - this.number = number; - this.type = type; - this.mapType = FieldMappingAttribute.MappedTypeFromFieldType(type); - this.isRepeated = isRepeated; - this.isPacked = isPacked; - this.defaultValue = defaultValue; - } - - public string FullName { get { return fullName; } } - - public bool IsRepeated { - get { return isRepeated; } - } - - public bool IsRequired { - get { return false; } - } - - public bool IsPacked { - get { return isPacked; } - } - - public bool IsExtension { - get { return true; } - } - - /// - /// This is not supported and assertions are made to ensure this does not exist on extensions of Lite types - /// - public bool MessageSetWireFormat { - get { return false; } - } - - public int FieldNumber { - get { return number; } - } - - public IEnumLiteMap EnumType { - get { return enumTypeMap; } - } - - public FieldType FieldType { - get { return type; } - } - - public MappedType MappedType { - get { return mapType; } - } - - public object DefaultValue { - get { return defaultValue; } - } - - public int CompareTo(IFieldDescriptorLite other) { - return FieldNumber.CompareTo(other.FieldNumber); - } - } - - public class GeneratedRepeatExtensionLite : GeneratedExtensionLite> - where TContainingType : IMessageLite { - public GeneratedRepeatExtensionLite(string fullName, TContainingType containingTypeDefaultInstance, - IMessageLite messageDefaultInstance, IEnumLiteMap enumTypeMap, int number, FieldType type, bool isPacked) : - base(fullName, containingTypeDefaultInstance, new List(), messageDefaultInstance, enumTypeMap, number, type, isPacked) { - } - - public override object ToReflectionType(object value) { - IList result = new List(); - foreach (object element in (IEnumerable) value) { - result.Add(SingularToReflectionType(element)); - } - return result; - } - - public override object FromReflectionType(object value) { - // Must convert the whole list. - List result = new List(); - foreach (object element in (IEnumerable)value) { - result.Add((TExtensionType)SingularFromReflectionType(element)); - } - return result; - } - } - - public class GeneratedExtensionLite : IGeneratedExtensionLite - where TContainingType : IMessageLite { - - private readonly TContainingType containingTypeDefaultInstance; - private readonly TExtensionType defaultValue; - private readonly IMessageLite messageDefaultInstance; - private readonly ExtensionDescriptorLite descriptor; - - // We can't always initialize a GeneratedExtension when we first construct - // it due to initialization order difficulties (namely, the default - // instances may not have been constructed yet). So, we construct an - // uninitialized GeneratedExtension once, then call internalInit() on it - // later. Generated code will always call internalInit() on all extensions - // as part of the static initialization code, and internalInit() throws an - // exception if called more than once, so this method is useless to users. - protected GeneratedExtensionLite( - TContainingType containingTypeDefaultInstance, - TExtensionType defaultValue, - IMessageLite messageDefaultInstance, - ExtensionDescriptorLite descriptor) { - this.containingTypeDefaultInstance = containingTypeDefaultInstance; - this.messageDefaultInstance = messageDefaultInstance; - this.defaultValue = defaultValue; - this.descriptor = descriptor; - } - - /** For use by generated code only. */ - public GeneratedExtensionLite( - string fullName, - TContainingType containingTypeDefaultInstance, - TExtensionType defaultValue, - IMessageLite messageDefaultInstance, - IEnumLiteMap enumTypeMap, - int number, - FieldType type) - : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance, - new ExtensionDescriptorLite(fullName, enumTypeMap, number, type, defaultValue, - false /* isRepeated */, false /* isPacked */)) { - } - - private static readonly IList Empty = new object[0]; - /** Repeating fields: For use by generated code only. */ - protected GeneratedExtensionLite( - string fullName, - TContainingType containingTypeDefaultInstance, - TExtensionType defaultValue, - IMessageLite messageDefaultInstance, - IEnumLiteMap enumTypeMap, - int number, - FieldType type, - bool isPacked) - : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance, - new ExtensionDescriptorLite(fullName, enumTypeMap, number, type, Empty, - true /* isRepeated */, isPacked)) { - } - - /// - /// Returns information about this extension - /// - public IFieldDescriptorLite Descriptor { - get { return descriptor; } - } - - /// - /// Returns the default value for this extension - /// - public TExtensionType DefaultValue { - get { return defaultValue; } - } - - /// - /// used for the extension registry - /// - object IGeneratedExtensionLite.ContainingType { - get { return ContainingTypeDefaultInstance; } - } - /** - * Default instance of the type being extended, used to identify that type. - */ - public TContainingType ContainingTypeDefaultInstance { - get { - return containingTypeDefaultInstance; - } - } - - /** Get the field number. */ - public int Number { - get { - return descriptor.FieldNumber; - } - } - /** - * If the extension is an embedded message, this is the default instance of - * that type. - */ - public IMessageLite MessageDefaultInstance { - get { - return messageDefaultInstance; - } - } - - /// - /// Converts from the type used by the native accessors to the type - /// used by reflection accessors. For example, the reflection accessors - /// for enums use EnumValueDescriptors but the native accessors use - /// the generated enum type. - /// - public virtual object ToReflectionType(object value) { - return SingularToReflectionType(value); - } - - /// - /// Like ToReflectionType(object) but for a single element. - /// - public object SingularToReflectionType(object value) { - return descriptor.MappedType == MappedType.Enum - ? descriptor.EnumType.FindValueByNumber((int)value) - : value; - } - - public virtual object FromReflectionType(object value) { - return SingularFromReflectionType(value); - } - - public object SingularFromReflectionType(object value) { - switch (Descriptor.MappedType) { - case MappedType.Message: - if (value is TExtensionType) { - return value; - } else { - // It seems the copy of the embedded message stored inside the - // extended message is not of the exact type the user was - // expecting. This can happen if a user defines a - // GeneratedExtension manually and gives it a different type. - // This should not happen in normal use. But, to be nice, we'll - // copy the message to whatever type the caller was expecting. - return MessageDefaultInstance.WeakCreateBuilderForType() - .WeakMergeFrom((IMessageLite)value).WeakBuild(); - } - case MappedType.Enum: - // Just return a boxed int - that can be unboxed to the enum - IEnumLite enumValue = (IEnumLite)value; - return enumValue.Number; - default: - return value; - } - } - } +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using Google.ProtocolBuffers.Collections; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + public interface IGeneratedExtensionLite + { + int Number { get; } + object ContainingType { get; } + IMessageLite MessageDefaultInstance { get; } + IFieldDescriptorLite Descriptor { get; } + } + + public class ExtensionDescriptorLite : IFieldDescriptorLite + { + private readonly string fullName; + private readonly IEnumLiteMap enumTypeMap; + private readonly int number; + private readonly FieldType type; + private readonly bool isRepeated; + private readonly bool isPacked; + private readonly MappedType mapType; + private readonly object defaultValue; + + public ExtensionDescriptorLite(string fullName, IEnumLiteMap enumTypeMap, int number, FieldType type, + object defaultValue, bool isRepeated, bool isPacked) + { + this.fullName = fullName; + this.enumTypeMap = enumTypeMap; + this.number = number; + this.type = type; + this.mapType = FieldMappingAttribute.MappedTypeFromFieldType(type); + this.isRepeated = isRepeated; + this.isPacked = isPacked; + this.defaultValue = defaultValue; + } + + public string FullName + { + get { return fullName; } + } + + public bool IsRepeated + { + get { return isRepeated; } + } + + public bool IsRequired + { + get { return false; } + } + + public bool IsPacked + { + get { return isPacked; } + } + + public bool IsExtension + { + get { return true; } + } + + /// + /// This is not supported and assertions are made to ensure this does not exist on extensions of Lite types + /// + public bool MessageSetWireFormat + { + get { return false; } + } + + public int FieldNumber + { + get { return number; } + } + + public IEnumLiteMap EnumType + { + get { return enumTypeMap; } + } + + public FieldType FieldType + { + get { return type; } + } + + public MappedType MappedType + { + get { return mapType; } + } + + public object DefaultValue + { + get { return defaultValue; } + } + + public int CompareTo(IFieldDescriptorLite other) + { + return FieldNumber.CompareTo(other.FieldNumber); + } + } + + public class GeneratedRepeatExtensionLite : + GeneratedExtensionLite> + where TContainingType : IMessageLite + { + public GeneratedRepeatExtensionLite(string fullName, TContainingType containingTypeDefaultInstance, + IMessageLite messageDefaultInstance, IEnumLiteMap enumTypeMap, int number, + FieldType type, bool isPacked) : + base( + fullName, containingTypeDefaultInstance, new List(), + messageDefaultInstance, enumTypeMap, number, type, isPacked) + { + } + + public override object ToReflectionType(object value) + { + IList result = new List(); + foreach (object element in (IEnumerable) value) + { + result.Add(SingularToReflectionType(element)); + } + return result; + } + + public override object FromReflectionType(object value) + { + // Must convert the whole list. + List result = new List(); + foreach (object element in (IEnumerable) value) + { + result.Add((TExtensionType) SingularFromReflectionType(element)); + } + return result; + } + } + + public class GeneratedExtensionLite : IGeneratedExtensionLite + where TContainingType : IMessageLite + { + private readonly TContainingType containingTypeDefaultInstance; + private readonly TExtensionType defaultValue; + private readonly IMessageLite messageDefaultInstance; + private readonly ExtensionDescriptorLite descriptor; + + // We can't always initialize a GeneratedExtension when we first construct + // it due to initialization order difficulties (namely, the default + // instances may not have been constructed yet). So, we construct an + // uninitialized GeneratedExtension once, then call internalInit() on it + // later. Generated code will always call internalInit() on all extensions + // as part of the static initialization code, and internalInit() throws an + // exception if called more than once, so this method is useless to users. + protected GeneratedExtensionLite( + TContainingType containingTypeDefaultInstance, + TExtensionType defaultValue, + IMessageLite messageDefaultInstance, + ExtensionDescriptorLite descriptor) + { + this.containingTypeDefaultInstance = containingTypeDefaultInstance; + this.messageDefaultInstance = messageDefaultInstance; + this.defaultValue = defaultValue; + this.descriptor = descriptor; + } + + /** For use by generated code only. */ + + public GeneratedExtensionLite( + string fullName, + TContainingType containingTypeDefaultInstance, + TExtensionType defaultValue, + IMessageLite messageDefaultInstance, + IEnumLiteMap enumTypeMap, + int number, + FieldType type) + : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance, + new ExtensionDescriptorLite(fullName, enumTypeMap, number, type, defaultValue, + false /* isRepeated */, false /* isPacked */)) + { + } + + private static readonly IList Empty = new object[0]; + /** Repeating fields: For use by generated code only. */ + + protected GeneratedExtensionLite( + string fullName, + TContainingType containingTypeDefaultInstance, + TExtensionType defaultValue, + IMessageLite messageDefaultInstance, + IEnumLiteMap enumTypeMap, + int number, + FieldType type, + bool isPacked) + : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance, + new ExtensionDescriptorLite(fullName, enumTypeMap, number, type, Empty, + true /* isRepeated */, isPacked)) + { + } + + /// + /// Returns information about this extension + /// + public IFieldDescriptorLite Descriptor + { + get { return descriptor; } + } + + /// + /// Returns the default value for this extension + /// + public TExtensionType DefaultValue + { + get { return defaultValue; } + } + + /// + /// used for the extension registry + /// + object IGeneratedExtensionLite.ContainingType + { + get { return ContainingTypeDefaultInstance; } + } + + /** + * Default instance of the type being extended, used to identify that type. + */ + + public TContainingType ContainingTypeDefaultInstance + { + get { return containingTypeDefaultInstance; } + } + + /** Get the field number. */ + + public int Number + { + get { return descriptor.FieldNumber; } + } + + /** + * If the extension is an embedded message, this is the default instance of + * that type. + */ + + public IMessageLite MessageDefaultInstance + { + get { return messageDefaultInstance; } + } + + /// + /// Converts from the type used by the native accessors to the type + /// used by reflection accessors. For example, the reflection accessors + /// for enums use EnumValueDescriptors but the native accessors use + /// the generated enum type. + /// + public virtual object ToReflectionType(object value) + { + return SingularToReflectionType(value); + } + + /// + /// Like ToReflectionType(object) but for a single element. + /// + public object SingularToReflectionType(object value) + { + return descriptor.MappedType == MappedType.Enum + ? descriptor.EnumType.FindValueByNumber((int) value) + : value; + } + + public virtual object FromReflectionType(object value) + { + return SingularFromReflectionType(value); + } + + public object SingularFromReflectionType(object value) + { + switch (Descriptor.MappedType) + { + case MappedType.Message: + if (value is TExtensionType) + { + return value; + } + else + { + // It seems the copy of the embedded message stored inside the + // extended message is not of the exact type the user was + // expecting. This can happen if a user defines a + // GeneratedExtension manually and gives it a different type. + // This should not happen in normal use. But, to be nice, we'll + // copy the message to whatever type the caller was expecting. + return MessageDefaultInstance.WeakCreateBuilderForType() + .WeakMergeFrom((IMessageLite) value).WeakBuild(); + } + case MappedType.Enum: + // Just return a boxed int - that can be unboxed to the enum + IEnumLite enumValue = (IEnumLite) value; + return enumValue.Number; + default: + return value; + } + } + } } \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedMessage.cs b/src/ProtocolBuffers/GeneratedMessage.cs index fe1188b6..0ec02e88 100644 --- a/src/ProtocolBuffers/GeneratedMessage.cs +++ b/src/ProtocolBuffers/GeneratedMessage.cs @@ -1,152 +1,179 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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.Descriptors; -using Google.ProtocolBuffers.FieldAccess; -using System.Collections; - -namespace Google.ProtocolBuffers { - - /// - /// All generated protocol message classes extend this class. It implements - /// most of the IMessage interface using reflection. Users - /// can ignore this class as an implementation detail. - /// - public abstract class GeneratedMessage : AbstractMessage - where TMessage : GeneratedMessage - where TBuilder : GeneratedBuilder { - - private UnknownFieldSet unknownFields = UnknownFieldSet.DefaultInstance; - - /// - /// Returns the message as a TMessage. - /// - protected abstract TMessage ThisMessage { get; } - - internal FieldAccessorTable FieldAccessorsFromBuilder { - get { return InternalFieldAccessors; } - } - - protected abstract FieldAccessorTable InternalFieldAccessors { get; } - - public override MessageDescriptor DescriptorForType { - get { return InternalFieldAccessors.Descriptor; } - } - - internal IDictionary GetMutableFieldMap() { - - // Use a SortedList so we'll end up serializing fields in order - var ret = new SortedList(); - MessageDescriptor descriptor = DescriptorForType; - foreach (FieldDescriptor field in descriptor.Fields) { - IFieldAccessor accessor = InternalFieldAccessors[field]; - if (field.IsRepeated) { - if (accessor.GetRepeatedCount(ThisMessage) != 0) { - ret[field] = accessor.GetValue(ThisMessage); - } - } else if (HasField(field)) { - ret[field] = accessor.GetValue(ThisMessage); - } - } - return ret; - } - - public override bool IsInitialized { - get { - foreach (FieldDescriptor field in DescriptorForType.Fields) { - // Check that all required fields are present. - if (field.IsRequired && !HasField(field)) { - return false; - } - // Check that embedded messages are initialized. - // This code is similar to that in AbstractMessage, but we don't - // fetch all the field values - just the ones we need to. - if (field.MappedType == MappedType.Message) { - if (field.IsRepeated) { - // We know it's an IList, but not the exact type - so - // IEnumerable is the best we can do. (C# generics aren't covariant yet.) - foreach (IMessageLite element in (IEnumerable) this[field]) { - if (!element.IsInitialized) { - return false; - } - } - } else { - if (HasField(field) && !((IMessageLite) this[field]).IsInitialized) { - return false; - } - } - } - } - return true; - } - } - - public override IDictionary AllFields { - get { return Dictionaries.AsReadOnly(GetMutableFieldMap()); } - } - - public override bool HasField(FieldDescriptor field) { - return InternalFieldAccessors[field].Has(ThisMessage); - } - - public override int GetRepeatedFieldCount(FieldDescriptor field) { - return InternalFieldAccessors[field].GetRepeatedCount(ThisMessage); - } - - public override object this[FieldDescriptor field, int index] { - get { return InternalFieldAccessors[field].GetRepeatedValue(ThisMessage, index); } - } - - public override object this[FieldDescriptor field] { - get { return InternalFieldAccessors[field].GetValue(ThisMessage); } - } - - public override UnknownFieldSet UnknownFields { - get { return unknownFields; } - } - - /// - /// Replaces the set of unknown fields for this message. This should - /// only be used before a message is built, by the builder. (In the - /// Java code it is private, but the builder is nested so has access - /// to it.) - /// - internal void SetUnknownFields(UnknownFieldSet fieldSet) { - unknownFields = fieldSet; - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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.Descriptors; +using Google.ProtocolBuffers.FieldAccess; +using System.Collections; + +namespace Google.ProtocolBuffers +{ + /// + /// All generated protocol message classes extend this class. It implements + /// most of the IMessage interface using reflection. Users + /// can ignore this class as an implementation detail. + /// + public abstract class GeneratedMessage : AbstractMessage + where TMessage : GeneratedMessage + where TBuilder : GeneratedBuilder + { + private UnknownFieldSet unknownFields = UnknownFieldSet.DefaultInstance; + + /// + /// Returns the message as a TMessage. + /// + protected abstract TMessage ThisMessage { get; } + + internal FieldAccessorTable FieldAccessorsFromBuilder + { + get { return InternalFieldAccessors; } + } + + protected abstract FieldAccessorTable InternalFieldAccessors { get; } + + public override MessageDescriptor DescriptorForType + { + get { return InternalFieldAccessors.Descriptor; } + } + + internal IDictionary GetMutableFieldMap() + { + // Use a SortedList so we'll end up serializing fields in order + var ret = new SortedList(); + MessageDescriptor descriptor = DescriptorForType; + foreach (FieldDescriptor field in descriptor.Fields) + { + IFieldAccessor accessor = InternalFieldAccessors[field]; + if (field.IsRepeated) + { + if (accessor.GetRepeatedCount(ThisMessage) != 0) + { + ret[field] = accessor.GetValue(ThisMessage); + } + } + else if (HasField(field)) + { + ret[field] = accessor.GetValue(ThisMessage); + } + } + return ret; + } + + public override bool IsInitialized + { + get + { + foreach (FieldDescriptor field in DescriptorForType.Fields) + { + // Check that all required fields are present. + if (field.IsRequired && !HasField(field)) + { + return false; + } + // Check that embedded messages are initialized. + // This code is similar to that in AbstractMessage, but we don't + // fetch all the field values - just the ones we need to. + if (field.MappedType == MappedType.Message) + { + if (field.IsRepeated) + { + // We know it's an IList, but not the exact type - so + // IEnumerable is the best we can do. (C# generics aren't covariant yet.) + foreach (IMessageLite element in (IEnumerable) this[field]) + { + if (!element.IsInitialized) + { + return false; + } + } + } + else + { + if (HasField(field) && !((IMessageLite) this[field]).IsInitialized) + { + return false; + } + } + } + } + return true; + } + } + + public override IDictionary AllFields + { + get { return Dictionaries.AsReadOnly(GetMutableFieldMap()); } + } + + public override bool HasField(FieldDescriptor field) + { + return InternalFieldAccessors[field].Has(ThisMessage); + } + + public override int GetRepeatedFieldCount(FieldDescriptor field) + { + return InternalFieldAccessors[field].GetRepeatedCount(ThisMessage); + } + + public override object this[FieldDescriptor field, int index] + { + get { return InternalFieldAccessors[field].GetRepeatedValue(ThisMessage, index); } + } + + public override object this[FieldDescriptor field] + { + get { return InternalFieldAccessors[field].GetValue(ThisMessage); } + } + + public override UnknownFieldSet UnknownFields + { + get { return unknownFields; } + } + + /// + /// Replaces the set of unknown fields for this message. This should + /// only be used before a message is built, by the builder. (In the + /// Java code it is private, but the builder is nested so has access + /// to it.) + /// + internal void SetUnknownFields(UnknownFieldSet fieldSet) + { + unknownFields = fieldSet; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedMessageLite.cs b/src/ProtocolBuffers/GeneratedMessageLite.cs index b2a009c4..2efaeaa8 100644 --- a/src/ProtocolBuffers/GeneratedMessageLite.cs +++ b/src/ProtocolBuffers/GeneratedMessageLite.cs @@ -1,132 +1,173 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Collections; -using System.Globalization; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers { - - /// - /// All generated protocol message classes extend this class. It implements - /// most of the IMessage interface using reflection. Users - /// can ignore this class as an implementation detail. - /// - public abstract class GeneratedMessageLite : AbstractMessageLite - where TMessage : GeneratedMessageLite - where TBuilder : GeneratedBuilderLite { - - protected abstract TMessage ThisMessage { get; } - - public sealed override string ToString() { - using (System.IO.StringWriter wtr = new System.IO.StringWriter()) { - PrintTo(wtr); - return wtr.ToString(); - } - } - - /// - /// PrintTo() helper methods for Lite Runtime - /// - protected static void PrintField(string name, IList value, System.IO.TextWriter writer) { - foreach (T item in value) - PrintField(name, true, (object)item, writer); - } - /// - /// PrintTo() helper methods for Lite Runtime - /// - protected static void PrintField(string name, bool hasValue, object value, System.IO.TextWriter writer) { - if (!hasValue) return; - if (value is IMessageLite) { - writer.WriteLine("{0} {{", name); - ((IMessageLite)value).PrintTo(writer); - writer.WriteLine("}"); - } else if (value is ByteString || value is String) { - writer.Write("{0}: \"", name); - if(value is String) - EscapeBytes( System.Text.Encoding.UTF8.GetBytes((string)value), writer); - else - EscapeBytes(((ByteString)value), writer); - writer.WriteLine("\""); - } else if (value is bool) { - writer.WriteLine("{0}: {1}", name, (bool)value ? "true" : "false"); - } else if (value is IEnumLite) { - writer.WriteLine("{0}: {1}", name, ((IEnumLite)value).Name); - } - else { - writer.WriteLine("{0}: {1}", name, ((IConvertible)value).ToString(CultureInfo.InvariantCulture)); - } - } - - /// - /// COPIED from TextFormat - /// Escapes bytes in the format used in protocol buffer text format, which - /// is the same as the format used for C string literals. All bytes - /// that are not printable 7-bit ASCII characters are escaped, as well as - /// backslash, single-quote, and double-quote characters. Characters for - /// which no defined short-hand escape sequence is defined will be escaped - /// using 3-digit octal sequences. - /// The returned value is guaranteed to be entirely ASCII. - /// - private static void EscapeBytes(IEnumerable input, System.IO.TextWriter writer) { - foreach (byte b in input) { - switch (b) { - // C# does not use \a or \v - case 0x07: writer.Write("\\a"); break; - case (byte)'\b': writer.Write("\\b"); break; - case (byte)'\f': writer.Write("\\f"); break; - case (byte)'\n': writer.Write("\\n"); break; - case (byte)'\r': writer.Write("\\r"); break; - case (byte)'\t': writer.Write("\\t"); break; - case 0x0b: writer.Write("\\v"); break; - case (byte)'\\': writer.Write("\\\\"); break; - case (byte)'\'': writer.Write("\\\'"); break; - case (byte)'"': writer.Write("\\\""); break; - default: - if (b >= 0x20 && b < 128) { - writer.Write((char)b); - } else { - writer.Write('\\'); - writer.Write((char)('0' + ((b >> 6) & 3))); - writer.Write((char)('0' + ((b >> 3) & 7))); - writer.Write((char)('0' + (b & 7))); - } - break; - } - } - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Collections; +using System.Globalization; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + /// + /// All generated protocol message classes extend this class. It implements + /// most of the IMessage interface using reflection. Users + /// can ignore this class as an implementation detail. + /// + public abstract class GeneratedMessageLite : AbstractMessageLite + where TMessage : GeneratedMessageLite + where TBuilder : GeneratedBuilderLite + { + protected abstract TMessage ThisMessage { get; } + + public override sealed string ToString() + { + using (System.IO.StringWriter wtr = new System.IO.StringWriter()) + { + PrintTo(wtr); + return wtr.ToString(); + } + } + + /// + /// PrintTo() helper methods for Lite Runtime + /// + protected static void PrintField(string name, IList value, System.IO.TextWriter writer) + { + foreach (T item in value) + PrintField(name, true, (object) item, writer); + } + + /// + /// PrintTo() helper methods for Lite Runtime + /// + protected static void PrintField(string name, bool hasValue, object value, System.IO.TextWriter writer) + { + if (!hasValue) return; + if (value is IMessageLite) + { + writer.WriteLine("{0} {{", name); + ((IMessageLite) value).PrintTo(writer); + writer.WriteLine("}"); + } + else if (value is ByteString || value is String) + { + writer.Write("{0}: \"", name); + if (value is String) + EscapeBytes(System.Text.Encoding.UTF8.GetBytes((string) value), writer); + else + EscapeBytes(((ByteString) value), writer); + writer.WriteLine("\""); + } + else if (value is bool) + { + writer.WriteLine("{0}: {1}", name, (bool) value ? "true" : "false"); + } + else if (value is IEnumLite) + { + writer.WriteLine("{0}: {1}", name, ((IEnumLite) value).Name); + } + else + { + writer.WriteLine("{0}: {1}", name, ((IConvertible) value).ToString(CultureInfo.InvariantCulture)); + } + } + + /// + /// COPIED from TextFormat + /// Escapes bytes in the format used in protocol buffer text format, which + /// is the same as the format used for C string literals. All bytes + /// that are not printable 7-bit ASCII characters are escaped, as well as + /// backslash, single-quote, and double-quote characters. Characters for + /// which no defined short-hand escape sequence is defined will be escaped + /// using 3-digit octal sequences. + /// The returned value is guaranteed to be entirely ASCII. + /// + private static void EscapeBytes(IEnumerable input, System.IO.TextWriter writer) + { + foreach (byte b in input) + { + switch (b) + { + // C# does not use \a or \v + case 0x07: + writer.Write("\\a"); + break; + case (byte) '\b': + writer.Write("\\b"); + break; + case (byte) '\f': + writer.Write("\\f"); + break; + case (byte) '\n': + writer.Write("\\n"); + break; + case (byte) '\r': + writer.Write("\\r"); + break; + case (byte) '\t': + writer.Write("\\t"); + break; + case 0x0b: + writer.Write("\\v"); + break; + case (byte) '\\': + writer.Write("\\\\"); + break; + case (byte) '\'': + writer.Write("\\\'"); + break; + case (byte) '"': + writer.Write("\\\""); + break; + default: + if (b >= 0x20 && b < 128) + { + writer.Write((char) b); + } + else + { + writer.Write('\\'); + writer.Write((char) ('0' + ((b >> 6) & 3))); + writer.Write((char) ('0' + ((b >> 3) & 7))); + writer.Write((char) ('0' + (b & 7))); + } + break; + } + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedRepeatExtension.cs b/src/ProtocolBuffers/GeneratedRepeatExtension.cs index 65dd63d6..6ea07fc0 100644 --- a/src/ProtocolBuffers/GeneratedRepeatExtension.cs +++ b/src/ProtocolBuffers/GeneratedRepeatExtension.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.Collections.Generic; -using Google.ProtocolBuffers.Descriptors; -using System.Collections; - -namespace Google.ProtocolBuffers { - /// - /// Class used to represent repeat extensions in generated classes. - /// - public sealed class GeneratedRepeatExtension : GeneratedExtensionBase> { - private GeneratedRepeatExtension(FieldDescriptor field) : base(field, typeof(TExtensionElement)) { - } - - public static GeneratedExtensionBase> CreateInstance(FieldDescriptor descriptor) { - if (!descriptor.IsRepeated) { - throw new ArgumentException("Must call GeneratedRepeatExtension.CreateInstance() for repeated types."); - } - return new GeneratedRepeatExtension(descriptor); - } - - /// - /// Converts the list to the right type. - /// TODO(jonskeet): Check where this is used, and whether we need to convert - /// for primitive types. - /// - /// - /// - public override object FromReflectionType(object value) { - if (Descriptor.MappedType == MappedType.Message || - Descriptor.MappedType == MappedType.Enum) { - // Must convert the whole list. - List result = new List(); - foreach (object element in (IEnumerable) value) { - result.Add((TExtensionElement) SingularFromReflectionType(element)); - } - return result; - } else { - return value; - } - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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 System.Collections; + +namespace Google.ProtocolBuffers +{ + /// + /// Class used to represent repeat extensions in generated classes. + /// + public sealed class GeneratedRepeatExtension : GeneratedExtensionBase> + { + private GeneratedRepeatExtension(FieldDescriptor field) : base(field, typeof (TExtensionElement)) + { + } + + public static GeneratedExtensionBase> CreateInstance(FieldDescriptor descriptor) + { + if (!descriptor.IsRepeated) + { + throw new ArgumentException("Must call GeneratedRepeatExtension.CreateInstance() for repeated types."); + } + return new GeneratedRepeatExtension(descriptor); + } + + /// + /// Converts the list to the right type. + /// TODO(jonskeet): Check where this is used, and whether we need to convert + /// for primitive types. + /// + /// + /// + public override object FromReflectionType(object value) + { + if (Descriptor.MappedType == MappedType.Message || + Descriptor.MappedType == MappedType.Enum) + { + // Must convert the whole list. + List result = new List(); + foreach (object element in (IEnumerable) value) + { + result.Add((TExtensionElement) SingularFromReflectionType(element)); + } + return result; + } + else + { + return value; + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedSingleExtension.cs b/src/ProtocolBuffers/GeneratedSingleExtension.cs index 1dea031b..de9fd29f 100644 --- a/src/ProtocolBuffers/GeneratedSingleExtension.cs +++ b/src/ProtocolBuffers/GeneratedSingleExtension.cs @@ -1,58 +1,65 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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; - -namespace Google.ProtocolBuffers { - - /// - /// Generated extension for a singular field. - /// - public sealed class GeneratedSingleExtension : GeneratedExtensionBase { - internal GeneratedSingleExtension(FieldDescriptor descriptor) : base(descriptor, typeof(TExtension)) { - } - - public static GeneratedSingleExtension CreateInstance(FieldDescriptor descriptor) { - if (descriptor.IsRepeated) { - throw new ArgumentException("Must call GeneratedRepeateExtension.CreateInstance() for repeated types."); - } - return new GeneratedSingleExtension(descriptor); - } - - public override object FromReflectionType(object value) { - return base.SingularFromReflectionType(value); - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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; + +namespace Google.ProtocolBuffers +{ + /// + /// Generated extension for a singular field. + /// + public sealed class GeneratedSingleExtension : GeneratedExtensionBase + { + internal GeneratedSingleExtension(FieldDescriptor descriptor) : base(descriptor, typeof (TExtension)) + { + } + + public static GeneratedSingleExtension CreateInstance(FieldDescriptor descriptor) + { + if (descriptor.IsRepeated) + { + throw new ArgumentException("Must call GeneratedRepeateExtension.CreateInstance() for repeated types."); + } + return new GeneratedSingleExtension(descriptor); + } + + public override object FromReflectionType(object value) + { + return base.SingularFromReflectionType(value); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IBuilder.cs b/src/ProtocolBuffers/IBuilder.cs index c4a1c609..7a9d6907 100644 --- a/src/ProtocolBuffers/IBuilder.cs +++ b/src/ProtocolBuffers/IBuilder.cs @@ -1,302 +1,309 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers { - - /// - /// Non-generic interface for all members whose signatures don't require knowledge of - /// the type being built. The generic interface extends this one. Some methods return - /// either an IBuilder or an IMessage; in these cases the generic interface redeclares - /// the same method with a type-specific signature. Implementations are encouraged to - /// use explicit interface implemenation for the non-generic form. This mirrors - /// how IEnumerable and IEnumerable<T> work. - /// - public interface IBuilder : IBuilderLite { - /// - /// Returns true iff all required fields in the message and all - /// embedded messages are set. - /// - new bool IsInitialized { get; } - - /// - /// Only present in the nongeneric interface - useful for tests, but - /// not as much in real life. - /// - IBuilder SetField(FieldDescriptor field, object value); - - /// - /// Only present in the nongeneric interface - useful for tests, but - /// not as much in real life. - /// - IBuilder SetRepeatedField(FieldDescriptor field, int index, object value); - - /// - /// Behaves like the equivalent property in IMessage<T>. - /// The returned map may or may not reflect future changes to the builder. - /// Either way, the returned map is unmodifiable. - /// - IDictionary AllFields { get; } - - /// - /// Allows getting and setting of a field. - /// - /// - /// - /// - object this[FieldDescriptor field] { get; set; } - - /// - /// Get the message's type descriptor. - /// - /// - MessageDescriptor DescriptorForType { get; } - - /// - /// - /// - /// - /// - int GetRepeatedFieldCount(FieldDescriptor field); - - /// - /// Allows getting and setting of a repeated field value. - /// - /// - object this[FieldDescriptor field, int index] { get; set; } - - /// - /// - /// - bool HasField(FieldDescriptor field); - - /// - /// - /// - UnknownFieldSet UnknownFields { get; set; } - - /// - /// Create a builder for messages of the appropriate type for the given field. - /// Messages built with this can then be passed to the various mutation properties - /// and methods. - /// - IBuilder CreateBuilderForField(FieldDescriptor field); - - #region Methods which are like those of the generic form, but without any knowledge of the type parameters - IBuilder WeakAddRepeatedField(FieldDescriptor field, object value); - new IBuilder WeakClear(); - IBuilder WeakClearField(FieldDescriptor field); - IBuilder WeakMergeFrom(IMessage message); - new IBuilder WeakMergeFrom(ByteString data); - new IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry); - new IBuilder WeakMergeFrom(CodedInputStream input); - new IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry); - new IMessage WeakBuild(); - new IMessage WeakBuildPartial(); - new IBuilder WeakClone(); - new IMessage WeakDefaultInstanceForType { get; } - #endregion - } - - /// - /// Interface implemented by Protocol Message builders. - /// TODO(jonskeet): Consider "SetXXX" methods returning the builder, as well as the properties. - /// - /// Type of message - /// Type of builder - public interface IBuilder : IBuilder, IBuilderLite - where TMessage : IMessage - where TBuilder : IBuilder { - - TBuilder SetUnknownFields(UnknownFieldSet unknownFields); - - /// - /// Resets all fields to their default values. - /// - new TBuilder Clear(); - - /// - /// Merge the specified other message which may be a different implementation of - /// the same message descriptor. - /// - TBuilder MergeFrom(IMessage other); - - /// - /// Constructs the final message. Once this is called, this Builder instance - /// is no longer valid, and calling any other method may throw a - /// NullReferenceException. If you need to continue working with the builder - /// after calling Build, call Clone first. - /// - /// the message - /// is missing one or more required fields; use BuildPartial to bypass - /// this check - new TMessage Build(); - - /// - /// Like Build(), but does not throw an exception if the message is missing - /// required fields. Instead, a partial message is returned. - /// - new TMessage BuildPartial(); - - /// - /// Clones this builder. - /// TODO(jonskeet): Explain depth of clone. - /// - new TBuilder Clone(); - - /// - /// Parses a message of this type from the input and merges it with this - /// message, as if using MergeFrom(IMessage<T>). - /// - /// - /// Warning: This does not verify that all required fields are present - /// in the input message. If you call Build() without setting all - /// required fields, it will throw an UninitializedMessageException. - /// There are a few good ways to deal with this: - /// - /// Call IsInitialized to verify to verify that all required fields are - /// set before building. - /// Parse the message separately using one of the static ParseFrom - /// methods, then use MergeFrom(IMessage<T>) to merge it with - /// this one. ParseFrom will throw an InvalidProtocolBufferException - /// (an IOException) if some required fields are missing. - /// Use BuildPartial to build, which ignores missing required fields. - /// - /// - new TBuilder MergeFrom(CodedInputStream input); - - /// - /// Like MergeFrom(CodedInputStream), but also parses extensions. - /// The extensions that you want to be able to parse must be registered - /// in . Extensions not in the registry - /// will be treated as unknown fields. - /// - new TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry); - - /// - /// Get's the message's type's default instance. - /// - /// - new TMessage DefaultInstanceForType { get; } - - /// - /// Clears the field. This is exactly equivalent to calling the generated - /// Clear method corresponding to the field. - /// - /// - /// - TBuilder ClearField(FieldDescriptor field); - - /// - /// Appends the given value as a new element for the specified repeated field. - /// - /// the field is not a repeated field, - /// the field does not belong to this builder's type, or the value is - /// of the incorrect type - /// - TBuilder AddRepeatedField(FieldDescriptor field, object value); - - /// - /// Merge some unknown fields into the set for this message. - /// - TBuilder MergeUnknownFields(UnknownFieldSet unknownFields); - - /// - /// Like MergeFrom(Stream), but does not read until the end of the file. - /// Instead, the size of the message (encoded as a varint) is read first, - /// then the message data. Use Message.WriteDelimitedTo(Stream) to - /// write messages in this format. - /// - /// - new TBuilder MergeDelimitedFrom(Stream input); - - /// - /// Like MergeDelimitedFrom(Stream) but supporting extensions. - /// - new TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry); - - #region Convenience methods - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). - /// - new TBuilder MergeFrom(ByteString data); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, extensionRegistry). - /// - new TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). - /// - new TBuilder MergeFrom(byte[] data); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, extensionRegistry). - /// - new TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). Note that this method always reads - /// the entire input (unless it throws an exception). If you want it to - /// stop earlier, you will need to wrap the input in a wrapper - /// stream which limits reading. Or, use IMessage.WriteDelimitedTo(Stream) - /// to write your message and MmergeDelimitedFrom(Stream) to read it. - /// Despite usually reading the entire stream, this method never closes the stream. - /// - new TBuilder MergeFrom(Stream input); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, extensionRegistry). - /// - new TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry); - #endregion - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + /// + /// Non-generic interface for all members whose signatures don't require knowledge of + /// the type being built. The generic interface extends this one. Some methods return + /// either an IBuilder or an IMessage; in these cases the generic interface redeclares + /// the same method with a type-specific signature. Implementations are encouraged to + /// use explicit interface implemenation for the non-generic form. This mirrors + /// how IEnumerable and IEnumerable<T> work. + /// + public interface IBuilder : IBuilderLite + { + /// + /// Returns true iff all required fields in the message and all + /// embedded messages are set. + /// + new bool IsInitialized { get; } + + /// + /// Only present in the nongeneric interface - useful for tests, but + /// not as much in real life. + /// + IBuilder SetField(FieldDescriptor field, object value); + + /// + /// Only present in the nongeneric interface - useful for tests, but + /// not as much in real life. + /// + IBuilder SetRepeatedField(FieldDescriptor field, int index, object value); + + /// + /// Behaves like the equivalent property in IMessage<T>. + /// The returned map may or may not reflect future changes to the builder. + /// Either way, the returned map is unmodifiable. + /// + IDictionary AllFields { get; } + + /// + /// Allows getting and setting of a field. + /// + /// + /// + /// + object this[FieldDescriptor field] { get; set; } + + /// + /// Get the message's type descriptor. + /// + /// + MessageDescriptor DescriptorForType { get; } + + /// + /// + /// + /// + /// + int GetRepeatedFieldCount(FieldDescriptor field); + + /// + /// Allows getting and setting of a repeated field value. + /// + /// + object this[FieldDescriptor field, int index] { get; set; } + + /// + /// + /// + bool HasField(FieldDescriptor field); + + /// + /// + /// + UnknownFieldSet UnknownFields { get; set; } + + /// + /// Create a builder for messages of the appropriate type for the given field. + /// Messages built with this can then be passed to the various mutation properties + /// and methods. + /// + IBuilder CreateBuilderForField(FieldDescriptor field); + + #region Methods which are like those of the generic form, but without any knowledge of the type parameters + + IBuilder WeakAddRepeatedField(FieldDescriptor field, object value); + new IBuilder WeakClear(); + IBuilder WeakClearField(FieldDescriptor field); + IBuilder WeakMergeFrom(IMessage message); + new IBuilder WeakMergeFrom(ByteString data); + new IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry); + new IBuilder WeakMergeFrom(CodedInputStream input); + new IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry); + new IMessage WeakBuild(); + new IMessage WeakBuildPartial(); + new IBuilder WeakClone(); + new IMessage WeakDefaultInstanceForType { get; } + + #endregion + } + + /// + /// Interface implemented by Protocol Message builders. + /// TODO(jonskeet): Consider "SetXXX" methods returning the builder, as well as the properties. + /// + /// Type of message + /// Type of builder + public interface IBuilder : IBuilder, IBuilderLite + where TMessage : IMessage + where TBuilder : IBuilder + { + TBuilder SetUnknownFields(UnknownFieldSet unknownFields); + + /// + /// Resets all fields to their default values. + /// + new TBuilder Clear(); + + /// + /// Merge the specified other message which may be a different implementation of + /// the same message descriptor. + /// + TBuilder MergeFrom(IMessage other); + + /// + /// Constructs the final message. Once this is called, this Builder instance + /// is no longer valid, and calling any other method may throw a + /// NullReferenceException. If you need to continue working with the builder + /// after calling Build, call Clone first. + /// + /// the message + /// is missing one or more required fields; use BuildPartial to bypass + /// this check + new TMessage Build(); + + /// + /// Like Build(), but does not throw an exception if the message is missing + /// required fields. Instead, a partial message is returned. + /// + new TMessage BuildPartial(); + + /// + /// Clones this builder. + /// TODO(jonskeet): Explain depth of clone. + /// + new TBuilder Clone(); + + /// + /// Parses a message of this type from the input and merges it with this + /// message, as if using MergeFrom(IMessage<T>). + /// + /// + /// Warning: This does not verify that all required fields are present + /// in the input message. If you call Build() without setting all + /// required fields, it will throw an UninitializedMessageException. + /// There are a few good ways to deal with this: + /// + /// Call IsInitialized to verify to verify that all required fields are + /// set before building. + /// Parse the message separately using one of the static ParseFrom + /// methods, then use MergeFrom(IMessage<T>) to merge it with + /// this one. ParseFrom will throw an InvalidProtocolBufferException + /// (an IOException) if some required fields are missing. + /// Use BuildPartial to build, which ignores missing required fields. + /// + /// + new TBuilder MergeFrom(CodedInputStream input); + + /// + /// Like MergeFrom(CodedInputStream), but also parses extensions. + /// The extensions that you want to be able to parse must be registered + /// in . Extensions not in the registry + /// will be treated as unknown fields. + /// + new TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry); + + /// + /// Get's the message's type's default instance. + /// + /// + new TMessage DefaultInstanceForType { get; } + + /// + /// Clears the field. This is exactly equivalent to calling the generated + /// Clear method corresponding to the field. + /// + /// + /// + TBuilder ClearField(FieldDescriptor field); + + /// + /// Appends the given value as a new element for the specified repeated field. + /// + /// the field is not a repeated field, + /// the field does not belong to this builder's type, or the value is + /// of the incorrect type + /// + TBuilder AddRepeatedField(FieldDescriptor field, object value); + + /// + /// Merge some unknown fields into the set for this message. + /// + TBuilder MergeUnknownFields(UnknownFieldSet unknownFields); + + /// + /// Like MergeFrom(Stream), but does not read until the end of the file. + /// Instead, the size of the message (encoded as a varint) is read first, + /// then the message data. Use Message.WriteDelimitedTo(Stream) to + /// write messages in this format. + /// + /// + new TBuilder MergeDelimitedFrom(Stream input); + + /// + /// Like MergeDelimitedFrom(Stream) but supporting extensions. + /// + new TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry); + + #region Convenience methods + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). + /// + new TBuilder MergeFrom(ByteString data); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream, extensionRegistry). + /// + new TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). + /// + new TBuilder MergeFrom(byte[] data); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream, extensionRegistry). + /// + new TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). Note that this method always reads + /// the entire input (unless it throws an exception). If you want it to + /// stop earlier, you will need to wrap the input in a wrapper + /// stream which limits reading. Or, use IMessage.WriteDelimitedTo(Stream) + /// to write your message and MmergeDelimitedFrom(Stream) to read it. + /// Despite usually reading the entire stream, this method never closes the stream. + /// + new TBuilder MergeFrom(Stream input); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream, extensionRegistry). + /// + new TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry); + + #endregion + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IBuilderLite.cs b/src/ProtocolBuffers/IBuilderLite.cs index e91d44bc..6cc14d6c 100644 --- a/src/ProtocolBuffers/IBuilderLite.cs +++ b/src/ProtocolBuffers/IBuilderLite.cs @@ -1,210 +1,215 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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; - -namespace Google.ProtocolBuffers { - - /// - /// Non-generic interface for all members whose signatures don't require knowledge of - /// the type being built. The generic interface extends this one. Some methods return - /// either an IBuilder or an IMessage; in these cases the generic interface redeclares - /// the same method with a type-specific signature. Implementations are encouraged to - /// use explicit interface implemenation for the non-generic form. This mirrors - /// how IEnumerable and IEnumerable<T> work. - /// - public interface IBuilderLite { - /// - /// Returns true iff all required fields in the message and all - /// embedded messages are set. - /// - bool IsInitialized { get; } - - IBuilderLite WeakClear(); - IBuilderLite WeakMergeFrom(IMessageLite message); - IBuilderLite WeakMergeFrom(ByteString data); - IBuilderLite WeakMergeFrom(ByteString data, ExtensionRegistry registry); - IBuilderLite WeakMergeFrom(CodedInputStream input); - IBuilderLite WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry); - IMessageLite WeakBuild(); - IMessageLite WeakBuildPartial(); - IBuilderLite WeakClone(); - IMessageLite WeakDefaultInstanceForType { get; } - } - - /// - /// Interface implemented by Protocol Message builders. - /// TODO(jonskeet): Consider "SetXXX" methods returning the builder, as well as the properties. - /// - /// Type of message - /// Type of builder - public interface IBuilderLite : IBuilderLite - where TMessage : IMessageLite - where TBuilder : IBuilderLite { - - /// - /// Resets all fields to their default values. - /// - TBuilder Clear(); - - /// - /// Merge the specified other message which may be a different implementation of - /// the same message descriptor. - /// - TBuilder MergeFrom(IMessageLite other); - - /// - /// Constructs the final message. Once this is called, this Builder instance - /// is no longer valid, and calling any other method may throw a - /// NullReferenceException. If you need to continue working with the builder - /// after calling Build, call Clone first. - /// - /// the message - /// is missing one or more required fields; use BuildPartial to bypass - /// this check - TMessage Build(); - - /// - /// Like Build(), but does not throw an exception if the message is missing - /// required fields. Instead, a partial message is returned. - /// - TMessage BuildPartial(); - - /// - /// Clones this builder. - /// TODO(jonskeet): Explain depth of clone. - /// - TBuilder Clone(); - - /// - /// Parses a message of this type from the input and merges it with this - /// message, as if using MergeFrom(IMessage<T>). - /// - /// - /// Warning: This does not verify that all required fields are present - /// in the input message. If you call Build() without setting all - /// required fields, it will throw an UninitializedMessageException. - /// There are a few good ways to deal with this: - /// - /// Call IsInitialized to verify to verify that all required fields are - /// set before building. - /// Parse the message separately using one of the static ParseFrom - /// methods, then use MergeFrom(IMessage<T>) to merge it with - /// this one. ParseFrom will throw an InvalidProtocolBufferException - /// (an IOException) if some required fields are missing. - /// Use BuildPartial to build, which ignores missing required fields. - /// - /// - TBuilder MergeFrom(CodedInputStream input); - - /// - /// Like MergeFrom(CodedInputStream), but also parses extensions. - /// The extensions that you want to be able to parse must be registered - /// in . Extensions not in the registry - /// will be treated as unknown fields. - /// - TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry); - - /// - /// Get's the message's type's default instance. - /// - /// - TMessage DefaultInstanceForType { get; } - - /// - /// Like MergeFrom(Stream), but does not read until the end of the file. - /// Instead, the size of the message (encoded as a varint) is read first, - /// then the message data. Use Message.WriteDelimitedTo(Stream) to - /// write messages in this format. - /// - /// - TBuilder MergeDelimitedFrom(Stream input); - - /// - /// Like MergeDelimitedFrom(Stream) but supporting extensions. - /// - TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry); - - #region Convenience methods - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). - /// - TBuilder MergeFrom(ByteString data); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, ExtensionRegistry). - /// - TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). - /// - TBuilder MergeFrom(byte[] data); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, ExtensionRegistry). - /// - TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). Note that this method always reads - /// the entire input (unless it throws an exception). If you want it to - /// stop earlier, you will need to wrap the input in a wrapper - /// stream which limits reading. Or, use IMessage.WriteDelimitedTo(Stream) - /// to write your message and MmergeDelimitedFrom(Stream) to read it. - /// Despite usually reading the entire stream, this method never closes the stream. - /// - TBuilder MergeFrom(Stream input); - - /// - /// Parse as a message of this type and merge - /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, ExtensionRegistry). - /// - TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry); - #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; + +namespace Google.ProtocolBuffers +{ + /// + /// Non-generic interface for all members whose signatures don't require knowledge of + /// the type being built. The generic interface extends this one. Some methods return + /// either an IBuilder or an IMessage; in these cases the generic interface redeclares + /// the same method with a type-specific signature. Implementations are encouraged to + /// use explicit interface implemenation for the non-generic form. This mirrors + /// how IEnumerable and IEnumerable<T> work. + /// + public interface IBuilderLite + { + /// + /// Returns true iff all required fields in the message and all + /// embedded messages are set. + /// + bool IsInitialized { get; } + + IBuilderLite WeakClear(); + IBuilderLite WeakMergeFrom(IMessageLite message); + IBuilderLite WeakMergeFrom(ByteString data); + IBuilderLite WeakMergeFrom(ByteString data, ExtensionRegistry registry); + IBuilderLite WeakMergeFrom(CodedInputStream input); + IBuilderLite WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry); + IMessageLite WeakBuild(); + IMessageLite WeakBuildPartial(); + IBuilderLite WeakClone(); + IMessageLite WeakDefaultInstanceForType { get; } + } + + /// + /// Interface implemented by Protocol Message builders. + /// TODO(jonskeet): Consider "SetXXX" methods returning the builder, as well as the properties. + /// + /// Type of message + /// Type of builder + public interface IBuilderLite : IBuilderLite + where TMessage : IMessageLite + where TBuilder : IBuilderLite + { + /// + /// Resets all fields to their default values. + /// + TBuilder Clear(); + + /// + /// Merge the specified other message which may be a different implementation of + /// the same message descriptor. + /// + TBuilder MergeFrom(IMessageLite other); + + /// + /// Constructs the final message. Once this is called, this Builder instance + /// is no longer valid, and calling any other method may throw a + /// NullReferenceException. If you need to continue working with the builder + /// after calling Build, call Clone first. + /// + /// the message + /// is missing one or more required fields; use BuildPartial to bypass + /// this check + TMessage Build(); + + /// + /// Like Build(), but does not throw an exception if the message is missing + /// required fields. Instead, a partial message is returned. + /// + TMessage BuildPartial(); + + /// + /// Clones this builder. + /// TODO(jonskeet): Explain depth of clone. + /// + TBuilder Clone(); + + /// + /// Parses a message of this type from the input and merges it with this + /// message, as if using MergeFrom(IMessage<T>). + /// + /// + /// Warning: This does not verify that all required fields are present + /// in the input message. If you call Build() without setting all + /// required fields, it will throw an UninitializedMessageException. + /// There are a few good ways to deal with this: + /// + /// Call IsInitialized to verify to verify that all required fields are + /// set before building. + /// Parse the message separately using one of the static ParseFrom + /// methods, then use MergeFrom(IMessage<T>) to merge it with + /// this one. ParseFrom will throw an InvalidProtocolBufferException + /// (an IOException) if some required fields are missing. + /// Use BuildPartial to build, which ignores missing required fields. + /// + /// + TBuilder MergeFrom(CodedInputStream input); + + /// + /// Like MergeFrom(CodedInputStream), but also parses extensions. + /// The extensions that you want to be able to parse must be registered + /// in . Extensions not in the registry + /// will be treated as unknown fields. + /// + TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry); + + /// + /// Get's the message's type's default instance. + /// + /// + TMessage DefaultInstanceForType { get; } + + /// + /// Like MergeFrom(Stream), but does not read until the end of the file. + /// Instead, the size of the message (encoded as a varint) is read first, + /// then the message data. Use Message.WriteDelimitedTo(Stream) to + /// write messages in this format. + /// + /// + TBuilder MergeDelimitedFrom(Stream input); + + /// + /// Like MergeDelimitedFrom(Stream) but supporting extensions. + /// + TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry); + + #region Convenience methods + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). + /// + TBuilder MergeFrom(ByteString data); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream, ExtensionRegistry). + /// + TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). + /// + TBuilder MergeFrom(byte[] data); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream, ExtensionRegistry). + /// + TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). Note that this method always reads + /// the entire input (unless it throws an exception). If you want it to + /// stop earlier, you will need to wrap the input in a wrapper + /// stream which limits reading. Or, use IMessage.WriteDelimitedTo(Stream) + /// to write your message and MmergeDelimitedFrom(Stream) to read it. + /// Despite usually reading the entire stream, this method never closes the stream. + /// + TBuilder MergeFrom(Stream input); + + /// + /// Parse as a message of this type and merge + /// it with the message being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream, ExtensionRegistry). + /// + TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry); + + #endregion + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IMessage.cs b/src/ProtocolBuffers/IMessage.cs index 4d37a8d2..7631a958 100644 --- a/src/ProtocolBuffers/IMessage.cs +++ b/src/ProtocolBuffers/IMessage.cs @@ -1,236 +1,249 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers { - - /// - /// Non-generic interface used for all parts of the API which don't require - /// any type knowledge. - /// - public interface IMessage : IMessageLite { - /// - /// Returns the message's type's descriptor. This differs from the - /// Descriptor property of each generated message class in that this - /// method is an abstract method of IMessage whereas Descriptor is - /// a static property of a specific class. They return the same thing. - /// - MessageDescriptor DescriptorForType { get; } - /// - /// Returns a collection of all the fields in this message which are set - /// and their corresponding values. A singular ("required" or "optional") - /// field is set iff HasField() returns true for that field. A "repeated" - /// field is set iff GetRepeatedFieldSize() is greater than zero. The - /// values are exactly what would be returned by calling - /// GetField(FieldDescriptor) for each field. The map - /// is guaranteed to be a sorted map, so iterating over it will return fields - /// in order by field number. - /// - IDictionary AllFields { get; } - - /// - /// Returns true if the given field is set. This is exactly equivalent - /// to calling the generated "Has" property corresponding to the field. - /// - /// the field is a repeated field, - /// or it's not a field of this type - bool HasField(FieldDescriptor field); - - /// - /// Obtains the value of the given field, or the default value if - /// it isn't set. For value type fields, the boxed value is returned. - /// For enum fields, the EnumValueDescriptor for the enum is returned. - /// For embedded message fields, the sub-message - /// is returned. For repeated fields, an IList<T> is returned. - /// - object this[FieldDescriptor field] { get; } - - /// - /// Returns the number of elements of a repeated field. This is - /// exactly equivalent to calling the generated "Count" property - /// corresponding to the field. - /// - /// the field is not a repeated field, - /// or it's not a field of this type - int GetRepeatedFieldCount(FieldDescriptor field); - - /// - /// Gets an element of a repeated field. For value type fields - /// excluding enums, the boxed value is returned. For embedded - /// message fields, the sub-message is returned. For enums, the - /// relevant EnumValueDescriptor is returned. - /// - /// the field is not a repeated field, - /// or it's not a field of this type - /// the index is out of - /// range for the repeated field's value - object this[FieldDescriptor field, int index] { get; } - - /// - /// Returns the unknown fields for this message. - /// - UnknownFieldSet UnknownFields { get; } - - /// - /// Returns true iff all required fields in the message and all embedded - /// messages are set. - /// - new bool IsInitialized { get; } - - /// - /// Serializes the message and writes it to the given output stream. - /// This does not flush or close the stream. - /// - /// - /// 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). - /// - new void WriteTo(CodedOutputStream output); - - /// - /// 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. - /// - /// - new void WriteDelimitedTo(Stream output); - - /// - /// Returns the number of bytes required to encode this message. - /// The result is only computed on the first call and memoized after that. - /// - new int SerializedSize { get; } - - #region Comparison and hashing - /// - /// 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. - /// - new bool Equals(object other); - - /// - /// Returns the hash code value for this message. - /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one! - /// - new int GetHashCode(); - #endregion - - #region Convenience methods - /// - /// Converts the message to a string in protocol buffer text format. - /// This is just a trivial wrapper around TextFormat.PrintToString. - /// - new string ToString(); - - /// - /// Serializes the message to a ByteString. This is a trivial wrapper - /// around WriteTo(CodedOutputStream). - /// - new ByteString ToByteString(); - - /// - /// Serializes the message to a byte array. This is a trivial wrapper - /// around WriteTo(CodedOutputStream). - /// - new byte[] ToByteArray(); - - /// - /// 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. - /// - /// - new void WriteTo(Stream output); - #endregion - - /// - /// Creates a builder for the type, but in a weakly typed manner. This - /// is typically implemented by strongly typed messages by just returning - /// the result of CreateBuilderForType. - /// - new IBuilder WeakCreateBuilderForType(); - - /// - /// Creates a builder with the same contents as this message. This - /// is typically implemented by strongly typed messages by just returning - /// the result of ToBuilder. - /// - new IBuilder WeakToBuilder(); - - new IMessage WeakDefaultInstanceForType { get; } - } - - public interface IMessage : IMessage, IMessageLite { - /// - /// Returns an instance of this message type with all fields set to - /// their default values. This may or may not be a singleton. This differs - /// from the DefaultInstance property of each generated message class in that this - /// method is an abstract method of IMessage whereas DefaultInstance is - /// a static property of a specific class. They return the same thing. - /// - new TMessage DefaultInstanceForType { get; } - } - - /// - /// Type-safe interface for all generated messages to implement. - /// - public interface IMessage : IMessage, IMessageLite - where TMessage : IMessage - where TBuilder : IBuilder { - #region Builders - /// - /// Constructs a new builder for a message of the same type as this message. - /// - new TBuilder CreateBuilderForType(); - /// - /// Creates a builder with the same contents as this current instance. - /// This is typically implemented by strongly typed messages by just - /// returning the result of ToBuilder(). - /// - new TBuilder ToBuilder(); - #endregion - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers +{ + /// + /// Non-generic interface used for all parts of the API which don't require + /// any type knowledge. + /// + public interface IMessage : IMessageLite + { + /// + /// Returns the message's type's descriptor. This differs from the + /// Descriptor property of each generated message class in that this + /// method is an abstract method of IMessage whereas Descriptor is + /// a static property of a specific class. They return the same thing. + /// + MessageDescriptor DescriptorForType { get; } + + /// + /// Returns a collection of all the fields in this message which are set + /// and their corresponding values. A singular ("required" or "optional") + /// field is set iff HasField() returns true for that field. A "repeated" + /// field is set iff GetRepeatedFieldSize() is greater than zero. The + /// values are exactly what would be returned by calling + /// GetField(FieldDescriptor) for each field. The map + /// is guaranteed to be a sorted map, so iterating over it will return fields + /// in order by field number. + /// + IDictionary AllFields { get; } + + /// + /// Returns true if the given field is set. This is exactly equivalent + /// to calling the generated "Has" property corresponding to the field. + /// + /// the field is a repeated field, + /// or it's not a field of this type + bool HasField(FieldDescriptor field); + + /// + /// Obtains the value of the given field, or the default value if + /// it isn't set. For value type fields, the boxed value is returned. + /// For enum fields, the EnumValueDescriptor for the enum is returned. + /// For embedded message fields, the sub-message + /// is returned. For repeated fields, an IList<T> is returned. + /// + object this[FieldDescriptor field] { get; } + + /// + /// Returns the number of elements of a repeated field. This is + /// exactly equivalent to calling the generated "Count" property + /// corresponding to the field. + /// + /// the field is not a repeated field, + /// or it's not a field of this type + int GetRepeatedFieldCount(FieldDescriptor field); + + /// + /// Gets an element of a repeated field. For value type fields + /// excluding enums, the boxed value is returned. For embedded + /// message fields, the sub-message is returned. For enums, the + /// relevant EnumValueDescriptor is returned. + /// + /// the field is not a repeated field, + /// or it's not a field of this type + /// the index is out of + /// range for the repeated field's value + object this[FieldDescriptor field, int index] { get; } + + /// + /// Returns the unknown fields for this message. + /// + UnknownFieldSet UnknownFields { get; } + + /// + /// Returns true iff all required fields in the message and all embedded + /// messages are set. + /// + new bool IsInitialized { get; } + + /// + /// Serializes the message and writes it to the given output stream. + /// This does not flush or close the stream. + /// + /// + /// 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). + /// + new void WriteTo(CodedOutputStream output); + + /// + /// 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. + /// + /// + new void WriteDelimitedTo(Stream output); + + /// + /// Returns the number of bytes required to encode this message. + /// The result is only computed on the first call and memoized after that. + /// + new int SerializedSize { get; } + + #region Comparison and hashing + + /// + /// 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. + /// + new bool Equals(object other); + + /// + /// Returns the hash code value for this message. + /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one! + /// + new int GetHashCode(); + + #endregion + + #region Convenience methods + + /// + /// Converts the message to a string in protocol buffer text format. + /// This is just a trivial wrapper around TextFormat.PrintToString. + /// + new string ToString(); + + /// + /// Serializes the message to a ByteString. This is a trivial wrapper + /// around WriteTo(CodedOutputStream). + /// + new ByteString ToByteString(); + + /// + /// Serializes the message to a byte array. This is a trivial wrapper + /// around WriteTo(CodedOutputStream). + /// + new byte[] ToByteArray(); + + /// + /// 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. + /// + /// + new void WriteTo(Stream output); + + #endregion + + /// + /// Creates a builder for the type, but in a weakly typed manner. This + /// is typically implemented by strongly typed messages by just returning + /// the result of CreateBuilderForType. + /// + new IBuilder WeakCreateBuilderForType(); + + /// + /// Creates a builder with the same contents as this message. This + /// is typically implemented by strongly typed messages by just returning + /// the result of ToBuilder. + /// + new IBuilder WeakToBuilder(); + + new IMessage WeakDefaultInstanceForType { get; } + } + + public interface IMessage : IMessage, IMessageLite + { + /// + /// Returns an instance of this message type with all fields set to + /// their default values. This may or may not be a singleton. This differs + /// from the DefaultInstance property of each generated message class in that this + /// method is an abstract method of IMessage whereas DefaultInstance is + /// a static property of a specific class. They return the same thing. + /// + new TMessage DefaultInstanceForType { get; } + } + + /// + /// Type-safe interface for all generated messages to implement. + /// + public interface IMessage : IMessage, IMessageLite + where TMessage : IMessage + where TBuilder : IBuilder + { + #region Builders + + /// + /// Constructs a new builder for a message of the same type as this message. + /// + new TBuilder CreateBuilderForType(); + + /// + /// Creates a builder with the same contents as this current instance. + /// This is typically implemented by strongly typed messages by just + /// returning the result of ToBuilder(). + /// + new TBuilder ToBuilder(); + + #endregion + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IMessageLite.cs b/src/ProtocolBuffers/IMessageLite.cs index 48660882..5fc0d94f 100644 --- a/src/ProtocolBuffers/IMessageLite.cs +++ b/src/ProtocolBuffers/IMessageLite.cs @@ -1,179 +1,190 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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; - -namespace Google.ProtocolBuffers { - - /// - /// Non-generic interface used for all parts of the API which don't require - /// any type knowledge. - /// - public interface IMessageLite { - - /// - /// Returns true iff all required fields in the message and all embedded - /// messages are set. - /// - bool IsInitialized { get; } - - /// - /// Serializes the message and writes it to the given output stream. - /// This does not flush or close the stream. - /// - /// - /// 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). - /// - void WriteTo(CodedOutputStream output); - - /// - /// 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. - /// - /// - void WriteDelimitedTo(Stream output); - - /// - /// Returns the number of bytes required to encode this message. - /// The result is only computed on the first call and memoized after that. - /// - int SerializedSize { get; } - - #region Comparison and hashing - /// - /// 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. - /// - bool Equals(object other); - - /// - /// Returns the hash code value for this message. - /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one! - /// - int GetHashCode(); - #endregion - - #region Convenience methods - /// - /// Converts the message to a string in protocol buffer text format. - /// This is just a trivial wrapper around TextFormat.PrintToString. - /// - string ToString(); - - /// - /// Converts the message to a string. - /// - void PrintTo(TextWriter writer); - - /// - /// Serializes the message to a ByteString. This is a trivial wrapper - /// around WriteTo(CodedOutputStream). - /// - ByteString ToByteString(); - - /// - /// Serializes the message to a byte array. This is a trivial wrapper - /// around WriteTo(CodedOutputStream). - /// - byte[] ToByteArray(); - - /// - /// 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. - /// - /// - void WriteTo(Stream output); - #endregion - - /// - /// Creates a builder for the type, but in a weakly typed manner. This - /// is typically implemented by strongly typed messages by just returning - /// the result of CreateBuilderForType. - /// - IBuilderLite WeakCreateBuilderForType(); - - /// - /// Creates a builder with the same contents as this message. This - /// is typically implemented by strongly typed messages by just returning - /// the result of ToBuilder. - /// - IBuilderLite WeakToBuilder(); - - IMessageLite WeakDefaultInstanceForType { get; } - } - - public interface IMessageLite : IMessageLite { - /// - /// Returns an instance of this message type with all fields set to - /// their default values. This may or may not be a singleton. This differs - /// from the DefaultInstance property of each generated message class in that this - /// method is an abstract method of IMessage whereas DefaultInstance is - /// a static property of a specific class. They return the same thing. - /// - TMessage DefaultInstanceForType { get; } - } - - /// - /// Type-safe interface for all generated messages to implement. - /// - public interface IMessageLite : IMessageLite - where TMessage : IMessageLite - where TBuilder : IBuilderLite { - #region Builders - /// - /// Constructs a new builder for a message of the same type as this message. - /// - TBuilder CreateBuilderForType(); - /// - /// Creates a builder with the same contents as this current instance. - /// This is typically implemented by strongly typed messages by just - /// returning the result of ToBuilder(). - /// - TBuilder ToBuilder(); - #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; + +namespace Google.ProtocolBuffers +{ + /// + /// Non-generic interface used for all parts of the API which don't require + /// any type knowledge. + /// + public interface IMessageLite + { + /// + /// Returns true iff all required fields in the message and all embedded + /// messages are set. + /// + bool IsInitialized { get; } + + /// + /// Serializes the message and writes it to the given output stream. + /// This does not flush or close the stream. + /// + /// + /// 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). + /// + void WriteTo(CodedOutputStream output); + + /// + /// 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. + /// + /// + void WriteDelimitedTo(Stream output); + + /// + /// Returns the number of bytes required to encode this message. + /// The result is only computed on the first call and memoized after that. + /// + int SerializedSize { get; } + + #region Comparison and hashing + + /// + /// 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. + /// + bool Equals(object other); + + /// + /// Returns the hash code value for this message. + /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one! + /// + int GetHashCode(); + + #endregion + + #region Convenience methods + + /// + /// Converts the message to a string in protocol buffer text format. + /// This is just a trivial wrapper around TextFormat.PrintToString. + /// + string ToString(); + + /// + /// Converts the message to a string. + /// + void PrintTo(TextWriter writer); + + /// + /// Serializes the message to a ByteString. This is a trivial wrapper + /// around WriteTo(CodedOutputStream). + /// + ByteString ToByteString(); + + /// + /// Serializes the message to a byte array. This is a trivial wrapper + /// around WriteTo(CodedOutputStream). + /// + byte[] ToByteArray(); + + /// + /// 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. + /// + /// + void WriteTo(Stream output); + + #endregion + + /// + /// Creates a builder for the type, but in a weakly typed manner. This + /// is typically implemented by strongly typed messages by just returning + /// the result of CreateBuilderForType. + /// + IBuilderLite WeakCreateBuilderForType(); + + /// + /// Creates a builder with the same contents as this message. This + /// is typically implemented by strongly typed messages by just returning + /// the result of ToBuilder. + /// + IBuilderLite WeakToBuilder(); + + IMessageLite WeakDefaultInstanceForType { get; } + } + + public interface IMessageLite : IMessageLite + { + /// + /// Returns an instance of this message type with all fields set to + /// their default values. This may or may not be a singleton. This differs + /// from the DefaultInstance property of each generated message class in that this + /// method is an abstract method of IMessage whereas DefaultInstance is + /// a static property of a specific class. They return the same thing. + /// + TMessage DefaultInstanceForType { get; } + } + + /// + /// Type-safe interface for all generated messages to implement. + /// + public interface IMessageLite : IMessageLite + where TMessage : IMessageLite + where TBuilder : IBuilderLite + { + #region Builders + + /// + /// Constructs a new builder for a message of the same type as this message. + /// + TBuilder CreateBuilderForType(); + + /// + /// Creates a builder with the same contents as this current instance. + /// This is typically implemented by strongly typed messages by just + /// returning the result of ToBuilder(). + /// + TBuilder ToBuilder(); + + #endregion + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IRpcChannel.cs b/src/ProtocolBuffers/IRpcChannel.cs index 7cb0028d..4ca24ea7 100644 --- a/src/ProtocolBuffers/IRpcChannel.cs +++ b/src/ProtocolBuffers/IRpcChannel.cs @@ -1,59 +1,63 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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; - -namespace Google.ProtocolBuffers { - /// - /// Interface for an RPC channel. A channel represents a communication line to - /// a service (IService implementation) which can be used to call that service's - /// methods. The service may be running on another machine. Normally, you should - /// not call an IRpcChannel directly, but instead construct a stub wrapping it. - /// Generated service classes contain a CreateStub method for precisely this purpose. - /// - public interface IRpcChannel { - /// - /// Calls the given method of the remote service. This method is similar - /// to with one important difference: the - /// caller decides the types of the IMessage objects, not the implementation. - /// The request may be of any type as long as request.Descriptor == method.InputType. - /// The response passed to the callback will be of the same type as - /// (which must be such that - /// responsePrototype.Descriptor == method.OutputType). - /// - void CallMethod(MethodDescriptor method, IRpcController controller, - IMessage request, IMessage responsePrototype, Action 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; + +namespace Google.ProtocolBuffers +{ + /// + /// Interface for an RPC channel. A channel represents a communication line to + /// a service (IService implementation) which can be used to call that service's + /// methods. The service may be running on another machine. Normally, you should + /// not call an IRpcChannel directly, but instead construct a stub wrapping it. + /// Generated service classes contain a CreateStub method for precisely this purpose. + /// + public interface IRpcChannel + { + /// + /// Calls the given method of the remote service. This method is similar + /// to with one important difference: the + /// caller decides the types of the IMessage objects, not the implementation. + /// The request may be of any type as long as request.Descriptor == method.InputType. + /// The response passed to the callback will be of the same type as + /// (which must be such that + /// responsePrototype.Descriptor == method.OutputType). + /// + void CallMethod(MethodDescriptor method, IRpcController controller, + IMessage request, IMessage responsePrototype, Action done); + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IRpcController.cs b/src/ProtocolBuffers/IRpcController.cs index d0e3c7ca..f6220e37 100644 --- a/src/ProtocolBuffers/IRpcController.cs +++ b/src/ProtocolBuffers/IRpcController.cs @@ -1,118 +1,125 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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 { - /// - /// Mediates a single method call. The primary purpose of the controller - /// is to provide a way to manipulate settings specific to the - /// RPC implementation and to find out about RPC-level errors. - /// - /// The methods provided by this interface are intended to be a "least - /// common denominator" set of features which we expect all implementations to - /// support. Specific implementations may provide more advanced features, - /// (e.g. deadline propagation). - /// - public interface IRpcController { - - #region Client side calls - // These calls may be made from the client side only. Their results - // are undefined on the server side (may throw exceptions). - - /// - /// Resets the controller to its initial state so that it may be reused in - /// a new call. This can be called from the client side only. It must not - /// be called while an RPC is in progress. - /// - void Reset(); - - /// - /// After a call has finished, returns true if the call failed. The possible - /// reasons for failure depend on the RPC implementation. Failed must - /// only be called on the client side, and must not be called before a call has - /// finished. - /// - bool Failed { get; } - - /// - /// If Failed is true, ErrorText returns a human-readable description of the error. - /// - string ErrorText { get; } - - /// - /// Advises the RPC system that the caller desires that the RPC call be - /// canceled. The RPC system may cancel it immediately, may wait awhile and - /// then cancel it, or may not even cancel the call at all. If the call is - /// canceled, the "done" callback will still be called and the RpcController - /// will indicate that the call failed at that time. - /// - void StartCancel(); - #endregion - - #region Server side calls - // These calls may be made from the server side only. Their results - // are undefined on the client side (may throw exceptions). - - /// - /// Causes Failed to return true on the client side. - /// will be incorporated into the message returned by ErrorText. - /// If you find you need to return machine-readable information about - /// failures, you should incorporate it into your response protocol buffer - /// and should *not* call SetFailed. - /// - void SetFailed(string reason); - - /// - /// If true, indicates that the client canceled the RPC, so the server may as - /// well give up on replying to it. This method must be called on the server - /// side only. The server should still call the final "done" callback. - /// - bool isCanceled(); - - /// - /// Requests that the given callback be called when the RPC is canceled. - /// The parameter passed to the callback will always be null. The callback will - /// be called exactly once. If the RPC completes without being canceled, the - /// callback will be called after completion. If the RPC has already been canceled - /// when NotifyOnCancel is called, the callback will be called immediately. - /// - /// NotifyOnCancel must be called no more than once per request. It must be - /// called on the server side only. - /// - /// - void NotifyOnCancel(Action callback); - #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; + +namespace Google.ProtocolBuffers +{ + /// + /// Mediates a single method call. The primary purpose of the controller + /// is to provide a way to manipulate settings specific to the + /// RPC implementation and to find out about RPC-level errors. + /// + /// The methods provided by this interface are intended to be a "least + /// common denominator" set of features which we expect all implementations to + /// support. Specific implementations may provide more advanced features, + /// (e.g. deadline propagation). + /// + public interface IRpcController + { + #region Client side calls + + // These calls may be made from the client side only. Their results + // are undefined on the server side (may throw exceptions). + + /// + /// Resets the controller to its initial state so that it may be reused in + /// a new call. This can be called from the client side only. It must not + /// be called while an RPC is in progress. + /// + void Reset(); + + /// + /// After a call has finished, returns true if the call failed. The possible + /// reasons for failure depend on the RPC implementation. Failed must + /// only be called on the client side, and must not be called before a call has + /// finished. + /// + bool Failed { get; } + + /// + /// If Failed is true, ErrorText returns a human-readable description of the error. + /// + string ErrorText { get; } + + /// + /// Advises the RPC system that the caller desires that the RPC call be + /// canceled. The RPC system may cancel it immediately, may wait awhile and + /// then cancel it, or may not even cancel the call at all. If the call is + /// canceled, the "done" callback will still be called and the RpcController + /// will indicate that the call failed at that time. + /// + void StartCancel(); + + #endregion + + #region Server side calls + + // These calls may be made from the server side only. Their results + // are undefined on the client side (may throw exceptions). + + /// + /// Causes Failed to return true on the client side. + /// will be incorporated into the message returned by ErrorText. + /// If you find you need to return machine-readable information about + /// failures, you should incorporate it into your response protocol buffer + /// and should *not* call SetFailed. + /// + void SetFailed(string reason); + + /// + /// If true, indicates that the client canceled the RPC, so the server may as + /// well give up on replying to it. This method must be called on the server + /// side only. The server should still call the final "done" callback. + /// + bool isCanceled(); + + /// + /// Requests that the given callback be called when the RPC is canceled. + /// The parameter passed to the callback will always be null. The callback will + /// be called exactly once. If the RPC completes without being canceled, the + /// callback will be called after completion. If the RPC has already been canceled + /// when NotifyOnCancel is called, the callback will be called immediately. + /// + /// NotifyOnCancel must be called no more than once per request. It must be + /// called on the server side only. + /// + /// + void NotifyOnCancel(Action callback); + + #endregion + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IRpcDispatch.cs b/src/ProtocolBuffers/IRpcDispatch.cs index 19f656ab..5abe4f87 100644 --- a/src/ProtocolBuffers/IRpcDispatch.cs +++ b/src/ProtocolBuffers/IRpcDispatch.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,24 +31,26 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE 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 { - /// - /// - /// - public interface IRpcServerStub - { - IMessageLite CallMethod(string methodName, CodedInputStream input, ExtensionRegistry registry); - } + /// + /// + /// + public interface IRpcServerStub + { + IMessageLite CallMethod(string methodName, CodedInputStream input, ExtensionRegistry registry); + } - public interface IRpcDispatch - { - TMessage CallMethod(string method, IMessageLite request, IBuilderLite response) - where TMessage : IMessageLite - where TBuilder : IBuilderLite; - } -} + public interface IRpcDispatch + { + TMessage CallMethod(string method, IMessageLite request, + IBuilderLite response) + where TMessage : IMessageLite + where TBuilder : IBuilderLite; + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IService.cs b/src/ProtocolBuffers/IService.cs index 872a302a..61af35c1 100644 --- a/src/ProtocolBuffers/IService.cs +++ b/src/ProtocolBuffers/IService.cs @@ -1,98 +1,102 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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; - -namespace Google.ProtocolBuffers { - /// - /// Base interface for protocol-buffer-based RPC services. Services themselves - /// are abstract classes (implemented either by servers or as stubs) but they - /// implement this itnerface. The methods of this interface can be used to call - /// the methods of the service without knowing its exact type at compile time - /// (analagous to the IMessage interface). - /// - public interface IService { - /// - /// The ServiceDescriptor describing this service and its methods. - /// - ServiceDescriptor DescriptorForType { get; } - - /// - /// Call a method of the service specified by MethodDescriptor. This is - /// normally implemented as a simple switch that calls the standard - /// definitions of the service's methods. - /// - /// Preconditions - /// - /// method.Service == DescriptorForType - /// request is of the exact same class as the object returned by GetRequestPrototype(method) - /// controller is of the correct type for the RPC implementation being used by this service. - /// For stubs, the "correct type" depends on the IRpcChannel which the stub is using. Server-side - /// implementations are expected to accept whatever type of IRpcController the server-side RPC implementation - /// uses. - /// - /// - /// - /// Postconditions - /// - /// will be called when the method is complete. - /// This may before CallMethod returns or it may be at some point in the future. - /// The parameter to is the response. It will be of the - /// exact same type as would be returned by . - /// If the RPC failed, the parameter to will be null. - /// Further details about the failure can be found by querying . - /// - /// - /// - void CallMethod(MethodDescriptor method, IRpcController controller, - IMessage request, Action done); - - /// - /// CallMethod requires that the request passed in is of a particular implementation - /// of IMessage. This method gets the default instance of this type of a given method. - /// You can then call WeakCreateBuilderForType to create a builder to build an object which - /// you can then pass to CallMethod. - /// - IMessage GetRequestPrototype(MethodDescriptor method); - - /// - /// Like GetRequestPrototype, but returns a prototype of the response message. - /// This is generally not needed because the IService implementation contructs - /// the response message itself, but it may be useful in some cases to know ahead - /// of time what type of object will be returned. - /// - IMessage GetResponsePrototype(MethodDescriptor method); - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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; + +namespace Google.ProtocolBuffers +{ + /// + /// Base interface for protocol-buffer-based RPC services. Services themselves + /// are abstract classes (implemented either by servers or as stubs) but they + /// implement this itnerface. The methods of this interface can be used to call + /// the methods of the service without knowing its exact type at compile time + /// (analagous to the IMessage interface). + /// + public interface IService + { + /// + /// The ServiceDescriptor describing this service and its methods. + /// + ServiceDescriptor DescriptorForType { get; } + + /// + /// Call a method of the service specified by MethodDescriptor. This is + /// normally implemented as a simple switch that calls the standard + /// definitions of the service's methods. + /// + /// Preconditions + /// + /// method.Service == DescriptorForType + /// request is of the exact same class as the object returned by GetRequestPrototype(method) + /// controller is of the correct type for the RPC implementation being used by this service. + /// For stubs, the "correct type" depends on the IRpcChannel which the stub is using. Server-side + /// implementations are expected to accept whatever type of IRpcController the server-side RPC implementation + /// uses. + /// + /// + /// + /// Postconditions + /// + /// will be called when the method is complete. + /// This may before CallMethod returns or it may be at some point in the future. + /// The parameter to is the response. It will be of the + /// exact same type as would be returned by . + /// If the RPC failed, the parameter to will be null. + /// Further details about the failure can be found by querying . + /// + /// + /// + void CallMethod(MethodDescriptor method, IRpcController controller, + IMessage request, Action done); + + /// + /// CallMethod requires that the request passed in is of a particular implementation + /// of IMessage. This method gets the default instance of this type of a given method. + /// You can then call WeakCreateBuilderForType to create a builder to build an object which + /// you can then pass to CallMethod. + /// + IMessage GetRequestPrototype(MethodDescriptor method); + + /// + /// Like GetRequestPrototype, but returns a prototype of the response message. + /// This is generally not needed because the IService implementation contructs + /// the response message itself, but it may be useful in some cases to know ahead + /// of time what type of object will be returned. + /// + IMessage GetResponsePrototype(MethodDescriptor method); + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/InvalidProtocolBufferException.cs b/src/ProtocolBuffers/InvalidProtocolBufferException.cs index f3ebb5f6..40a377cb 100644 --- a/src/ProtocolBuffers/InvalidProtocolBufferException.cs +++ b/src/ProtocolBuffers/InvalidProtocolBufferException.cs @@ -1,99 +1,112 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System.IO; - -namespace Google.ProtocolBuffers { - /// - /// Thrown when a protocol message being parsed is invalid in some way, - /// e.g. it contains a malformed varint or a negative byte length. - /// - public sealed class InvalidProtocolBufferException : IOException { - - internal InvalidProtocolBufferException(string message) - : base(message) { - } - - public static InvalidProtocolBufferException TruncatedMessage() { - return new InvalidProtocolBufferException( - "While parsing a protocol message, the input ended unexpectedly " + - "in the middle of a field. This could mean either than the " + - "input has been truncated or that an embedded message " + - "misreported its own length."); - } - - internal static InvalidProtocolBufferException NegativeSize() { - return new InvalidProtocolBufferException( - "CodedInputStream encountered an embedded string or message " + - "which claimed to have negative size."); - } - - public static InvalidProtocolBufferException MalformedVarint() { - return new InvalidProtocolBufferException( - "CodedInputStream encountered a malformed varint."); - } - - internal static InvalidProtocolBufferException InvalidTag() { - return new InvalidProtocolBufferException( - "Protocol message contained an invalid tag (zero)."); - } - - internal static InvalidProtocolBufferException InvalidEndTag() { - return new InvalidProtocolBufferException( - "Protocol message end-group tag did not match expected tag."); - } - - internal static InvalidProtocolBufferException InvalidWireType() { - return new InvalidProtocolBufferException( - "Protocol message tag had invalid wire type."); - } - - internal static InvalidProtocolBufferException RecursionLimitExceeded() { - return new InvalidProtocolBufferException( - "Protocol message had too many levels of nesting. May be malicious. " + - "Use CodedInputStream.SetRecursionLimit() to increase the depth limit."); - } - - internal static InvalidProtocolBufferException SizeLimitExceeded() { - return new InvalidProtocolBufferException( - "Protocol message was too large. May be malicious. " + - "Use CodedInputStream.SetSizeLimit() to increase the size limit."); - } - - internal static InvalidProtocolBufferException InvalidMessageStreamTag() { - return new InvalidProtocolBufferException( - "Stream of protocol messages had invalid tag. Expected tag is length-delimited field 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.IO; + +namespace Google.ProtocolBuffers +{ + /// + /// Thrown when a protocol message being parsed is invalid in some way, + /// e.g. it contains a malformed varint or a negative byte length. + /// + public sealed class InvalidProtocolBufferException : IOException + { + internal InvalidProtocolBufferException(string message) + : base(message) + { + } + + public static InvalidProtocolBufferException TruncatedMessage() + { + return new InvalidProtocolBufferException( + "While parsing a protocol message, the input ended unexpectedly " + + "in the middle of a field. This could mean either than the " + + "input has been truncated or that an embedded message " + + "misreported its own length."); + } + + internal static InvalidProtocolBufferException NegativeSize() + { + return new InvalidProtocolBufferException( + "CodedInputStream encountered an embedded string or message " + + "which claimed to have negative size."); + } + + public static InvalidProtocolBufferException MalformedVarint() + { + return new InvalidProtocolBufferException( + "CodedInputStream encountered a malformed varint."); + } + + internal static InvalidProtocolBufferException InvalidTag() + { + return new InvalidProtocolBufferException( + "Protocol message contained an invalid tag (zero)."); + } + + internal static InvalidProtocolBufferException InvalidEndTag() + { + return new InvalidProtocolBufferException( + "Protocol message end-group tag did not match expected tag."); + } + + internal static InvalidProtocolBufferException InvalidWireType() + { + return new InvalidProtocolBufferException( + "Protocol message tag had invalid wire type."); + } + + internal static InvalidProtocolBufferException RecursionLimitExceeded() + { + return new InvalidProtocolBufferException( + "Protocol message had too many levels of nesting. May be malicious. " + + "Use CodedInputStream.SetRecursionLimit() to increase the depth limit."); + } + + internal static InvalidProtocolBufferException SizeLimitExceeded() + { + return new InvalidProtocolBufferException( + "Protocol message was too large. May be malicious. " + + "Use CodedInputStream.SetSizeLimit() to increase the size limit."); + } + + internal static InvalidProtocolBufferException InvalidMessageStreamTag() + { + return new InvalidProtocolBufferException( + "Stream of protocol messages had invalid tag. Expected tag is length-delimited field 1."); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/MessageStreamIterator.cs b/src/ProtocolBuffers/MessageStreamIterator.cs index 0466262b..7bc32383 100644 --- a/src/ProtocolBuffers/MessageStreamIterator.cs +++ b/src/ProtocolBuffers/MessageStreamIterator.cs @@ -1,206 +1,239 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Collections; -using System.IO; -using System.Reflection; - -namespace Google.ProtocolBuffers { - - /// - /// Iterates over data created using a . - /// Unlike MessageStreamWriter, this class is not usually constructed directly with - /// a stream; instead it is provided with a way of opening a stream when iteration - /// is started. The stream is closed when the iteration is completed or the enumerator - /// is disposed. (This occurs naturally when using foreach.) - /// - public class MessageStreamIterator : IEnumerable - where TMessage : IMessage { - - private readonly StreamProvider streamProvider; - private readonly ExtensionRegistry extensionRegistry; - private readonly int sizeLimit; - - // Type.EmptyTypes isn't present on the compact framework - private static readonly Type[] EmptyTypes = new Type[0]; - - /// - /// Delegate created via reflection trickery (once per type) to create a builder - /// and read a message from a CodedInputStream with it. Note that unlike in Java, - /// there's one static field per constructed type. - /// - private static readonly Func messageReader = BuildMessageReader(); - - /// - /// Any exception (within reason) thrown within messageReader is caught and rethrown in the constructor. - /// This makes life a lot simpler for the caller. - /// - private static Exception typeInitializationException; - - /// - /// Creates the delegate later used to read messages. This is only called once per type, but to - /// avoid exceptions occurring at confusing times, if this fails it will set typeInitializationException - /// to the appropriate error and return null. - /// - private static Func BuildMessageReader() { - try { - Type builderType = FindBuilderType(); - - // Yes, it's redundant to find this again, but it's only the once... - MethodInfo createBuilderMethod = typeof(TMessage).GetMethod("CreateBuilder", EmptyTypes); - Delegate builderBuilder = Delegate.CreateDelegate( - typeof(Func<>).MakeGenericType(builderType), null, createBuilderMethod); - - MethodInfo buildMethod = typeof(MessageStreamIterator) - .GetMethod("BuildImpl", BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod(typeof(TMessage), builderType); - - return (Func)Delegate.CreateDelegate( - typeof(Func), builderBuilder, buildMethod); - } catch (ArgumentException e) { - typeInitializationException = e; - } catch (InvalidOperationException e) { - typeInitializationException = e; - } catch (InvalidCastException e) { - // Can't see why this would happen, but best to know about it. - typeInitializationException = e; - } - return null; - } - - /// - /// Works out the builder type for TMessage, or throws an ArgumentException to explain why it can't. - /// - private static Type FindBuilderType() { - MethodInfo createBuilderMethod = typeof(TMessage).GetMethod("CreateBuilder", EmptyTypes); - if (createBuilderMethod == null) { - throw new ArgumentException("Message type " + typeof(TMessage).FullName + " has no CreateBuilder method."); - } - if (createBuilderMethod.ReturnType == typeof(void)) { - throw new ArgumentException("CreateBuilder method in " + typeof(TMessage).FullName + " has void return type"); - } - Type builderType = createBuilderMethod.ReturnType; - Type messageInterface = typeof(IMessage<,>).MakeGenericType(typeof(TMessage), builderType); - Type builderInterface = typeof(IBuilder<,>).MakeGenericType(typeof(TMessage), builderType); - if (Array.IndexOf(typeof(TMessage).GetInterfaces(), messageInterface) == -1) { - throw new ArgumentException("Message type " + typeof(TMessage) + " doesn't implement " + messageInterface.FullName); - } - if (Array.IndexOf(builderType.GetInterfaces(), builderInterface) == -1) { - throw new ArgumentException("Builder type " + typeof(TMessage) + " doesn't implement " + builderInterface.FullName); - } - return builderType; - } - -// This is only ever fetched by reflection, so the compiler may -// complain that it's unused -#pragma warning disable 0169 - /// - /// Method we'll use to build messageReader, with the first parameter fixed to TMessage.CreateBuilder. Note that we - /// have to introduce another type parameter (TMessage2) as we can't constrain TMessage for just a single method - /// (and we can't do it at the type level because we don't know TBuilder). However, by constraining TMessage2 - /// to not only implement IMessage appropriately but also to derive from TMessage2, we can avoid doing a cast - /// for every message; the implicit reference conversion will be fine. In practice, TMessage2 and TMessage will - /// be the same type when we construct the generic method by reflection. - /// - private static TMessage BuildImpl(Func builderBuilder, CodedInputStream input, ExtensionRegistry registry) - where TBuilder : IBuilder - where TMessage2 : TMessage, IMessage { - TBuilder builder = builderBuilder(); - input.ReadMessage(builder, registry); - return builder.Build(); - } -#pragma warning restore 0414 - - private static readonly uint ExpectedTag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); - - private MessageStreamIterator(StreamProvider streamProvider, ExtensionRegistry extensionRegistry, int sizeLimit) { - if (messageReader == null) { - throw typeInitializationException; - } - this.streamProvider = streamProvider; - this.extensionRegistry = extensionRegistry; - this.sizeLimit = sizeLimit; - } - - private MessageStreamIterator(StreamProvider streamProvider, ExtensionRegistry extensionRegistry) - : this (streamProvider, extensionRegistry, CodedInputStream.DefaultSizeLimit) { - } - - /// - /// Creates a new instance which uses the same stream provider as this one, - /// but the specified extension registry. - /// - public MessageStreamIterator WithExtensionRegistry(ExtensionRegistry newRegistry) { - return new MessageStreamIterator(streamProvider, newRegistry, sizeLimit); - } - - /// - /// Creates a new instance which uses the same stream provider and extension registry as this one, - /// but with the specified size limit. Note that this must be big enough for the largest message - /// and the tag and size preceding it. - /// - public MessageStreamIterator WithSizeLimit(int newSizeLimit) { - return new MessageStreamIterator(streamProvider, extensionRegistry, newSizeLimit); - } - - public static MessageStreamIterator FromFile(string file) { - return new MessageStreamIterator(() => File.OpenRead(file), ExtensionRegistry.Empty); - } - - public static MessageStreamIterator FromStreamProvider(StreamProvider streamProvider) { - return new MessageStreamIterator(streamProvider, ExtensionRegistry.Empty); - } - - public IEnumerator GetEnumerator() { - using (Stream stream = streamProvider()) { - CodedInputStream input = CodedInputStream.CreateInstance(stream); - input.SetSizeLimit(sizeLimit); - uint tag; - while ((tag = input.ReadTag()) != 0) { - if (tag != ExpectedTag) { - throw InvalidProtocolBufferException.InvalidMessageStreamTag(); - } - yield return messageReader(input, extensionRegistry); - input.ResetSizeCounter(); - } - } - } - - IEnumerator IEnumerable.GetEnumerator() { - return GetEnumerator(); - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Collections; +using System.IO; +using System.Reflection; + +namespace Google.ProtocolBuffers +{ + /// + /// Iterates over data created using a . + /// Unlike MessageStreamWriter, this class is not usually constructed directly with + /// a stream; instead it is provided with a way of opening a stream when iteration + /// is started. The stream is closed when the iteration is completed or the enumerator + /// is disposed. (This occurs naturally when using foreach.) + /// + public class MessageStreamIterator : IEnumerable + where TMessage : IMessage + { + private readonly StreamProvider streamProvider; + private readonly ExtensionRegistry extensionRegistry; + private readonly int sizeLimit; + + // Type.EmptyTypes isn't present on the compact framework + private static readonly Type[] EmptyTypes = new Type[0]; + + /// + /// Delegate created via reflection trickery (once per type) to create a builder + /// and read a message from a CodedInputStream with it. Note that unlike in Java, + /// there's one static field per constructed type. + /// + private static readonly Func messageReader = BuildMessageReader(); + + /// + /// Any exception (within reason) thrown within messageReader is caught and rethrown in the constructor. + /// This makes life a lot simpler for the caller. + /// + private static Exception typeInitializationException; + + /// + /// Creates the delegate later used to read messages. This is only called once per type, but to + /// avoid exceptions occurring at confusing times, if this fails it will set typeInitializationException + /// to the appropriate error and return null. + /// + private static Func BuildMessageReader() + { + try + { + Type builderType = FindBuilderType(); + + // Yes, it's redundant to find this again, but it's only the once... + MethodInfo createBuilderMethod = typeof (TMessage).GetMethod("CreateBuilder", EmptyTypes); + Delegate builderBuilder = Delegate.CreateDelegate( + typeof (Func<>).MakeGenericType(builderType), null, createBuilderMethod); + + MethodInfo buildMethod = typeof (MessageStreamIterator) + .GetMethod("BuildImpl", BindingFlags.Static | BindingFlags.NonPublic) + .MakeGenericMethod(typeof (TMessage), builderType); + + return (Func) Delegate.CreateDelegate( + typeof (Func), builderBuilder, buildMethod); + } + catch (ArgumentException e) + { + typeInitializationException = e; + } + catch (InvalidOperationException e) + { + typeInitializationException = e; + } + catch (InvalidCastException e) + { + // Can't see why this would happen, but best to know about it. + typeInitializationException = e; + } + return null; + } + + /// + /// Works out the builder type for TMessage, or throws an ArgumentException to explain why it can't. + /// + private static Type FindBuilderType() + { + MethodInfo createBuilderMethod = typeof (TMessage).GetMethod("CreateBuilder", EmptyTypes); + if (createBuilderMethod == null) + { + throw new ArgumentException("Message type " + typeof (TMessage).FullName + + " has no CreateBuilder method."); + } + if (createBuilderMethod.ReturnType == typeof (void)) + { + throw new ArgumentException("CreateBuilder method in " + typeof (TMessage).FullName + + " has void return type"); + } + Type builderType = createBuilderMethod.ReturnType; + Type messageInterface = typeof (IMessage<,>).MakeGenericType(typeof (TMessage), builderType); + Type builderInterface = typeof (IBuilder<,>).MakeGenericType(typeof (TMessage), builderType); + if (Array.IndexOf(typeof (TMessage).GetInterfaces(), messageInterface) == -1) + { + throw new ArgumentException("Message type " + typeof (TMessage) + " doesn't implement " + + messageInterface.FullName); + } + if (Array.IndexOf(builderType.GetInterfaces(), builderInterface) == -1) + { + throw new ArgumentException("Builder type " + typeof (TMessage) + " doesn't implement " + + builderInterface.FullName); + } + return builderType; + } + +// This is only ever fetched by reflection, so the compiler may +// complain that it's unused +#pragma warning disable 0169 + /// + /// Method we'll use to build messageReader, with the first parameter fixed to TMessage.CreateBuilder. Note that we + /// have to introduce another type parameter (TMessage2) as we can't constrain TMessage for just a single method + /// (and we can't do it at the type level because we don't know TBuilder). However, by constraining TMessage2 + /// to not only implement IMessage appropriately but also to derive from TMessage2, we can avoid doing a cast + /// for every message; the implicit reference conversion will be fine. In practice, TMessage2 and TMessage will + /// be the same type when we construct the generic method by reflection. + /// + private static TMessage BuildImpl(Func builderBuilder, CodedInputStream input, + ExtensionRegistry registry) + where TBuilder : IBuilder + where TMessage2 : TMessage, IMessage + { + TBuilder builder = builderBuilder(); + input.ReadMessage(builder, registry); + return builder.Build(); + } +#pragma warning restore 0414 + + private static readonly uint ExpectedTag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); + + private MessageStreamIterator(StreamProvider streamProvider, ExtensionRegistry extensionRegistry, int sizeLimit) + { + if (messageReader == null) + { + throw typeInitializationException; + } + this.streamProvider = streamProvider; + this.extensionRegistry = extensionRegistry; + this.sizeLimit = sizeLimit; + } + + private MessageStreamIterator(StreamProvider streamProvider, ExtensionRegistry extensionRegistry) + : this(streamProvider, extensionRegistry, CodedInputStream.DefaultSizeLimit) + { + } + + /// + /// Creates a new instance which uses the same stream provider as this one, + /// but the specified extension registry. + /// + public MessageStreamIterator WithExtensionRegistry(ExtensionRegistry newRegistry) + { + return new MessageStreamIterator(streamProvider, newRegistry, sizeLimit); + } + + /// + /// Creates a new instance which uses the same stream provider and extension registry as this one, + /// but with the specified size limit. Note that this must be big enough for the largest message + /// and the tag and size preceding it. + /// + public MessageStreamIterator WithSizeLimit(int newSizeLimit) + { + return new MessageStreamIterator(streamProvider, extensionRegistry, newSizeLimit); + } + + public static MessageStreamIterator FromFile(string file) + { + return new MessageStreamIterator(() => File.OpenRead(file), ExtensionRegistry.Empty); + } + + public static MessageStreamIterator FromStreamProvider(StreamProvider streamProvider) + { + return new MessageStreamIterator(streamProvider, ExtensionRegistry.Empty); + } + + public IEnumerator GetEnumerator() + { + using (Stream stream = streamProvider()) + { + CodedInputStream input = CodedInputStream.CreateInstance(stream); + input.SetSizeLimit(sizeLimit); + uint tag; + while ((tag = input.ReadTag()) != 0) + { + if (tag != ExpectedTag) + { + throw InvalidProtocolBufferException.InvalidMessageStreamTag(); + } + yield return messageReader(input, extensionRegistry); + input.ResetSizeCounter(); + } + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/MessageStreamWriter.cs b/src/ProtocolBuffers/MessageStreamWriter.cs index 2f6413ec..df1e10e2 100644 --- a/src/ProtocolBuffers/MessageStreamWriter.cs +++ b/src/ProtocolBuffers/MessageStreamWriter.cs @@ -1,64 +1,70 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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 { - /// - /// Writes multiple messages to the same stream. Each message is written - /// as if it were an element of a repeated field 1 in a larger protocol buffer. - /// This class takes no ownership of the stream it is given; it never closes the - /// stream. - /// - public sealed class MessageStreamWriter where T : IMessage { - - private readonly CodedOutputStream codedOutput; - - /// - /// Creates an instance which writes to the given stream. - /// - /// Stream to write messages to. - public MessageStreamWriter(Stream output) { - codedOutput = CodedOutputStream.CreateInstance(output); - } - - public void Write(T message) { - codedOutput.WriteMessage(1, message); - } - - public void Flush() { - codedOutput.Flush(); - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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 +{ + /// + /// Writes multiple messages to the same stream. Each message is written + /// as if it were an element of a repeated field 1 in a larger protocol buffer. + /// This class takes no ownership of the stream it is given; it never closes the + /// stream. + /// + public sealed class MessageStreamWriter where T : IMessage + { + private readonly CodedOutputStream codedOutput; + + /// + /// Creates an instance which writes to the given stream. + /// + /// Stream to write messages to. + public MessageStreamWriter(Stream output) + { + codedOutput = CodedOutputStream.CreateInstance(output); + } + + public void Write(T message) + { + codedOutput.WriteMessage(1, message); + } + + public void Flush() + { + codedOutput.Flush(); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/MessageUtil.cs b/src/ProtocolBuffers/MessageUtil.cs index 18d81027..a32bda88 100644 --- a/src/ProtocolBuffers/MessageUtil.cs +++ b/src/ProtocolBuffers/MessageUtil.cs @@ -1,94 +1,109 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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.Reflection; - -namespace Google.ProtocolBuffers { - /// - /// Utilities for arbitrary messages of an unknown type. This class does not use - /// generics precisely because it is designed for dynamically discovered types. - /// - public static class MessageUtil { - - /// - /// Returns the default message for the given type. If an exception is thrown - /// (directly from this code), the message will be suitable to be displayed to a user. - /// - /// - /// The type parameter is null. - /// The type doesn't implement IMessage, or doesn't - /// have a static DefaultMessage property of the same type, or is generic or abstract. - /// - public static IMessage GetDefaultMessage(Type type) { - if (type == null) { - throw new ArgumentNullException("type", "No type specified."); - } - if (type.IsAbstract || type.IsGenericTypeDefinition) { - throw new ArgumentException("Unable to get a default message for an abstract or generic type (" + type.FullName + ")"); - } - if (!typeof(IMessage).IsAssignableFrom(type)) { - throw new ArgumentException("Unable to get a default message for non-message type (" + type.FullName + ")"); - } - PropertyInfo property = type.GetProperty("DefaultInstance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); - if (property == null) { - throw new ArgumentException(type.FullName + " doesn't have a static DefaultInstance property"); - } - if (property.PropertyType != type) { - throw new ArgumentException(type.FullName + ".DefaultInstance property is of the wrong type"); - } - return (IMessage) property.GetValue(null, null); - } - - /// - /// Returns the default message for the type with the given name. This is just - /// a convenience wrapper around calling Type.GetType and then GetDefaultMessage. - /// If an exception is thrown, the message will be suitable to be displayed to a user. - /// - /// - /// The typeName parameter is null. - /// The type doesn't implement IMessage, or doesn't - /// have a static DefaultMessage property of the same type, or can't be found. - public static IMessage GetDefaultMessage(string typeName) { - if (typeName == null) { - throw new ArgumentNullException("typeName", "No type name specified."); - } - Type type = Type.GetType(typeName); - if (type == null) { - throw new ArgumentException("Unable to load type " + typeName); - } - return GetDefaultMessage(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 System.Reflection; + +namespace Google.ProtocolBuffers +{ + /// + /// Utilities for arbitrary messages of an unknown type. This class does not use + /// generics precisely because it is designed for dynamically discovered types. + /// + public static class MessageUtil + { + /// + /// Returns the default message for the given type. If an exception is thrown + /// (directly from this code), the message will be suitable to be displayed to a user. + /// + /// + /// The type parameter is null. + /// The type doesn't implement IMessage, or doesn't + /// have a static DefaultMessage property of the same type, or is generic or abstract. + /// + public static IMessage GetDefaultMessage(Type type) + { + if (type == null) + { + throw new ArgumentNullException("type", "No type specified."); + } + if (type.IsAbstract || type.IsGenericTypeDefinition) + { + throw new ArgumentException("Unable to get a default message for an abstract or generic type (" + + type.FullName + ")"); + } + if (!typeof (IMessage).IsAssignableFrom(type)) + { + throw new ArgumentException("Unable to get a default message for non-message type (" + type.FullName + + ")"); + } + PropertyInfo property = type.GetProperty("DefaultInstance", + BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + if (property == null) + { + throw new ArgumentException(type.FullName + " doesn't have a static DefaultInstance property"); + } + if (property.PropertyType != type) + { + throw new ArgumentException(type.FullName + ".DefaultInstance property is of the wrong type"); + } + return (IMessage) property.GetValue(null, null); + } + + /// + /// Returns the default message for the type with the given name. This is just + /// a convenience wrapper around calling Type.GetType and then GetDefaultMessage. + /// If an exception is thrown, the message will be suitable to be displayed to a user. + /// + /// + /// The typeName parameter is null. + /// The type doesn't implement IMessage, or doesn't + /// have a static DefaultMessage property of the same type, or can't be found. + public static IMessage GetDefaultMessage(string typeName) + { + if (typeName == null) + { + throw new ArgumentNullException("typeName", "No type name specified."); + } + Type type = Type.GetType(typeName); + if (type == null) + { + throw new ArgumentException("Unable to load type " + typeName); + } + return GetDefaultMessage(type); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/NameHelpers.cs b/src/ProtocolBuffers/NameHelpers.cs index 59a0e12c..663cfe2d 100644 --- a/src/ProtocolBuffers/NameHelpers.cs +++ b/src/ProtocolBuffers/NameHelpers.cs @@ -1,111 +1,135 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://github.com/jskeet/dotnet-protobufs/ -// Original C++/Java/Python code: -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE 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 System.Globalization; - -namespace Google.ProtocolBuffers { - /// - /// Helpers for converting names to pascal case etc. - /// - public class NameHelpers { - - public static string UnderscoresToPascalCase(string input) { - return UnderscoresToPascalOrCamelCase(input, true); - } - - public static string UnderscoresToCamelCase(string input) { - return UnderscoresToPascalOrCamelCase(input, false); - } - - /// - /// Converts a string to Pascal or Camel case. The first letter is capitalized or - /// lower-cased depending on is true. - /// After the first letter, any punctuation is removed but triggers capitalization - /// of the next letter. Digits are preserved but trigger capitalization of the next - /// letter. - /// All capitalisation is done in the invariant culture. - /// - private static string UnderscoresToPascalOrCamelCase(string input, bool pascal) { - StringBuilder result = new StringBuilder(); - bool capitaliseNext = pascal; - for (int i = 0; i < input.Length; i++) { - char c = input[i]; - if ('a' <= c && c <= 'z') { - if (capitaliseNext) { - result.Append(char.ToUpper(c, CultureInfo.InvariantCulture)); - } else { - result.Append(c); - } - capitaliseNext = false; - } else if ('A' <= c && c <= 'Z') { - if (i == 0 && !pascal) { - // Force first letter to lower-case unless explicitly told to - // capitalize it. - result.Append(char.ToLower(c, CultureInfo.InvariantCulture)); - } else { - // Capital letters after the first are left as-is. - result.Append(c); - } - capitaliseNext = false; - } else if ('0' <= c && c <= '9') { - result.Append(c); - capitaliseNext = true; - } else { - capitaliseNext = true; - } - } - return result.ToString(); - } - - internal static string StripProto(string text) { - if (!StripSuffix(ref text, ".protodevel")) { - StripSuffix(ref text, ".proto"); - } - return text; - } - - /// - /// Attempts to strip a suffix from a string, returning whether - /// or not the suffix was actually present. - /// - public static bool StripSuffix(ref string text, string suffix) { - if (text.EndsWith(suffix)) { - text = text.Substring(0, text.Length - suffix.Length); - return true; - } - return false; - } - } -} +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE 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 System.Globalization; + +namespace Google.ProtocolBuffers +{ + /// + /// Helpers for converting names to pascal case etc. + /// + public class NameHelpers + { + public static string UnderscoresToPascalCase(string input) + { + return UnderscoresToPascalOrCamelCase(input, true); + } + + public static string UnderscoresToCamelCase(string input) + { + return UnderscoresToPascalOrCamelCase(input, false); + } + + /// + /// Converts a string to Pascal or Camel case. The first letter is capitalized or + /// lower-cased depending on is true. + /// After the first letter, any punctuation is removed but triggers capitalization + /// of the next letter. Digits are preserved but trigger capitalization of the next + /// letter. + /// All capitalisation is done in the invariant culture. + /// + private static string UnderscoresToPascalOrCamelCase(string input, bool pascal) + { + StringBuilder result = new StringBuilder(); + bool capitaliseNext = pascal; + for (int i = 0; i < input.Length; i++) + { + char c = input[i]; + if ('a' <= c && c <= 'z') + { + if (capitaliseNext) + { + result.Append(char.ToUpper(c, CultureInfo.InvariantCulture)); + } + else + { + result.Append(c); + } + capitaliseNext = false; + } + else if ('A' <= c && c <= 'Z') + { + if (i == 0 && !pascal) + { + // Force first letter to lower-case unless explicitly told to + // capitalize it. + result.Append(char.ToLower(c, CultureInfo.InvariantCulture)); + } + else + { + // Capital letters after the first are left as-is. + result.Append(c); + } + capitaliseNext = false; + } + else if ('0' <= c && c <= '9') + { + result.Append(c); + capitaliseNext = true; + } + else + { + capitaliseNext = true; + } + } + return result.ToString(); + } + + internal static string StripProto(string text) + { + if (!StripSuffix(ref text, ".protodevel")) + { + StripSuffix(ref text, ".proto"); + } + return text; + } + + /// + /// Attempts to strip a suffix from a string, returning whether + /// or not the suffix was actually present. + /// + public static bool StripSuffix(ref string text, string suffix) + { + if (text.EndsWith(suffix)) + { + text = text.Substring(0, text.Length - suffix.Length); + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/Properties/AssemblyInfo.cs b/src/ProtocolBuffers/Properties/AssemblyInfo.cs index c45391cf..fdae52b8 100644 --- a/src/ProtocolBuffers/Properties/AssemblyInfo.cs +++ b/src/ProtocolBuffers/Properties/AssemblyInfo.cs @@ -37,6 +37,7 @@ using System.Runtime.CompilerServices; // 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")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] @@ -48,9 +49,11 @@ using System.Runtime.CompilerServices; // 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("279b643d-70e8-47ae-9eb1-500d1c48bab6")] // Version information for an assembly consists of the following four values: @@ -63,9 +66,11 @@ using System.Runtime.CompilerServices; // 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")] #if !COMPACT_FRAMEWORK_35 + [assembly: AssemblyFileVersion("2.3.0.277")] #endif -[assembly: CLSCompliant(true)] +[assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/src/ProtocolBuffers/RpcUtil.cs b/src/ProtocolBuffers/RpcUtil.cs index d0614a37..4659d86a 100644 --- a/src/ProtocolBuffers/RpcUtil.cs +++ b/src/ProtocolBuffers/RpcUtil.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,42 +31,49 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE 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 { - /// - /// Grab-bag of utility functions useful when dealing with RPCs. - /// - public static class RpcUtil { - +namespace Google.ProtocolBuffers +{ /// - /// Converts an Action[IMessage] to an Action[T]. + /// Grab-bag of utility functions useful when dealing with RPCs. /// - public static Action SpecializeCallback(Action action) - where T : IMessage { - return message => action(message); - } + public static class RpcUtil + { + /// + /// Converts an Action[IMessage] to an Action[T]. + /// + public static Action SpecializeCallback(Action action) + where T : IMessage + { + return message => action(message); + } - /// - /// Converts an Action[T] to an Action[IMessage]. - /// The generalized action will accept any message object which has - /// the same descriptor, and will convert it to the correct class - /// before calling the original action. However, if the generalized - /// callback is given a message with a different descriptor, an - /// exception will be thrown. - /// - public static Action GeneralizeCallback(Action action, TMessage defaultInstance) - where TMessage : class, IMessage - where TBuilder : IBuilder { - return message => { - TMessage castMessage = message as TMessage; - if (castMessage == null) { - castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build(); + /// + /// Converts an Action[T] to an Action[IMessage]. + /// The generalized action will accept any message object which has + /// the same descriptor, and will convert it to the correct class + /// before calling the original action. However, if the generalized + /// callback is given a message with a different descriptor, an + /// exception will be thrown. + /// + public static Action GeneralizeCallback(Action action, + TMessage defaultInstance) + where TMessage : class, IMessage + where TBuilder : IBuilder + { + return message => + { + TMessage castMessage = message as TMessage; + if (castMessage == null) + { + castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build(); + } + action(castMessage); + }; } - action(castMessage); - }; } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/SilverlightCompatibility.cs b/src/ProtocolBuffers/SilverlightCompatibility.cs index 5f2e12b1..f9ff5c3e 100644 --- a/src/ProtocolBuffers/SilverlightCompatibility.cs +++ b/src/ProtocolBuffers/SilverlightCompatibility.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.Text.RegularExpressions; @@ -41,12 +43,10 @@ namespace Google.ProtocolBuffers /// internal static class SilverlightCompatibility { - #if SILVERLIGHT2 internal const RegexOptions CompiledRegexWhereAvailable = RegexOptions.None; #else internal const RegexOptions CompiledRegexWhereAvailable = RegexOptions.Compiled; #endif - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/SortedList.cs b/src/ProtocolBuffers/SortedList.cs index da186ee5..54bd8b20 100644 --- a/src/ProtocolBuffers/SortedList.cs +++ b/src/ProtocolBuffers/SortedList.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 #if SILVERLIGHT2 @@ -110,14 +112,8 @@ namespace Google.ProtocolBuffers public TValue this[TKey key] { - get - { - return wrapped[key]; - } - set - { - wrapped[key] = value; - } + get { return wrapped[key]; } + set { wrapped[key] = value; } } public void Add(KeyValuePair item) @@ -169,4 +165,5 @@ namespace Google.ProtocolBuffers } } } + #endif \ No newline at end of file diff --git a/src/ProtocolBuffers/TextFormat.cs b/src/ProtocolBuffers/TextFormat.cs index cf352273..5f6f547c 100644 --- a/src/ProtocolBuffers/TextFormat.cs +++ b/src/ProtocolBuffers/TextFormat.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; @@ -40,646 +42,818 @@ using System.Text; using Google.ProtocolBuffers.Descriptors; using System.Collections; -namespace Google.ProtocolBuffers { - /// - /// Provides ASCII text formatting support for messages. - /// TODO(jonskeet): Support for alternative line endings. - /// (Easy to print, via TextGenerator. Not sure about parsing.) - /// - public static class TextFormat { - - /// - /// Outputs a textual representation of the Protocol Message supplied into - /// the parameter output. - /// - public static void Print(IMessage message, TextWriter output) { - TextGenerator generator = new TextGenerator(output, "\n"); - Print(message, generator); - } - +namespace Google.ProtocolBuffers +{ /// - /// Outputs a textual representation of to . + /// Provides ASCII text formatting support for messages. + /// TODO(jonskeet): Support for alternative line endings. + /// (Easy to print, via TextGenerator. Not sure about parsing.) /// - public static void Print(UnknownFieldSet fields, TextWriter output) { - TextGenerator generator = new TextGenerator(output, "\n"); - PrintUnknownFields(fields, generator); - } - - public static string PrintToString(IMessage message) { - StringWriter text = new StringWriter(); - Print(message, text); - return text.ToString(); - } - - public static string PrintToString(UnknownFieldSet fields) { - StringWriter text = new StringWriter(); - Print(fields, text); - return text.ToString(); - } - - private static void Print(IMessage message, TextGenerator generator) { - foreach (KeyValuePair entry in message.AllFields) { - PrintField(entry.Key, entry.Value, generator); - } - PrintUnknownFields(message.UnknownFields, generator); - } - - internal static void PrintField(FieldDescriptor field, object value, TextGenerator generator) { - if (field.IsRepeated) { - // Repeated field. Print each element. - foreach (object element in (IEnumerable) value) { - PrintSingleField(field, element, generator); + public static class TextFormat + { + /// + /// Outputs a textual representation of the Protocol Message supplied into + /// the parameter output. + /// + public static void Print(IMessage message, TextWriter output) + { + TextGenerator generator = new TextGenerator(output, "\n"); + Print(message, generator); } - } else { - PrintSingleField(field, value, generator); - } - } - private static void PrintSingleField(FieldDescriptor field, Object value, TextGenerator generator) { - if (field.IsExtension) { - generator.Print("["); - // We special-case MessageSet elements for compatibility with proto1. - if (field.ContainingType.Options.MessageSetWireFormat - && field.FieldType == FieldType.Message - && field.IsOptional - // object equality (TODO(jonskeet): Work out what this comment means!) - && field.ExtensionScope == field.MessageType) { - generator.Print(field.MessageType.FullName); - } else { - generator.Print(field.FullName); - } - generator.Print("]"); - } else { - if (field.FieldType == FieldType.Group) { - // Groups must be serialized with their original capitalization. - generator.Print(field.MessageType.Name); - } else { - generator.Print(field.Name); + /// + /// Outputs a textual representation of to . + /// + public static void Print(UnknownFieldSet fields, TextWriter output) + { + TextGenerator generator = new TextGenerator(output, "\n"); + PrintUnknownFields(fields, generator); } - } - - if (field.MappedType == MappedType.Message) { - generator.Print(" {\n"); - generator.Indent(); - } else { - generator.Print(": "); - } - - PrintFieldValue(field, value, generator); - - if (field.MappedType == MappedType.Message) { - generator.Outdent(); - generator.Print("}"); - } - generator.Print("\n"); - } - private static void PrintFieldValue(FieldDescriptor field, object value, TextGenerator generator) { - switch (field.FieldType) { - case FieldType.Int32: - case FieldType.Int64: - case FieldType.SInt32: - case FieldType.SInt64: - case FieldType.SFixed32: - case FieldType.SFixed64: - case FieldType.Float: - case FieldType.Double: - case FieldType.UInt32: - case FieldType.UInt64: - case FieldType.Fixed32: - case FieldType.Fixed64: - // The simple Object.ToString converts using the current culture. - // We want to always use the invariant culture so it's predictable. - generator.Print(((IConvertible) value).ToString(CultureInfo.InvariantCulture)); - break; - case FieldType.Bool: - // Explicitly use the Java true/false - generator.Print((bool) value ? "true" : "false"); - break; - - case FieldType.String: - generator.Print("\""); - generator.Print(EscapeText((string) value)); - generator.Print("\""); - break; - - case FieldType.Bytes: { - generator.Print("\""); - generator.Print(EscapeBytes((ByteString) value)); - generator.Print("\""); - break; + public static string PrintToString(IMessage message) + { + StringWriter text = new StringWriter(); + Print(message, text); + return text.ToString(); } - case FieldType.Enum: { - if (value is IEnumLite && !(value is EnumValueDescriptor)) { - throw new NotSupportedException("Lite enumerations are not supported."); - } - generator.Print(((EnumValueDescriptor)value).Name); - break; + public static string PrintToString(UnknownFieldSet fields) + { + StringWriter text = new StringWriter(); + Print(fields, text); + return text.ToString(); } - case FieldType.Message: - case FieldType.Group: - if (value is IMessageLite && !(value is IMessage)) { - throw new NotSupportedException("Lite messages are not supported."); - } - Print((IMessage)value, generator); - break; - } - } - - private static void PrintUnknownFields(UnknownFieldSet unknownFields, TextGenerator generator) { - foreach (KeyValuePair entry in unknownFields.FieldDictionary) { - String prefix = entry.Key.ToString() + ": "; - UnknownField field = entry.Value; - - foreach (ulong value in field.VarintList) { - generator.Print(prefix); - generator.Print(value.ToString()); - generator.Print("\n"); - } - foreach (uint value in field.Fixed32List) { - generator.Print(prefix); - generator.Print(string.Format("0x{0:x8}", value)); - generator.Print("\n"); - } - foreach (ulong value in field.Fixed64List) { - generator.Print(prefix); - generator.Print(string.Format("0x{0:x16}", value)); - generator.Print("\n"); - } - foreach (ByteString value in field.LengthDelimitedList) { - generator.Print(entry.Key.ToString()); - generator.Print(": \""); - generator.Print(EscapeBytes(value)); - generator.Print("\"\n"); - } - foreach (UnknownFieldSet value in field.GroupList) { - generator.Print(entry.Key.ToString()); - generator.Print(" {\n"); - generator.Indent(); - PrintUnknownFields(value, generator); - generator.Outdent(); - generator.Print("}\n"); + private static void Print(IMessage message, TextGenerator generator) + { + foreach (KeyValuePair entry in message.AllFields) + { + PrintField(entry.Key, entry.Value, generator); + } + PrintUnknownFields(message.UnknownFields, generator); } - } - } - - [CLSCompliant(false)] - public static ulong ParseUInt64(string text) { - return (ulong) ParseInteger(text, false, true); - } - public static long ParseInt64(string text) { - return ParseInteger(text, true, true); - } - - [CLSCompliant(false)] - public static uint ParseUInt32(string text) { - return (uint) ParseInteger(text, false, false); - } - - public static int ParseInt32(string text) { - return (int) ParseInteger(text, true, false); - } - - public static float ParseFloat(string text) { - switch (text) { - case "-inf": - case "-infinity": - case "-inff": - case "-infinityf": - return float.NegativeInfinity; - case "inf": - case "infinity": - case "inff": - case "infinityf": - return float.PositiveInfinity; - case "nan": - case "nanf": - return float.NaN; - default: - return float.Parse(text, CultureInfo.InvariantCulture); - } - } - - public static double ParseDouble(string text) { - switch (text) { - case "-inf": - case "-infinity": - return double.NegativeInfinity; - case "inf": - case "infinity": - return double.PositiveInfinity; - case "nan": - return double.NaN; - default: - return double.Parse(text, CultureInfo.InvariantCulture); - } - } - - /// - /// Parses an integer in hex (leading 0x), decimal (no prefix) or octal (leading 0). - /// Only a negative sign is permitted, and it must come before the radix indicator. - /// - private static long ParseInteger(string text, bool isSigned, bool isLong) { - string original = text; - bool negative = false; - if (text.StartsWith("-")) { - if (!isSigned) { - throw new FormatException("Number must be positive: " + original); - } - negative = true; - text = text.Substring(1); - } - - int radix = 10; - if (text.StartsWith("0x")) { - radix = 16; - text = text.Substring(2); - } else if (text.StartsWith("0")) { - radix = 8; - } - - ulong result; - try { - // Workaround for https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278448 - // We should be able to use Convert.ToUInt64 for all cases. - result = radix == 10 ? ulong.Parse(text) : Convert.ToUInt64(text, radix); - } catch (OverflowException) { - // Convert OverflowException to FormatException so there's a single exception type this method can throw. - string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32, isSigned ? "" : "un"); - throw new FormatException("Number out of range for " + numberDescription + ": " + original); - } - - if (negative) { - ulong max = isLong ? 0x8000000000000000UL : 0x80000000L; - if (result > max) { - string numberDescription = string.Format("{0}-bit signed integer", isLong ? 64 : 32); - throw new FormatException("Number out of range for " + numberDescription + ": " + original); - } - return -((long) result); - } else { - ulong max = isSigned - ? (isLong ? (ulong) long.MaxValue : int.MaxValue) - : (isLong ? ulong.MaxValue : uint.MaxValue); - if (result > max) { - string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32, isSigned ? "" : "un"); - throw new FormatException("Number out of range for " + numberDescription + ": " + original); + internal static void PrintField(FieldDescriptor field, object value, TextGenerator generator) + { + if (field.IsRepeated) + { + // Repeated field. Print each element. + foreach (object element in (IEnumerable) value) + { + PrintSingleField(field, element, generator); + } + } + else + { + PrintSingleField(field, value, generator); + } } - return (long) result; - } - } - /// - /// Tests a character to see if it's an octal digit. - /// - private static bool IsOctal(char c) { - return '0' <= c && c <= '7'; - } + private static void PrintSingleField(FieldDescriptor field, Object value, TextGenerator generator) + { + if (field.IsExtension) + { + generator.Print("["); + // We special-case MessageSet elements for compatibility with proto1. + if (field.ContainingType.Options.MessageSetWireFormat + && field.FieldType == FieldType.Message + && field.IsOptional + // object equality (TODO(jonskeet): Work out what this comment means!) + && field.ExtensionScope == field.MessageType) + { + generator.Print(field.MessageType.FullName); + } + else + { + generator.Print(field.FullName); + } + generator.Print("]"); + } + else + { + if (field.FieldType == FieldType.Group) + { + // Groups must be serialized with their original capitalization. + generator.Print(field.MessageType.Name); + } + else + { + generator.Print(field.Name); + } + } - /// - /// Tests a character to see if it's a hex digit. - /// - private static bool IsHex(char c) { - return ('0' <= c && c <= '9') || - ('a' <= c && c <= 'f') || - ('A' <= c && c <= 'F'); - } + if (field.MappedType == MappedType.Message) + { + generator.Print(" {\n"); + generator.Indent(); + } + else + { + generator.Print(": "); + } - /// - /// Interprets a character as a digit (in any base up to 36) and returns the - /// numeric value. - /// - private static int ParseDigit(char c) { - if ('0' <= c && c <= '9') { - return c - '0'; - } else if ('a' <= c && c <= 'z') { - return c - 'a' + 10; - } else { - return c - 'A' + 10; - } - } + PrintFieldValue(field, value, generator); - /// - /// Unescapes a text string as escaped using . - /// Two-digit hex escapes (starting with "\x" are also recognised. - /// - public static string UnescapeText(string input) { - return UnescapeBytes(input).ToStringUtf8(); - } + if (field.MappedType == MappedType.Message) + { + generator.Outdent(); + generator.Print("}"); + } + generator.Print("\n"); + } - /// - /// Like but escapes a text string. - /// The string is first encoded as UTF-8, then each byte escaped individually. - /// The returned value is guaranteed to be entirely ASCII. - /// - public static string EscapeText(string input) { - return EscapeBytes(ByteString.CopyFromUtf8(input)); - } + private static void PrintFieldValue(FieldDescriptor field, object value, TextGenerator generator) + { + switch (field.FieldType) + { + case FieldType.Int32: + case FieldType.Int64: + case FieldType.SInt32: + case FieldType.SInt64: + case FieldType.SFixed32: + case FieldType.SFixed64: + case FieldType.Float: + case FieldType.Double: + case FieldType.UInt32: + case FieldType.UInt64: + case FieldType.Fixed32: + case FieldType.Fixed64: + // The simple Object.ToString converts using the current culture. + // We want to always use the invariant culture so it's predictable. + generator.Print(((IConvertible) value).ToString(CultureInfo.InvariantCulture)); + break; + case FieldType.Bool: + // Explicitly use the Java true/false + generator.Print((bool) value ? "true" : "false"); + break; + + case FieldType.String: + generator.Print("\""); + generator.Print(EscapeText((string) value)); + generator.Print("\""); + break; + + case FieldType.Bytes: + { + generator.Print("\""); + generator.Print(EscapeBytes((ByteString) value)); + generator.Print("\""); + break; + } + + case FieldType.Enum: + { + if (value is IEnumLite && !(value is EnumValueDescriptor)) + { + throw new NotSupportedException("Lite enumerations are not supported."); + } + generator.Print(((EnumValueDescriptor) value).Name); + break; + } + + case FieldType.Message: + case FieldType.Group: + if (value is IMessageLite && !(value is IMessage)) + { + throw new NotSupportedException("Lite messages are not supported."); + } + Print((IMessage) value, generator); + break; + } + } - /// - /// Escapes bytes in the format used in protocol buffer text format, which - /// is the same as the format used for C string literals. All bytes - /// that are not printable 7-bit ASCII characters are escaped, as well as - /// backslash, single-quote, and double-quote characters. Characters for - /// which no defined short-hand escape sequence is defined will be escaped - /// using 3-digit octal sequences. - /// The returned value is guaranteed to be entirely ASCII. - /// - public static String EscapeBytes(ByteString input) { - StringBuilder builder = new StringBuilder(input.Length); - foreach (byte b in input) { - switch (b) { - // C# does not use \a or \v - case 0x07: builder.Append("\\a" ); break; - case (byte)'\b': builder.Append("\\b" ); break; - case (byte)'\f': builder.Append("\\f" ); break; - case (byte)'\n': builder.Append("\\n" ); break; - case (byte)'\r': builder.Append("\\r" ); break; - case (byte)'\t': builder.Append("\\t" ); break; - case 0x0b: builder.Append("\\v" ); break; - case (byte)'\\': builder.Append("\\\\"); break; - case (byte)'\'': builder.Append("\\\'"); break; - case (byte)'"' : builder.Append("\\\""); break; - default: - if (b >= 0x20 && b < 128) { - builder.Append((char) b); - } else { - builder.Append('\\'); - builder.Append((char) ('0' + ((b >> 6) & 3))); - builder.Append((char) ('0' + ((b >> 3) & 7))); - builder.Append((char) ('0' + (b & 7))); + private static void PrintUnknownFields(UnknownFieldSet unknownFields, TextGenerator generator) + { + foreach (KeyValuePair entry in unknownFields.FieldDictionary) + { + String prefix = entry.Key.ToString() + ": "; + UnknownField field = entry.Value; + + foreach (ulong value in field.VarintList) + { + generator.Print(prefix); + generator.Print(value.ToString()); + generator.Print("\n"); + } + foreach (uint value in field.Fixed32List) + { + generator.Print(prefix); + generator.Print(string.Format("0x{0:x8}", value)); + generator.Print("\n"); + } + foreach (ulong value in field.Fixed64List) + { + generator.Print(prefix); + generator.Print(string.Format("0x{0:x16}", value)); + generator.Print("\n"); + } + foreach (ByteString value in field.LengthDelimitedList) + { + generator.Print(entry.Key.ToString()); + generator.Print(": \""); + generator.Print(EscapeBytes(value)); + generator.Print("\"\n"); + } + foreach (UnknownFieldSet value in field.GroupList) + { + generator.Print(entry.Key.ToString()); + generator.Print(" {\n"); + generator.Indent(); + PrintUnknownFields(value, generator); + generator.Outdent(); + generator.Print("}\n"); + } } - break; } - } - return builder.ToString(); - } - /// - /// Performs string unescaping from C style (octal, hex, form feeds, tab etc) into a byte string. - /// - public static ByteString UnescapeBytes(string input) { - byte[] result = new byte[input.Length]; - int pos = 0; - for (int i = 0; i < input.Length; i++) { - char c = input[i]; - if (c > 127 || c < 32) { - throw new FormatException("Escaped string must only contain ASCII"); + [CLSCompliant(false)] + public static ulong ParseUInt64(string text) + { + return (ulong) ParseInteger(text, false, true); } - if (c != '\\') { - result[pos++] = (byte) c; - continue; + + public static long ParseInt64(string text) + { + return ParseInteger(text, true, true); } - if (i + 1 >= input.Length) { - throw new FormatException("Invalid escape sequence: '\\' at end of string."); + + [CLSCompliant(false)] + public static uint ParseUInt32(string text) + { + return (uint) ParseInteger(text, false, false); } - i++; - c = input[i]; - if (c >= '0' && c <= '7') { - // Octal escape. - int code = ParseDigit(c); - if (i + 1 < input.Length && IsOctal(input[i+1])) { - i++; - code = code * 8 + ParseDigit(input[i]); - } - if (i + 1 < input.Length && IsOctal(input[i+1])) { - i++; - code = code * 8 + ParseDigit(input[i]); - } - result[pos++] = (byte) code; - } else { - switch (c) { - case 'a': result[pos++] = 0x07; break; - case 'b': result[pos++] = (byte) '\b'; break; - case 'f': result[pos++] = (byte) '\f'; break; - case 'n': result[pos++] = (byte) '\n'; break; - case 'r': result[pos++] = (byte) '\r'; break; - case 't': result[pos++] = (byte) '\t'; break; - case 'v': result[pos++] = 0x0b; break; - case '\\': result[pos++] = (byte) '\\'; break; - case '\'': result[pos++] = (byte) '\''; break; - case '"': result[pos++] = (byte) '\"'; break; - - case 'x': - // hex escape - int code; - if (i + 1 < input.Length && IsHex(input[i+1])) { - i++; - code = ParseDigit(input[i]); - } else { - throw new FormatException("Invalid escape sequence: '\\x' with no digits"); - } - if (i + 1 < input.Length && IsHex(input[i+1])) { - ++i; - code = code * 16 + ParseDigit(input[i]); - } - result[pos++] = (byte)code; - break; - - default: - throw new FormatException("Invalid escape sequence: '\\" + c + "'"); - } + public static int ParseInt32(string text) + { + return (int) ParseInteger(text, true, false); } - } - return ByteString.CopyFrom(result, 0, pos); - } + public static float ParseFloat(string text) + { + switch (text) + { + case "-inf": + case "-infinity": + case "-inff": + case "-infinityf": + return float.NegativeInfinity; + case "inf": + case "infinity": + case "inff": + case "infinityf": + return float.PositiveInfinity; + case "nan": + case "nanf": + return float.NaN; + default: + return float.Parse(text, CultureInfo.InvariantCulture); + } + } - public static void Merge(string text, IBuilder builder) { - Merge(text, ExtensionRegistry.Empty, builder); - } + public static double ParseDouble(string text) + { + switch (text) + { + case "-inf": + case "-infinity": + return double.NegativeInfinity; + case "inf": + case "infinity": + return double.PositiveInfinity; + case "nan": + return double.NaN; + default: + return double.Parse(text, CultureInfo.InvariantCulture); + } + } - public static void Merge(TextReader reader, IBuilder builder) { - Merge(reader, ExtensionRegistry.Empty, builder); - } + /// + /// Parses an integer in hex (leading 0x), decimal (no prefix) or octal (leading 0). + /// Only a negative sign is permitted, and it must come before the radix indicator. + /// + private static long ParseInteger(string text, bool isSigned, bool isLong) + { + string original = text; + bool negative = false; + if (text.StartsWith("-")) + { + if (!isSigned) + { + throw new FormatException("Number must be positive: " + original); + } + negative = true; + text = text.Substring(1); + } - public static void Merge(TextReader reader, ExtensionRegistry registry, IBuilder builder) { - Merge(reader.ReadToEnd(), registry, builder); - } + int radix = 10; + if (text.StartsWith("0x")) + { + radix = 16; + text = text.Substring(2); + } + else if (text.StartsWith("0")) + { + radix = 8; + } - public static void Merge(string text, ExtensionRegistry registry, IBuilder builder) { - TextTokenizer tokenizer = new TextTokenizer(text); + ulong result; + try + { + // Workaround for https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278448 + // We should be able to use Convert.ToUInt64 for all cases. + result = radix == 10 ? ulong.Parse(text) : Convert.ToUInt64(text, radix); + } + catch (OverflowException) + { + // Convert OverflowException to FormatException so there's a single exception type this method can throw. + string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32, + isSigned ? "" : "un"); + throw new FormatException("Number out of range for " + numberDescription + ": " + original); + } - while (!tokenizer.AtEnd) { - MergeField(tokenizer, registry, builder); - } - } + if (negative) + { + ulong max = isLong ? 0x8000000000000000UL : 0x80000000L; + if (result > max) + { + string numberDescription = string.Format("{0}-bit signed integer", isLong ? 64 : 32); + throw new FormatException("Number out of range for " + numberDescription + ": " + original); + } + return -((long) result); + } + else + { + ulong max = isSigned + ? (isLong ? (ulong) long.MaxValue : int.MaxValue) + : (isLong ? ulong.MaxValue : uint.MaxValue); + if (result > max) + { + string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32, + isSigned ? "" : "un"); + throw new FormatException("Number out of range for " + numberDescription + ": " + original); + } + return (long) result; + } + } - /// - /// Parses a single field from the specified tokenizer and merges it into - /// the builder. - /// - private static void MergeField(TextTokenizer tokenizer, ExtensionRegistry extensionRegistry, - IBuilder builder) { - - FieldDescriptor field; - MessageDescriptor type = builder.DescriptorForType; - ExtensionInfo extension = null; - - if (tokenizer.TryConsume("[")) { - // An extension. - StringBuilder name = new StringBuilder(tokenizer.ConsumeIdentifier()); - while (tokenizer.TryConsume(".")) { - name.Append("."); - name.Append(tokenizer.ConsumeIdentifier()); + /// + /// Tests a character to see if it's an octal digit. + /// + private static bool IsOctal(char c) + { + return '0' <= c && c <= '7'; } - extension = extensionRegistry[name.ToString()]; + /// + /// Tests a character to see if it's a hex digit. + /// + private static bool IsHex(char c) + { + return ('0' <= c && c <= '9') || + ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F'); + } - if (extension == null) { - throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" not found in the ExtensionRegistry."); - } else if (extension.Descriptor.ContainingType != type) { - throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" does not extend message type \"" + - type.FullName + "\"."); + /// + /// Interprets a character as a digit (in any base up to 36) and returns the + /// numeric value. + /// + private static int ParseDigit(char c) + { + if ('0' <= c && c <= '9') + { + return c - '0'; + } + else if ('a' <= c && c <= 'z') + { + return c - 'a' + 10; + } + else + { + return c - 'A' + 10; + } } - tokenizer.Consume("]"); - - field = extension.Descriptor; - } else { - String name = tokenizer.ConsumeIdentifier(); - field = type.FindDescriptor(name); - - // Group names are expected to be capitalized as they appear in the - // .proto file, which actually matches their type names, not their field - // names. - if (field == null) { - // Explicitly specify the invariant culture so that this code does not break when - // executing in Turkey. - String lowerName = name.ToLower(CultureInfo.InvariantCulture); - field = type.FindDescriptor(lowerName); - // If the case-insensitive match worked but the field is NOT a group, - // TODO(jonskeet): What? Java comment ends here! - if (field != null && field.FieldType != FieldType.Group) { - field = null; - } + /// + /// Unescapes a text string as escaped using . + /// Two-digit hex escapes (starting with "\x" are also recognised. + /// + public static string UnescapeText(string input) + { + return UnescapeBytes(input).ToStringUtf8(); } - // Again, special-case group names as described above. - if (field != null && field.FieldType == FieldType.Group && field.MessageType.Name != name) { - field = null; + + /// + /// Like but escapes a text string. + /// The string is first encoded as UTF-8, then each byte escaped individually. + /// The returned value is guaranteed to be entirely ASCII. + /// + public static string EscapeText(string input) + { + return EscapeBytes(ByteString.CopyFromUtf8(input)); } - if (field == null) { - throw tokenizer.CreateFormatExceptionPreviousToken( - "Message type \"" + type.FullName + "\" has no field named \"" + name + "\"."); + /// + /// Escapes bytes in the format used in protocol buffer text format, which + /// is the same as the format used for C string literals. All bytes + /// that are not printable 7-bit ASCII characters are escaped, as well as + /// backslash, single-quote, and double-quote characters. Characters for + /// which no defined short-hand escape sequence is defined will be escaped + /// using 3-digit octal sequences. + /// The returned value is guaranteed to be entirely ASCII. + /// + public static String EscapeBytes(ByteString input) + { + StringBuilder builder = new StringBuilder(input.Length); + foreach (byte b in input) + { + switch (b) + { + // C# does not use \a or \v + case 0x07: + builder.Append("\\a"); + break; + case (byte) '\b': + builder.Append("\\b"); + break; + case (byte) '\f': + builder.Append("\\f"); + break; + case (byte) '\n': + builder.Append("\\n"); + break; + case (byte) '\r': + builder.Append("\\r"); + break; + case (byte) '\t': + builder.Append("\\t"); + break; + case 0x0b: + builder.Append("\\v"); + break; + case (byte) '\\': + builder.Append("\\\\"); + break; + case (byte) '\'': + builder.Append("\\\'"); + break; + case (byte) '"': + builder.Append("\\\""); + break; + default: + if (b >= 0x20 && b < 128) + { + builder.Append((char) b); + } + else + { + builder.Append('\\'); + builder.Append((char) ('0' + ((b >> 6) & 3))); + builder.Append((char) ('0' + ((b >> 3) & 7))); + builder.Append((char) ('0' + (b & 7))); + } + break; + } + } + return builder.ToString(); } - } - object value = null; + /// + /// Performs string unescaping from C style (octal, hex, form feeds, tab etc) into a byte string. + /// + public static ByteString UnescapeBytes(string input) + { + byte[] result = new byte[input.Length]; + int pos = 0; + for (int i = 0; i < input.Length; i++) + { + char c = input[i]; + if (c > 127 || c < 32) + { + throw new FormatException("Escaped string must only contain ASCII"); + } + if (c != '\\') + { + result[pos++] = (byte) c; + continue; + } + if (i + 1 >= input.Length) + { + throw new FormatException("Invalid escape sequence: '\\' at end of string."); + } - if (field.MappedType == MappedType.Message) { - tokenizer.TryConsume(":"); // optional + i++; + c = input[i]; + if (c >= '0' && c <= '7') + { + // Octal escape. + int code = ParseDigit(c); + if (i + 1 < input.Length && IsOctal(input[i + 1])) + { + i++; + code = code*8 + ParseDigit(input[i]); + } + if (i + 1 < input.Length && IsOctal(input[i + 1])) + { + i++; + code = code*8 + ParseDigit(input[i]); + } + result[pos++] = (byte) code; + } + else + { + switch (c) + { + case 'a': + result[pos++] = 0x07; + break; + case 'b': + result[pos++] = (byte) '\b'; + break; + case 'f': + result[pos++] = (byte) '\f'; + break; + case 'n': + result[pos++] = (byte) '\n'; + break; + case 'r': + result[pos++] = (byte) '\r'; + break; + case 't': + result[pos++] = (byte) '\t'; + break; + case 'v': + result[pos++] = 0x0b; + break; + case '\\': + result[pos++] = (byte) '\\'; + break; + case '\'': + result[pos++] = (byte) '\''; + break; + case '"': + result[pos++] = (byte) '\"'; + break; + + case 'x': + // hex escape + int code; + if (i + 1 < input.Length && IsHex(input[i + 1])) + { + i++; + code = ParseDigit(input[i]); + } + else + { + throw new FormatException("Invalid escape sequence: '\\x' with no digits"); + } + if (i + 1 < input.Length && IsHex(input[i + 1])) + { + ++i; + code = code*16 + ParseDigit(input[i]); + } + result[pos++] = (byte) code; + break; + + default: + throw new FormatException("Invalid escape sequence: '\\" + c + "'"); + } + } + } - String endToken; - if (tokenizer.TryConsume("<")) { - endToken = ">"; - } else { - tokenizer.Consume("{"); - endToken = "}"; + return ByteString.CopyFrom(result, 0, pos); } - IBuilder subBuilder; - if (extension == null) { - subBuilder = builder.CreateBuilderForField(field); - } else { - subBuilder = extension.DefaultInstance.WeakCreateBuilderForType() as IBuilder; - if (subBuilder == null) - throw new NotSupportedException("Lite messages are not supported."); + public static void Merge(string text, IBuilder builder) + { + Merge(text, ExtensionRegistry.Empty, builder); } - while (!tokenizer.TryConsume(endToken)) { - if (tokenizer.AtEnd) { - throw tokenizer.CreateFormatException("Expected \"" + endToken + "\"."); - } - MergeField(tokenizer, extensionRegistry, subBuilder); + public static void Merge(TextReader reader, IBuilder builder) + { + Merge(reader, ExtensionRegistry.Empty, builder); } - value = subBuilder.WeakBuild(); - - } else { - tokenizer.Consume(":"); - - switch (field.FieldType) { - case FieldType.Int32: - case FieldType.SInt32: - case FieldType.SFixed32: - value = tokenizer.ConsumeInt32(); - break; - - case FieldType.Int64: - case FieldType.SInt64: - case FieldType.SFixed64: - value = tokenizer.ConsumeInt64(); - break; - - case FieldType.UInt32: - case FieldType.Fixed32: - value = tokenizer.ConsumeUInt32(); - break; - - case FieldType.UInt64: - case FieldType.Fixed64: - value = tokenizer.ConsumeUInt64(); - break; - - case FieldType.Float: - value = tokenizer.ConsumeFloat(); - break; - - case FieldType.Double: - value = tokenizer.ConsumeDouble(); - break; - - case FieldType.Bool: - value = tokenizer.ConsumeBoolean(); - break; - - case FieldType.String: - value = tokenizer.ConsumeString(); - break; - - case FieldType.Bytes: - value = tokenizer.ConsumeByteString(); - break; - - case FieldType.Enum: { - EnumDescriptor enumType = field.EnumType; - - if (tokenizer.LookingAtInteger()) { - int number = tokenizer.ConsumeInt32(); - value = enumType.FindValueByNumber(number); - if (value == null) { - throw tokenizer.CreateFormatExceptionPreviousToken( - "Enum type \"" + enumType.FullName + - "\" has no value with number " + number + "."); - } - } else { - String id = tokenizer.ConsumeIdentifier(); - value = enumType.FindValueByName(id); - if (value == null) { - throw tokenizer.CreateFormatExceptionPreviousToken( - "Enum type \"" + enumType.FullName + - "\" has no value named \"" + id + "\"."); - } - } + public static void Merge(TextReader reader, ExtensionRegistry registry, IBuilder builder) + { + Merge(reader.ReadToEnd(), registry, builder); + } - break; - } + public static void Merge(string text, ExtensionRegistry registry, IBuilder builder) + { + TextTokenizer tokenizer = new TextTokenizer(text); - case FieldType.Message: - case FieldType.Group: - throw new InvalidOperationException("Can't get here."); + while (!tokenizer.AtEnd) + { + MergeField(tokenizer, registry, builder); + } } - } - if (field.IsRepeated) { - builder.WeakAddRepeatedField(field, value); - } else { - builder.SetField(field, value); - } + /// + /// Parses a single field from the specified tokenizer and merges it into + /// the builder. + /// + private static void MergeField(TextTokenizer tokenizer, ExtensionRegistry extensionRegistry, + IBuilder builder) + { + FieldDescriptor field; + MessageDescriptor type = builder.DescriptorForType; + ExtensionInfo extension = null; + + if (tokenizer.TryConsume("[")) + { + // An extension. + StringBuilder name = new StringBuilder(tokenizer.ConsumeIdentifier()); + while (tokenizer.TryConsume(".")) + { + name.Append("."); + name.Append(tokenizer.ConsumeIdentifier()); + } + + extension = extensionRegistry[name.ToString()]; + + if (extension == null) + { + throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + + "\" not found in the ExtensionRegistry."); + } + else if (extension.Descriptor.ContainingType != type) + { + throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + + "\" does not extend message type \"" + + type.FullName + "\"."); + } + + tokenizer.Consume("]"); + + field = extension.Descriptor; + } + else + { + String name = tokenizer.ConsumeIdentifier(); + field = type.FindDescriptor(name); + + // Group names are expected to be capitalized as they appear in the + // .proto file, which actually matches their type names, not their field + // names. + if (field == null) + { + // Explicitly specify the invariant culture so that this code does not break when + // executing in Turkey. + String lowerName = name.ToLower(CultureInfo.InvariantCulture); + field = type.FindDescriptor(lowerName); + // If the case-insensitive match worked but the field is NOT a group, + // TODO(jonskeet): What? Java comment ends here! + if (field != null && field.FieldType != FieldType.Group) + { + field = null; + } + } + // Again, special-case group names as described above. + if (field != null && field.FieldType == FieldType.Group && field.MessageType.Name != name) + { + field = null; + } + + if (field == null) + { + throw tokenizer.CreateFormatExceptionPreviousToken( + "Message type \"" + type.FullName + "\" has no field named \"" + name + "\"."); + } + } + + object value = null; + + if (field.MappedType == MappedType.Message) + { + tokenizer.TryConsume(":"); // optional + + String endToken; + if (tokenizer.TryConsume("<")) + { + endToken = ">"; + } + else + { + tokenizer.Consume("{"); + endToken = "}"; + } + + IBuilder subBuilder; + if (extension == null) + { + subBuilder = builder.CreateBuilderForField(field); + } + else + { + subBuilder = extension.DefaultInstance.WeakCreateBuilderForType() as IBuilder; + if (subBuilder == null) + throw new NotSupportedException("Lite messages are not supported."); + } + + while (!tokenizer.TryConsume(endToken)) + { + if (tokenizer.AtEnd) + { + throw tokenizer.CreateFormatException("Expected \"" + endToken + "\"."); + } + MergeField(tokenizer, extensionRegistry, subBuilder); + } + + value = subBuilder.WeakBuild(); + } + else + { + tokenizer.Consume(":"); + + switch (field.FieldType) + { + case FieldType.Int32: + case FieldType.SInt32: + case FieldType.SFixed32: + value = tokenizer.ConsumeInt32(); + break; + + case FieldType.Int64: + case FieldType.SInt64: + case FieldType.SFixed64: + value = tokenizer.ConsumeInt64(); + break; + + case FieldType.UInt32: + case FieldType.Fixed32: + value = tokenizer.ConsumeUInt32(); + break; + + case FieldType.UInt64: + case FieldType.Fixed64: + value = tokenizer.ConsumeUInt64(); + break; + + case FieldType.Float: + value = tokenizer.ConsumeFloat(); + break; + + case FieldType.Double: + value = tokenizer.ConsumeDouble(); + break; + + case FieldType.Bool: + value = tokenizer.ConsumeBoolean(); + break; + + case FieldType.String: + value = tokenizer.ConsumeString(); + break; + + case FieldType.Bytes: + value = tokenizer.ConsumeByteString(); + break; + + case FieldType.Enum: + { + EnumDescriptor enumType = field.EnumType; + + if (tokenizer.LookingAtInteger()) + { + int number = tokenizer.ConsumeInt32(); + value = enumType.FindValueByNumber(number); + if (value == null) + { + throw tokenizer.CreateFormatExceptionPreviousToken( + "Enum type \"" + enumType.FullName + + "\" has no value with number " + number + "."); + } + } + else + { + String id = tokenizer.ConsumeIdentifier(); + value = enumType.FindValueByName(id); + if (value == null) + { + throw tokenizer.CreateFormatExceptionPreviousToken( + "Enum type \"" + enumType.FullName + + "\" has no value named \"" + id + "\"."); + } + } + + break; + } + + case FieldType.Message: + case FieldType.Group: + throw new InvalidOperationException("Can't get here."); + } + } + + if (field.IsRepeated) + { + builder.WeakAddRepeatedField(field, value); + } + else + { + builder.SetField(field, value); + } + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/TextGenerator.cs b/src/ProtocolBuffers/TextGenerator.cs index b333ff0a..30cbf0fd 100644 --- a/src/ProtocolBuffers/TextGenerator.cs +++ b/src/ProtocolBuffers/TextGenerator.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,114 +31,129 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #endregion using System; using System.IO; using System.Text; -namespace Google.ProtocolBuffers { - - /// - /// Helper class to control indentation. Used for TextFormat and by ProtoGen. - /// - public sealed class TextGenerator { - - /// - /// The string to use at the end of each line. We assume that "Print" is only called using \n - /// to indicate a line break; that's what we use to detect when we need to indent etc, and - /// *just* the \n is replaced with the contents of lineBreak. - /// - private readonly string lineBreak; - - /// - /// Writer to write formatted text to. - /// - private readonly TextWriter writer; - +namespace Google.ProtocolBuffers +{ /// - /// Keeps track of whether the next piece of text should be indented + /// Helper class to control indentation. Used for TextFormat and by ProtoGen. /// - bool atStartOfLine = true; - - /// - /// Keeps track of the current level of indentation - /// - readonly StringBuilder indent = new StringBuilder(); + public sealed class TextGenerator + { + /// + /// The string to use at the end of each line. We assume that "Print" is only called using \n + /// to indicate a line break; that's what we use to detect when we need to indent etc, and + /// *just* the \n is replaced with the contents of lineBreak. + /// + private readonly string lineBreak; + + /// + /// Writer to write formatted text to. + /// + private readonly TextWriter writer; + + /// + /// Keeps track of whether the next piece of text should be indented + /// + private bool atStartOfLine = true; + + /// + /// Keeps track of the current level of indentation + /// + private readonly StringBuilder indent = new StringBuilder(); + + /// + /// Creates a generator writing to the given writer. The writer + /// is not closed by this class. + /// + public TextGenerator(TextWriter writer, string lineBreak) + { + this.writer = writer; + this.lineBreak = lineBreak; + } - /// - /// Creates a generator writing to the given writer. The writer - /// is not closed by this class. - /// - public TextGenerator(TextWriter writer, string lineBreak) { - this.writer = writer; - this.lineBreak = lineBreak; - } + /// + /// Indents text by two spaces. After calling Indent(), two spaces + /// will be inserted at the beginning of each line of text. Indent() may + /// be called multiple times to produce deeper indents. + /// + public void Indent() + { + indent.Append(" "); + } - /// - /// Indents text by two spaces. After calling Indent(), two spaces - /// will be inserted at the beginning of each line of text. Indent() may - /// be called multiple times to produce deeper indents. - /// - public void Indent() { - indent.Append(" "); - } + /// + /// Reduces the current indent level by two spaces. + /// + public void Outdent() + { + if (indent.Length == 0) + { + throw new InvalidOperationException("Too many calls to Outdent()"); + } + indent.Length -= 2; + } - /// - /// Reduces the current indent level by two spaces. - /// - public void Outdent() { - if (indent.Length == 0) { - throw new InvalidOperationException("Too many calls to Outdent()"); - } - indent.Length -= 2; - } + public void WriteLine(string text) + { + Print(text); + Print("\n"); + } - public void WriteLine(string text) { - Print(text); - Print("\n"); - } + public void WriteLine(string format, params object[] args) + { + WriteLine(string.Format(format, args)); + } - public void WriteLine(string format, params object[] args) { - WriteLine(string.Format(format, args)); - } + public void WriteLine() + { + WriteLine(""); + } - public void WriteLine() { - WriteLine(""); - } + /// + /// Prints the given text to the output stream, indenting at line boundaries. + /// + /// + public void Print(string text) + { + int pos = 0; + + for (int i = 0; i < text.Length; i++) + { + if (text[i] == '\n') + { + // Strip off the \n from what we write + Write(text.Substring(pos, i - pos)); + Write(lineBreak); + pos = i + 1; + atStartOfLine = true; + } + } + Write(text.Substring(pos)); + } - /// - /// Prints the given text to the output stream, indenting at line boundaries. - /// - /// - public void Print(string text) { - int pos = 0; - - for (int i = 0; i < text.Length; i++) { - if (text[i] == '\n') { - // Strip off the \n from what we write - Write(text.Substring(pos, i - pos)); - Write(lineBreak); - pos = i + 1; - atStartOfLine = true; + public void Write(string format, params object[] args) + { + Write(string.Format(format, args)); } - } - Write(text.Substring(pos)); - } - public void Write(string format, params object[] args) { - Write(string.Format(format, args)); - } - - private void Write(string data) { - if (data.Length == 0) { - return; - } - if (atStartOfLine) { - atStartOfLine = false; - writer.Write(indent); - } - writer.Write(data); + private void Write(string data) + { + if (data.Length == 0) + { + return; + } + if (atStartOfLine) + { + atStartOfLine = false; + writer.Write(indent); + } + writer.Write(data); + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/TextTokenizer.cs b/src/ProtocolBuffers/TextTokenizer.cs index d3e8878c..22f73223 100644 --- a/src/ProtocolBuffers/TextTokenizer.cs +++ b/src/ProtocolBuffers/TextTokenizer.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,383 +31,471 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #endregion using System; using System.Globalization; using System.Text.RegularExpressions; -namespace Google.ProtocolBuffers { - /// - /// Represents a stream of tokens parsed from a string. - /// - internal sealed class TextTokenizer { - private readonly string text; - private string currentToken; - +namespace Google.ProtocolBuffers +{ /// - /// The character index within the text to perform the next regex match at. + /// Represents a stream of tokens parsed from a string. /// - private int matchPos = 0; - - /// - /// The character index within the text at which the current token begins. - /// - private int pos = 0; - - /// - /// The line number of the current token. - /// - private int line = 0; - /// - /// The column number of the current token. - /// - private int column = 0; - - /// - /// The line number of the previous token. - /// - private int previousLine = 0; - /// - /// The column number of the previous token. - /// - private int previousColumn = 0; - - // Note: atomic groups used to mimic possessive quantifiers in Java in both of these regexes - internal static readonly Regex WhitespaceAndCommentPattern = new Regex("\\G(?>(\\s|(#.*$))+)", - SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline); - private static readonly Regex TokenPattern = new Regex( - "\\G[a-zA-Z_](?>[0-9a-zA-Z_+-]*)|" + // an identifier - "\\G[0-9+-](?>[0-9a-zA-Z_.+-]*)|" + // a number - "\\G\"(?>([^\"\\\n\\\\]|\\\\.)*)(\"|\\\\?$)|" + // a double-quoted string - "\\G\'(?>([^\"\\\n\\\\]|\\\\.)*)(\'|\\\\?$)", // a single-quoted string - SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline); - - private static readonly Regex DoubleInfinity = new Regex("^-?inf(inity)?$", - SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); - private static readonly Regex FloatInfinity = new Regex("^-?inf(inity)?f?$", - SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); - private static readonly Regex FloatNan = new Regex("^nanf?$", - SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); - - /** Construct a tokenizer that parses tokens from the given text. */ - public TextTokenizer(string text) { - this.text = text; - SkipWhitespace(); - NextToken(); - } - - /// - /// Are we at the end of the input? - /// - public bool AtEnd { - get { return currentToken.Length == 0; } - } - - /// - /// Advances to the next token. - /// - public void NextToken() { - previousLine = line; - previousColumn = column; - - // Advance the line counter to the current position. - while (pos < matchPos) { - if (text[pos] == '\n') { - ++line; - column = 0; - } else { - ++column; + internal sealed class TextTokenizer + { + private readonly string text; + private string currentToken; + + /// + /// The character index within the text to perform the next regex match at. + /// + private int matchPos = 0; + + /// + /// The character index within the text at which the current token begins. + /// + private int pos = 0; + + /// + /// The line number of the current token. + /// + private int line = 0; + + /// + /// The column number of the current token. + /// + private int column = 0; + + /// + /// The line number of the previous token. + /// + private int previousLine = 0; + + /// + /// The column number of the previous token. + /// + private int previousColumn = 0; + + // Note: atomic groups used to mimic possessive quantifiers in Java in both of these regexes + internal static readonly Regex WhitespaceAndCommentPattern = new Regex("\\G(?>(\\s|(#.*$))+)", + SilverlightCompatibility. + CompiledRegexWhereAvailable | + RegexOptions.Multiline); + + private static readonly Regex TokenPattern = new Regex( + "\\G[a-zA-Z_](?>[0-9a-zA-Z_+-]*)|" + // an identifier + "\\G[0-9+-](?>[0-9a-zA-Z_.+-]*)|" + // a number + "\\G\"(?>([^\"\\\n\\\\]|\\\\.)*)(\"|\\\\?$)|" + // a double-quoted string + "\\G\'(?>([^\"\\\n\\\\]|\\\\.)*)(\'|\\\\?$)", // a single-quoted string + SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline); + + private static readonly Regex DoubleInfinity = new Regex("^-?inf(inity)?$", + SilverlightCompatibility.CompiledRegexWhereAvailable | + RegexOptions.IgnoreCase); + + private static readonly Regex FloatInfinity = new Regex("^-?inf(inity)?f?$", + SilverlightCompatibility.CompiledRegexWhereAvailable | + RegexOptions.IgnoreCase); + + private static readonly Regex FloatNan = new Regex("^nanf?$", + SilverlightCompatibility.CompiledRegexWhereAvailable | + RegexOptions.IgnoreCase); + + /** Construct a tokenizer that parses tokens from the given text. */ + + public TextTokenizer(string text) + { + this.text = text; + SkipWhitespace(); + NextToken(); } - ++pos; - } - - // Match the next token. - if (matchPos == text.Length) { - // EOF - currentToken = ""; - } else { - Match match = TokenPattern.Match(text, matchPos); - if (match.Success) { - currentToken = match.Value; - matchPos += match.Length; - } else { - // Take one character. - currentToken = text[matchPos].ToString(); - matchPos++; + + /// + /// Are we at the end of the input? + /// + public bool AtEnd + { + get { return currentToken.Length == 0; } } - SkipWhitespace(); - } - } + /// + /// Advances to the next token. + /// + public void NextToken() + { + previousLine = line; + previousColumn = column; + + // Advance the line counter to the current position. + while (pos < matchPos) + { + if (text[pos] == '\n') + { + ++line; + column = 0; + } + else + { + ++column; + } + ++pos; + } + + // Match the next token. + if (matchPos == text.Length) + { + // EOF + currentToken = ""; + } + else + { + Match match = TokenPattern.Match(text, matchPos); + if (match.Success) + { + currentToken = match.Value; + matchPos += match.Length; + } + else + { + // Take one character. + currentToken = text[matchPos].ToString(); + matchPos++; + } + + SkipWhitespace(); + } + } - /// - /// Skip over any whitespace so that matchPos starts at the next token. - /// - private void SkipWhitespace() { - Match match = WhitespaceAndCommentPattern.Match(text, matchPos); - if (match.Success) { - matchPos += match.Length; - } - } + /// + /// Skip over any whitespace so that matchPos starts at the next token. + /// + private void SkipWhitespace() + { + Match match = WhitespaceAndCommentPattern.Match(text, matchPos); + if (match.Success) + { + matchPos += match.Length; + } + } - /// - /// If the next token exactly matches the given token, consume it and return - /// true. Otherwise, return false without doing anything. - /// - public bool TryConsume(string token) { - if (currentToken == token) { - NextToken(); - return true; - } - return false; - } + /// + /// If the next token exactly matches the given token, consume it and return + /// true. Otherwise, return false without doing anything. + /// + public bool TryConsume(string token) + { + if (currentToken == token) + { + NextToken(); + return true; + } + return false; + } - /* + /* * If the next token exactly matches {@code token}, consume it. Otherwise, * throw a {@link ParseException}. */ - /// - /// If the next token exactly matches the specified one, consume it. - /// Otherwise, throw a FormatException. - /// - /// - public void Consume(string token) { - if (!TryConsume(token)) { - throw CreateFormatException("Expected \"" + token + "\"."); - } - } - - /// - /// Returns true if the next token is an integer, but does not consume it. - /// - public bool LookingAtInteger() { - if (currentToken.Length == 0) { - return false; - } - char c = currentToken[0]; - return ('0' <= c && c <= '9') || c == '-' || c == '+'; - } + /// + /// If the next token exactly matches the specified one, consume it. + /// Otherwise, throw a FormatException. + /// + /// + public void Consume(string token) + { + if (!TryConsume(token)) + { + throw CreateFormatException("Expected \"" + token + "\"."); + } + } - /// - /// If the next token is an identifier, consume it and return its value. - /// Otherwise, throw a FormatException. - /// - public string ConsumeIdentifier() { - foreach (char c in currentToken) { - if (('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - ('0' <= c && c <= '9') || - (c == '_') || (c == '.')) { - // OK - } else { - throw CreateFormatException("Expected identifier."); + /// + /// Returns true if the next token is an integer, but does not consume it. + /// + public bool LookingAtInteger() + { + if (currentToken.Length == 0) + { + return false; + } + + char c = currentToken[0]; + return ('0' <= c && c <= '9') || c == '-' || c == '+'; } - } - string result = currentToken; - NextToken(); - return result; - } + /// + /// If the next token is an identifier, consume it and return its value. + /// Otherwise, throw a FormatException. + /// + public string ConsumeIdentifier() + { + foreach (char c in currentToken) + { + if (('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + ('0' <= c && c <= '9') || + (c == '_') || (c == '.')) + { + // OK + } + else + { + throw CreateFormatException("Expected identifier."); + } + } + + string result = currentToken; + NextToken(); + return result; + } - /// - /// If the next token is a 32-bit signed integer, consume it and return its - /// value. Otherwise, throw a FormatException. - /// - public int ConsumeInt32() { - try { - int result = TextFormat.ParseInt32(currentToken); - NextToken(); - return result; - } catch (FormatException e) { - throw CreateIntegerParseException(e); - } - } + /// + /// If the next token is a 32-bit signed integer, consume it and return its + /// value. Otherwise, throw a FormatException. + /// + public int ConsumeInt32() + { + try + { + int result = TextFormat.ParseInt32(currentToken); + NextToken(); + return result; + } + catch (FormatException e) + { + throw CreateIntegerParseException(e); + } + } - /// - /// If the next token is a 32-bit unsigned integer, consume it and return its - /// value. Otherwise, throw a FormatException. - /// - public uint ConsumeUInt32() { - try { - uint result = TextFormat.ParseUInt32(currentToken); - NextToken(); - return result; - } catch (FormatException e) { - throw CreateIntegerParseException(e); - } - } + /// + /// If the next token is a 32-bit unsigned integer, consume it and return its + /// value. Otherwise, throw a FormatException. + /// + public uint ConsumeUInt32() + { + try + { + uint result = TextFormat.ParseUInt32(currentToken); + NextToken(); + return result; + } + catch (FormatException e) + { + throw CreateIntegerParseException(e); + } + } - /// - /// If the next token is a 64-bit signed integer, consume it and return its - /// value. Otherwise, throw a FormatException. - /// - public long ConsumeInt64() { - try { - long result = TextFormat.ParseInt64(currentToken); - NextToken(); - return result; - } catch (FormatException e) { - throw CreateIntegerParseException(e); - } - } + /// + /// If the next token is a 64-bit signed integer, consume it and return its + /// value. Otherwise, throw a FormatException. + /// + public long ConsumeInt64() + { + try + { + long result = TextFormat.ParseInt64(currentToken); + NextToken(); + return result; + } + catch (FormatException e) + { + throw CreateIntegerParseException(e); + } + } - /// - /// If the next token is a 64-bit unsigned integer, consume it and return its - /// value. Otherwise, throw a FormatException. - /// - public ulong ConsumeUInt64() { - try { - ulong result = TextFormat.ParseUInt64(currentToken); - NextToken(); - return result; - } catch (FormatException e) { - throw CreateIntegerParseException(e); - } - } + /// + /// If the next token is a 64-bit unsigned integer, consume it and return its + /// value. Otherwise, throw a FormatException. + /// + public ulong ConsumeUInt64() + { + try + { + ulong result = TextFormat.ParseUInt64(currentToken); + NextToken(); + return result; + } + catch (FormatException e) + { + throw CreateIntegerParseException(e); + } + } - /// - /// If the next token is a double, consume it and return its value. - /// Otherwise, throw a FormatException. - /// - public double ConsumeDouble() { - // We need to parse infinity and nan separately because - // double.Parse() does not accept "inf", "infinity", or "nan". - if (DoubleInfinity.IsMatch(currentToken)) { - bool negative = currentToken.StartsWith("-"); - NextToken(); - return negative ? double.NegativeInfinity : double.PositiveInfinity; - } - if (currentToken.Equals("nan", StringComparison.InvariantCultureIgnoreCase)) { - NextToken(); - return Double.NaN; - } - - try { - double result = double.Parse(currentToken, CultureInfo.InvariantCulture); - NextToken(); - return result; - } catch (FormatException e) { - throw CreateFloatParseException(e); - } catch (OverflowException e) { - throw CreateFloatParseException(e); - } - } + /// + /// If the next token is a double, consume it and return its value. + /// Otherwise, throw a FormatException. + /// + public double ConsumeDouble() + { + // We need to parse infinity and nan separately because + // double.Parse() does not accept "inf", "infinity", or "nan". + if (DoubleInfinity.IsMatch(currentToken)) + { + bool negative = currentToken.StartsWith("-"); + NextToken(); + return negative ? double.NegativeInfinity : double.PositiveInfinity; + } + if (currentToken.Equals("nan", StringComparison.InvariantCultureIgnoreCase)) + { + NextToken(); + return Double.NaN; + } + + try + { + double result = double.Parse(currentToken, CultureInfo.InvariantCulture); + NextToken(); + return result; + } + catch (FormatException e) + { + throw CreateFloatParseException(e); + } + catch (OverflowException e) + { + throw CreateFloatParseException(e); + } + } - /// - /// If the next token is a float, consume it and return its value. - /// Otherwise, throw a FormatException. - /// - public float ConsumeFloat() { - // We need to parse infinity and nan separately because - // Float.parseFloat() does not accept "inf", "infinity", or "nan". - if (FloatInfinity.IsMatch(currentToken)) { - bool negative = currentToken.StartsWith("-"); - NextToken(); - return negative ? float.NegativeInfinity : float.PositiveInfinity; - } - if (FloatNan.IsMatch(currentToken)) { - NextToken(); - return float.NaN; - } - - if (currentToken.EndsWith("f")) { - currentToken = currentToken.TrimEnd('f'); - } - - try { - float result = float.Parse(currentToken, CultureInfo.InvariantCulture); - NextToken(); - return result; - } catch (FormatException e) { - throw CreateFloatParseException(e); - } catch (OverflowException e) { - throw CreateFloatParseException(e); - } - } + /// + /// If the next token is a float, consume it and return its value. + /// Otherwise, throw a FormatException. + /// + public float ConsumeFloat() + { + // We need to parse infinity and nan separately because + // Float.parseFloat() does not accept "inf", "infinity", or "nan". + if (FloatInfinity.IsMatch(currentToken)) + { + bool negative = currentToken.StartsWith("-"); + NextToken(); + return negative ? float.NegativeInfinity : float.PositiveInfinity; + } + if (FloatNan.IsMatch(currentToken)) + { + NextToken(); + return float.NaN; + } + + if (currentToken.EndsWith("f")) + { + currentToken = currentToken.TrimEnd('f'); + } + + try + { + float result = float.Parse(currentToken, CultureInfo.InvariantCulture); + NextToken(); + return result; + } + catch (FormatException e) + { + throw CreateFloatParseException(e); + } + catch (OverflowException e) + { + throw CreateFloatParseException(e); + } + } - /// - /// If the next token is a Boolean, consume it and return its value. - /// Otherwise, throw a FormatException. - /// - public bool ConsumeBoolean() { - if (currentToken == "true") { - NextToken(); - return true; - } - if (currentToken == "false") { - NextToken(); - return false; - } - throw CreateFormatException("Expected \"true\" or \"false\"."); - } + /// + /// If the next token is a Boolean, consume it and return its value. + /// Otherwise, throw a FormatException. + /// + public bool ConsumeBoolean() + { + if (currentToken == "true") + { + NextToken(); + return true; + } + if (currentToken == "false") + { + NextToken(); + return false; + } + throw CreateFormatException("Expected \"true\" or \"false\"."); + } - /// - /// If the next token is a string, consume it and return its (unescaped) value. - /// Otherwise, throw a FormatException. - /// - public string ConsumeString() { - return ConsumeByteString().ToStringUtf8(); - } + /// + /// If the next token is a string, consume it and return its (unescaped) value. + /// Otherwise, throw a FormatException. + /// + public string ConsumeString() + { + return ConsumeByteString().ToStringUtf8(); + } - /// - /// If the next token is a string, consume it, unescape it as a - /// ByteString and return it. Otherwise, throw a FormatException. - /// - public ByteString ConsumeByteString() { - char quote = currentToken.Length > 0 ? currentToken[0] : '\0'; - if (quote != '\"' && quote != '\'') { - throw CreateFormatException("Expected string."); - } - - if (currentToken.Length < 2 || - currentToken[currentToken.Length-1] != quote) { - throw CreateFormatException("String missing ending quote."); - } - - try { - string escaped = currentToken.Substring(1, currentToken.Length - 2); - ByteString result = TextFormat.UnescapeBytes(escaped); - NextToken(); - return result; - } catch (FormatException e) { - throw CreateFormatException(e.Message); - } - } + /// + /// If the next token is a string, consume it, unescape it as a + /// ByteString and return it. Otherwise, throw a FormatException. + /// + public ByteString ConsumeByteString() + { + char quote = currentToken.Length > 0 ? currentToken[0] : '\0'; + if (quote != '\"' && quote != '\'') + { + throw CreateFormatException("Expected string."); + } + + if (currentToken.Length < 2 || + currentToken[currentToken.Length - 1] != quote) + { + throw CreateFormatException("String missing ending quote."); + } + + try + { + string escaped = currentToken.Substring(1, currentToken.Length - 2); + ByteString result = TextFormat.UnescapeBytes(escaped); + NextToken(); + return result; + } + catch (FormatException e) + { + throw CreateFormatException(e.Message); + } + } - /// - /// Returns a format exception with the current line and column numbers - /// in the description, suitable for throwing. - /// - public FormatException CreateFormatException(string description) { - // Note: People generally prefer one-based line and column numbers. - return new FormatException((line + 1) + ":" + (column + 1) + ": " + description); - } + /// + /// Returns a format exception with the current line and column numbers + /// in the description, suitable for throwing. + /// + public FormatException CreateFormatException(string description) + { + // Note: People generally prefer one-based line and column numbers. + return new FormatException((line + 1) + ":" + (column + 1) + ": " + description); + } - /// - /// Returns a format exception with the line and column numbers of the - /// previous token in the description, suitable for throwing. - /// - public FormatException CreateFormatExceptionPreviousToken(string description) { - // Note: People generally prefer one-based line and column numbers. - return new FormatException((previousLine + 1) + ":" + (previousColumn + 1) + ": " + description); - } + /// + /// Returns a format exception with the line and column numbers of the + /// previous token in the description, suitable for throwing. + /// + public FormatException CreateFormatExceptionPreviousToken(string description) + { + // Note: People generally prefer one-based line and column numbers. + return new FormatException((previousLine + 1) + ":" + (previousColumn + 1) + ": " + description); + } - /// - /// Constructs an appropriate FormatException for the given existing exception - /// when trying to parse an integer. - /// - private FormatException CreateIntegerParseException(FormatException e) { - return CreateFormatException("Couldn't parse integer: " + e.Message); - } + /// + /// Constructs an appropriate FormatException for the given existing exception + /// when trying to parse an integer. + /// + private FormatException CreateIntegerParseException(FormatException e) + { + return CreateFormatException("Couldn't parse integer: " + e.Message); + } - /// - /// Constructs an appropriate FormatException for the given existing exception - /// when trying to parse a float or double. - /// - private FormatException CreateFloatParseException(Exception e) { - return CreateFormatException("Couldn't parse number: " + e.Message); + /// + /// Constructs an appropriate FormatException for the given existing exception + /// when trying to parse a float or double. + /// + private FormatException CreateFloatParseException(Exception e) + { + return CreateFormatException("Couldn't parse number: " + e.Message); + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/ThrowHelper.cs b/src/ProtocolBuffers/ThrowHelper.cs index 580024db..c854a777 100644 --- a/src/ProtocolBuffers/ThrowHelper.cs +++ b/src/ProtocolBuffers/ThrowHelper.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,44 +31,53 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #endregion using System; using System.Collections.Generic; -namespace Google.ProtocolBuffers { - /// - /// Helper methods for throwing exceptions - /// - public static class ThrowHelper { - +namespace Google.ProtocolBuffers +{ /// - /// Throws an ArgumentNullException if the given value is null. + /// Helper methods for throwing exceptions /// - public static void ThrowIfNull(object value, string name) { - if (value == null) { - throw new ArgumentNullException(name); - } - } + public static class ThrowHelper + { + /// + /// Throws an ArgumentNullException if the given value is null. + /// + public static void ThrowIfNull(object value, string name) + { + if (value == null) + { + throw new ArgumentNullException(name); + } + } - /// - /// Throws an ArgumentNullException if the given value is null. - /// - public static void ThrowIfNull(object value) { - if (value == null) { - throw new ArgumentNullException(); - } - } + /// + /// Throws an ArgumentNullException if the given value is null. + /// + public static void ThrowIfNull(object value) + { + if (value == null) + { + throw new ArgumentNullException(); + } + } - /// - /// Throws an ArgumentNullException if the given value or any element within it is null. - /// - public static void ThrowIfAnyNull(IEnumerable sequence) { - foreach (T t in sequence) { - if (t == null) { - throw new ArgumentNullException(); + /// + /// Throws an ArgumentNullException if the given value or any element within it is null. + /// + public static void ThrowIfAnyNull(IEnumerable sequence) + { + foreach (T t in sequence) + { + if (t == null) + { + throw new ArgumentNullException(); + } + } } - } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/UninitializedMessageException.cs b/src/ProtocolBuffers/UninitializedMessageException.cs index 96f50653..9e4f856e 100644 --- a/src/ProtocolBuffers/UninitializedMessageException.cs +++ b/src/ProtocolBuffers/UninitializedMessageException.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,141 +31,178 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #endregion using System; using System.Collections; using System.Collections.Generic; using System.Text; + #if !LITE using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Descriptors; -#endif - -namespace Google.ProtocolBuffers { - /// - /// TODO(jonskeet): Write summary text. - /// - public sealed class UninitializedMessageException : Exception { - private readonly IList missingFields; +#endif - private UninitializedMessageException(IList missingFields) - : base(BuildDescription(missingFields)) { - this.missingFields = new List(missingFields); - } +namespace Google.ProtocolBuffers +{ /// - /// Returns a read-only list of human-readable names of - /// required fields missing from this message. Each name - /// is a full path to a field, e.g. "foo.bar[5].baz" + /// TODO(jonskeet): Write summary text. /// - public IList MissingFields { - get { return missingFields; } - } + public sealed class UninitializedMessageException : Exception + { + private readonly IList missingFields; - /// - /// Converts this exception into an InvalidProtocolBufferException. - /// When a parsed message is missing required fields, this should be thrown - /// instead of UninitializedMessageException. - /// - public InvalidProtocolBufferException AsInvalidProtocolBufferException() { - return new InvalidProtocolBufferException(Message); - } + private UninitializedMessageException(IList missingFields) + : base(BuildDescription(missingFields)) + { + this.missingFields = new List(missingFields); + } - /// - /// Constructs the description string for a given list of missing fields. - /// - private static string BuildDescription(IEnumerable missingFields) { - StringBuilder description = new StringBuilder("Message missing required fields: "); - bool first = true; - foreach(string field in missingFields) { - if (first) { - first = false; - } else { - description.Append(", "); + /// + /// Returns a read-only list of human-readable names of + /// required fields missing from this message. Each name + /// is a full path to a field, e.g. "foo.bar[5].baz" + /// + public IList MissingFields + { + get { return missingFields; } } - description.Append(field); - } - return description.ToString(); - } - /// - /// For Lite exceptions that do not known how to enumerate missing fields - /// - public UninitializedMessageException(IMessageLite message) - : base(String.Format("Message {0} is missing required fields", message.GetType())) { - missingFields = new List(); - } + /// + /// Converts this exception into an InvalidProtocolBufferException. + /// When a parsed message is missing required fields, this should be thrown + /// instead of UninitializedMessageException. + /// + public InvalidProtocolBufferException AsInvalidProtocolBufferException() + { + return new InvalidProtocolBufferException(Message); + } -#if !LITE - public UninitializedMessageException(IMessage message) - : this(FindMissingFields(message)) { - } + /// + /// Constructs the description string for a given list of missing fields. + /// + private static string BuildDescription(IEnumerable missingFields) + { + StringBuilder description = new StringBuilder("Message missing required fields: "); + bool first = true; + foreach (string field in missingFields) + { + if (first) + { + first = false; + } + else + { + description.Append(", "); + } + description.Append(field); + } + return description.ToString(); + } - /// - /// Returns a list of the full "paths" of missing required - /// fields in the specified message. - /// - private static IList FindMissingFields(IMessage message) { - List results = new List(); - FindMissingFields(message, "", results); - return results; - } + /// + /// For Lite exceptions that do not known how to enumerate missing fields + /// + public UninitializedMessageException(IMessageLite message) + : base(String.Format("Message {0} is missing required fields", message.GetType())) + { + missingFields = new List(); + } - /// - /// Recursive helper implementing FindMissingFields. - /// - private static void FindMissingFields(IMessage message, String prefix, List results) { - foreach (FieldDescriptor field in message.DescriptorForType.Fields) { - if (field.IsRequired && !message.HasField(field)) { - results.Add(prefix + field.Name); +#if !LITE + public UninitializedMessageException(IMessage message) + : this(FindMissingFields(message)) + { + } + + /// + /// Returns a list of the full "paths" of missing required + /// fields in the specified message. + /// + private static IList FindMissingFields(IMessage message) + { + List results = new List(); + FindMissingFields(message, "", results); + return results; } - } - - foreach (KeyValuePair entry in message.AllFields) { - FieldDescriptor field = entry.Key; - object value = entry.Value; - - if (field.MappedType == MappedType.Message) { - if (field.IsRepeated) { - int i = 0; - foreach (object element in (IEnumerable) value) { - if (element is IMessage) { - FindMissingFields((IMessage)element, SubMessagePrefix(prefix, field, i++), results); - } else { - results.Add(prefix + field.Name); - } + + /// + /// Recursive helper implementing FindMissingFields. + /// + private static void FindMissingFields(IMessage message, String prefix, List results) + { + foreach (FieldDescriptor field in message.DescriptorForType.Fields) + { + if (field.IsRequired && !message.HasField(field)) + { + results.Add(prefix + field.Name); + } } - } else { - if (message.HasField(field)) { - if (value is IMessage) { - FindMissingFields((IMessage)value, SubMessagePrefix(prefix, field, -1), results); - } else { - results.Add(prefix + field.Name); - } + + foreach (KeyValuePair entry in message.AllFields) + { + FieldDescriptor field = entry.Key; + object value = entry.Value; + + if (field.MappedType == MappedType.Message) + { + if (field.IsRepeated) + { + int i = 0; + foreach (object element in (IEnumerable) value) + { + if (element is IMessage) + { + FindMissingFields((IMessage) element, SubMessagePrefix(prefix, field, i++), results); + } + else + { + results.Add(prefix + field.Name); + } + } + } + else + { + if (message.HasField(field)) + { + if (value is IMessage) + { + FindMissingFields((IMessage) value, SubMessagePrefix(prefix, field, -1), results); + } + else + { + results.Add(prefix + field.Name); + } + } + } + } } - } } - } - } - private static String SubMessagePrefix(String prefix, FieldDescriptor field, int index) { - StringBuilder result = new StringBuilder(prefix); - if (field.IsExtension) { - result.Append('(') - .Append(field.FullName) - .Append(')'); - } else { - result.Append(field.Name); - } - if (index != -1) { - result.Append('[') - .Append(index) - .Append(']'); - } - result.Append('.'); - return result.ToString(); - } + private static String SubMessagePrefix(String prefix, FieldDescriptor field, int index) + { + StringBuilder result = new StringBuilder(prefix); + if (field.IsExtension) + { + result.Append('(') + .Append(field.FullName) + .Append(')'); + } + else + { + result.Append(field.Name); + } + if (index != -1) + { + result.Append('[') + .Append(index) + .Append(']'); + } + result.Append('.'); + return result.ToString(); + } #endif - } -} + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/UnknownField.cs b/src/ProtocolBuffers/UnknownField.cs index 7aed8473..c403e8a9 100644 --- a/src/ProtocolBuffers/UnknownField.cs +++ b/src/ProtocolBuffers/UnknownField.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,335 +39,379 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using Google.ProtocolBuffers.Collections; -namespace Google.ProtocolBuffers { - /// - /// Represents a single field in an UnknownFieldSet. - /// - /// An UnknownField consists of five lists of values. The lists correspond - /// to the five "wire types" used in the protocol buffer binary format. - /// The wire type of each field can be determined from the encoded form alone, - /// without knowing the field's declared type. So, we are able to parse - /// unknown values at least this far and separate them. Normally, only one - /// of the five lists will contain any values, since it is impossible to - /// define a valid message type that declares two different types for the - /// same field number. However, the code is designed to allow for the case - /// where the same unknown field number is encountered using multiple different - /// wire types. - /// - /// UnknownField is an immutable class. To construct one, you must use an - /// UnknownField.Builder. - /// - public sealed class UnknownField { +namespace Google.ProtocolBuffers +{ + /// + /// Represents a single field in an UnknownFieldSet. + /// + /// An UnknownField consists of five lists of values. The lists correspond + /// to the five "wire types" used in the protocol buffer binary format. + /// The wire type of each field can be determined from the encoded form alone, + /// without knowing the field's declared type. So, we are able to parse + /// unknown values at least this far and separate them. Normally, only one + /// of the five lists will contain any values, since it is impossible to + /// define a valid message type that declares two different types for the + /// same field number. However, the code is designed to allow for the case + /// where the same unknown field number is encountered using multiple different + /// wire types. + /// + /// UnknownField is an immutable class. To construct one, you must use an + /// UnknownField.Builder. + /// + public sealed class UnknownField + { + private static readonly UnknownField defaultInstance = CreateBuilder().Build(); + private readonly ReadOnlyCollection varintList; + private readonly ReadOnlyCollection fixed32List; + private readonly ReadOnlyCollection fixed64List; + private readonly ReadOnlyCollection lengthDelimitedList; + private readonly ReadOnlyCollection groupList; - private static readonly UnknownField defaultInstance = CreateBuilder().Build(); - private readonly ReadOnlyCollection varintList; - private readonly ReadOnlyCollection fixed32List; - private readonly ReadOnlyCollection fixed64List; - private readonly ReadOnlyCollection lengthDelimitedList; - private readonly ReadOnlyCollection groupList; + private UnknownField(ReadOnlyCollection varintList, + ReadOnlyCollection fixed32List, + ReadOnlyCollection fixed64List, + ReadOnlyCollection lengthDelimitedList, + ReadOnlyCollection groupList) + { + this.varintList = varintList; + this.fixed32List = fixed32List; + this.fixed64List = fixed64List; + this.lengthDelimitedList = lengthDelimitedList; + this.groupList = groupList; + } - private UnknownField(ReadOnlyCollection varintList, - ReadOnlyCollection fixed32List, - ReadOnlyCollection fixed64List, - ReadOnlyCollection lengthDelimitedList, - ReadOnlyCollection groupList) { - this.varintList = varintList; - this.fixed32List = fixed32List; - this.fixed64List = fixed64List; - this.lengthDelimitedList = lengthDelimitedList; - this.groupList = groupList; - } + public static UnknownField DefaultInstance + { + get { return defaultInstance; } + } - public static UnknownField DefaultInstance { - get { return defaultInstance; } - } + /// + /// The list of varint values for this field. + /// + public IList VarintList + { + get { return varintList; } + } - /// - /// The list of varint values for this field. - /// - public IList VarintList { - get { return varintList; } - } + /// + /// The list of fixed32 values for this field. + /// + public IList Fixed32List + { + get { return fixed32List; } + } - /// - /// The list of fixed32 values for this field. - /// - public IList Fixed32List { - get { return fixed32List; } - } + /// + /// The list of fixed64 values for this field. + /// + public IList Fixed64List + { + get { return fixed64List; } + } - /// - /// The list of fixed64 values for this field. - /// - public IList Fixed64List { - get { return fixed64List; } - } + /// + /// The list of length-delimited values for this field. + /// + public IList LengthDelimitedList + { + get { return lengthDelimitedList; } + } - /// - /// The list of length-delimited values for this field. - /// - public IList LengthDelimitedList { - get { return lengthDelimitedList; } - } + /// + /// The list of embedded group values for this field. These + /// are represented using UnknownFieldSets rather than Messages + /// since the group's type is presumably unknown. + /// + public IList GroupList + { + get { return groupList; } + } - /// - /// The list of embedded group values for this field. These - /// are represented using UnknownFieldSets rather than Messages - /// since the group's type is presumably unknown. - /// - public IList GroupList { - get { return groupList; } - } + public override bool Equals(object other) + { + if (ReferenceEquals(this, other)) + { + return true; + } + UnknownField otherField = other as UnknownField; + return otherField != null + && Lists.Equals(varintList, otherField.varintList) + && Lists.Equals(fixed32List, otherField.fixed32List) + && Lists.Equals(fixed64List, otherField.fixed64List) + && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList) + && Lists.Equals(groupList, otherField.groupList); + } - public override bool Equals(object other) { - if (ReferenceEquals(this, other)) { - return true; - } - UnknownField otherField = other as UnknownField; - return otherField != null - && Lists.Equals(varintList, otherField.varintList) - && Lists.Equals(fixed32List, otherField.fixed32List) - && Lists.Equals(fixed64List, otherField.fixed64List) - && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList) - && Lists.Equals(groupList, otherField.groupList); - } + public override int GetHashCode() + { + int hash = 43; + hash = hash*47 + Lists.GetHashCode(varintList); + hash = hash*47 + Lists.GetHashCode(fixed32List); + hash = hash*47 + Lists.GetHashCode(fixed64List); + hash = hash*47 + Lists.GetHashCode(lengthDelimitedList); + hash = hash*47 + Lists.GetHashCode(groupList); + return hash; + } - public override int GetHashCode() { - int hash = 43; - hash = hash * 47 + Lists.GetHashCode(varintList); - hash = hash * 47 + Lists.GetHashCode(fixed32List); - hash = hash * 47 + Lists.GetHashCode(fixed64List); - hash = hash * 47 + Lists.GetHashCode(lengthDelimitedList); - hash = hash * 47 + Lists.GetHashCode(groupList); - return hash; - } + /// + /// Constructs a new Builder. + /// + public static Builder CreateBuilder() + { + return new Builder(); + } - /// - /// Constructs a new Builder. - /// - public static Builder CreateBuilder() { - return new Builder(); - } + /// + /// Constructs a new Builder and initializes it to a copy of . + /// + public static Builder CreateBuilder(UnknownField copyFrom) + { + return new Builder().MergeFrom(copyFrom); + } - /// - /// Constructs a new Builder and initializes it to a copy of . - /// - public static Builder CreateBuilder(UnknownField copyFrom) { - return new Builder().MergeFrom(copyFrom); - } - - /// - /// Serializes the field, including the field number, and writes it to - /// . - /// - public void WriteTo(int fieldNumber, CodedOutputStream output) { - foreach (ulong value in varintList) { - output.WriteUInt64(fieldNumber, value); - } - foreach (uint value in fixed32List) { - output.WriteFixed32(fieldNumber, value); - } - foreach (ulong value in fixed64List) { - output.WriteFixed64(fieldNumber, value); - } - foreach (ByteString value in lengthDelimitedList) { - output.WriteBytes(fieldNumber, value); - } - foreach (UnknownFieldSet value in groupList) { + /// + /// Serializes the field, including the field number, and writes it to + /// . + /// + public void WriteTo(int fieldNumber, CodedOutputStream output) + { + foreach (ulong value in varintList) + { + output.WriteUInt64(fieldNumber, value); + } + foreach (uint value in fixed32List) + { + output.WriteFixed32(fieldNumber, value); + } + foreach (ulong value in fixed64List) + { + output.WriteFixed64(fieldNumber, value); + } + foreach (ByteString value in lengthDelimitedList) + { + output.WriteBytes(fieldNumber, value); + } + foreach (UnknownFieldSet value in groupList) + { #pragma warning disable 0612 - output.WriteUnknownGroup(fieldNumber, value); + output.WriteUnknownGroup(fieldNumber, value); #pragma warning restore 0612 - } - } + } + } - /// - /// Computes the number of bytes required to encode this field, including field - /// number. - /// - public int GetSerializedSize(int fieldNumber) { - int result = 0; - foreach (ulong value in varintList) { - result += CodedOutputStream.ComputeUInt64Size(fieldNumber, value); - } - foreach (uint value in fixed32List) { - result += CodedOutputStream.ComputeFixed32Size(fieldNumber, value); - } - foreach (ulong value in fixed64List) { - result += CodedOutputStream.ComputeFixed64Size(fieldNumber, value); - } - foreach (ByteString value in lengthDelimitedList) { - result += CodedOutputStream.ComputeBytesSize(fieldNumber, value); - } - foreach (UnknownFieldSet value in groupList) { + /// + /// Computes the number of bytes required to encode this field, including field + /// number. + /// + public int GetSerializedSize(int fieldNumber) + { + int result = 0; + foreach (ulong value in varintList) + { + result += CodedOutputStream.ComputeUInt64Size(fieldNumber, value); + } + foreach (uint value in fixed32List) + { + result += CodedOutputStream.ComputeFixed32Size(fieldNumber, value); + } + foreach (ulong value in fixed64List) + { + result += CodedOutputStream.ComputeFixed64Size(fieldNumber, value); + } + foreach (ByteString value in lengthDelimitedList) + { + result += CodedOutputStream.ComputeBytesSize(fieldNumber, value); + } + foreach (UnknownFieldSet value in groupList) + { #pragma warning disable 0612 - result += CodedOutputStream.ComputeUnknownGroupSize(fieldNumber, value); + result += CodedOutputStream.ComputeUnknownGroupSize(fieldNumber, value); #pragma warning restore 0612 - } - return result; - } + } + return result; + } - /// - /// Serializes the length-delimited values of the field, including field - /// number, and writes them to using the MessageSet wire format. - /// - /// - /// - public void WriteAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) { - foreach (ByteString value in lengthDelimitedList) { - output.WriteRawMessageSetExtension(fieldNumber, value); - } - } + /// + /// Serializes the length-delimited values of the field, including field + /// number, and writes them to using the MessageSet wire format. + /// + /// + /// + public void WriteAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) + { + foreach (ByteString value in lengthDelimitedList) + { + output.WriteRawMessageSetExtension(fieldNumber, value); + } + } - /// - /// Get the number of bytes required to encode this field, incuding field number, - /// using the MessageSet wire format. - /// - public int GetSerializedSizeAsMessageSetExtension(int fieldNumber) { - int result = 0; - foreach (ByteString value in lengthDelimitedList) { - result += CodedOutputStream.ComputeRawMessageSetExtensionSize(fieldNumber, value); - } - return result; - } + /// + /// Get the number of bytes required to encode this field, incuding field number, + /// using the MessageSet wire format. + /// + public int GetSerializedSizeAsMessageSetExtension(int fieldNumber) + { + int result = 0; + foreach (ByteString value in lengthDelimitedList) + { + result += CodedOutputStream.ComputeRawMessageSetExtensionSize(fieldNumber, value); + } + return result; + } - /// - /// Used to build instances of UnknownField. - /// - public sealed class Builder { + /// + /// Used to build instances of UnknownField. + /// + public sealed class Builder + { + private List varintList; + private List fixed32List; + private List fixed64List; + private List lengthDelimitedList; + private List groupList; - private List varintList; - private List fixed32List; - private List fixed64List; - private List lengthDelimitedList; - private List groupList; + /// + /// Builds the field. After building, the builder is reset to an empty + /// state. (This is actually easier than making it unusable.) + /// + public UnknownField Build() + { + return new UnknownField(MakeReadOnly(ref varintList), + MakeReadOnly(ref fixed32List), + MakeReadOnly(ref fixed64List), + MakeReadOnly(ref lengthDelimitedList), + MakeReadOnly(ref groupList)); + } - /// - /// Builds the field. After building, the builder is reset to an empty - /// state. (This is actually easier than making it unusable.) - /// - public UnknownField Build() { - return new UnknownField(MakeReadOnly(ref varintList), - MakeReadOnly(ref fixed32List), - MakeReadOnly(ref fixed64List), - MakeReadOnly(ref lengthDelimitedList), - MakeReadOnly(ref groupList)); - } + /// + /// Merge the values in into this field. For each list + /// of values, 's values are append to the ones in this + /// field. + /// + public Builder MergeFrom(UnknownField other) + { + varintList = AddAll(varintList, other.VarintList); + fixed32List = AddAll(fixed32List, other.Fixed32List); + fixed64List = AddAll(fixed64List, other.Fixed64List); + lengthDelimitedList = AddAll(lengthDelimitedList, other.LengthDelimitedList); + groupList = AddAll(groupList, other.GroupList); + return this; + } - /// - /// Merge the values in into this field. For each list - /// of values, 's values are append to the ones in this - /// field. - /// - public Builder MergeFrom(UnknownField other) { - varintList = AddAll(varintList, other.VarintList); - fixed32List = AddAll(fixed32List, other.Fixed32List); - fixed64List = AddAll(fixed64List, other.Fixed64List); - lengthDelimitedList = AddAll(lengthDelimitedList, other.LengthDelimitedList); - groupList = AddAll(groupList, other.GroupList); - return this; - } + /// + /// Returns a new list containing all of the given specified values from + /// both the and lists. + /// If is null and is empty, + /// null is returned. Otherwise, either a new list is created (if + /// is null) or the elements of are added to . + /// + private static List AddAll(List current, IList extras) + { + if (extras.Count == 0) + { + return current; + } + if (current == null) + { + current = new List(extras); + } + else + { + current.AddRange(extras); + } + return current; + } - /// - /// Returns a new list containing all of the given specified values from - /// both the and lists. - /// If is null and is empty, - /// null is returned. Otherwise, either a new list is created (if - /// is null) or the elements of are added to . - /// - private static List AddAll(List current, IList extras) - { - if (extras.Count == 0) { - return current; - } - if (current == null) { - current = new List(extras); - } else { - current.AddRange(extras); - } - return current; - } + /// + /// Clears the contents of this builder. + /// + public Builder Clear() + { + varintList = null; + fixed32List = null; + fixed64List = null; + lengthDelimitedList = null; + groupList = null; + return this; + } - /// - /// Clears the contents of this builder. - /// - public Builder Clear() { - varintList = null; - fixed32List = null; - fixed64List = null; - lengthDelimitedList = null; - groupList = null; - return this; - } + /// + /// Adds a varint value. + /// + [CLSCompliant(false)] + public Builder AddVarint(ulong value) + { + varintList = Add(varintList, value); + return this; + } - /// - /// Adds a varint value. - /// - [CLSCompliant(false)] - public Builder AddVarint(ulong value) { - varintList = Add(varintList, value); - return this; - } + /// + /// Adds a fixed32 value. + /// + [CLSCompliant(false)] + public Builder AddFixed32(uint value) + { + fixed32List = Add(fixed32List, value); + return this; + } - /// - /// Adds a fixed32 value. - /// - [CLSCompliant(false)] - public Builder AddFixed32(uint value) { - fixed32List = Add(fixed32List, value); - return this; - } + /// + /// Adds a fixed64 value. + /// + [CLSCompliant(false)] + public Builder AddFixed64(ulong value) + { + fixed64List = Add(fixed64List, value); + return this; + } - /// - /// Adds a fixed64 value. - /// - [CLSCompliant(false)] - public Builder AddFixed64(ulong value) { - fixed64List = Add(fixed64List, value); - return this; - } + /// + /// Adds a length-delimited value. + /// + public Builder AddLengthDelimited(ByteString value) + { + lengthDelimitedList = Add(lengthDelimitedList, value); + return this; + } - /// - /// Adds a length-delimited value. - /// - public Builder AddLengthDelimited(ByteString value) { - lengthDelimitedList = Add(lengthDelimitedList, value); - return this; - } + /// + /// Adds an embedded group. + /// + /// + /// + public Builder AddGroup(UnknownFieldSet value) + { + groupList = Add(groupList, value); + return this; + } - /// - /// Adds an embedded group. - /// - /// - /// - public Builder AddGroup(UnknownFieldSet value) { - groupList = Add(groupList, value); - return this; - } + /// + /// Adds to the , creating + /// a new list if is null. The list is returned - either + /// the original reference or the new list. + /// + private static List Add(List list, T value) + { + if (list == null) + { + list = new List(); + } + list.Add(value); + return list; + } - /// - /// Adds to the , creating - /// a new list if is null. The list is returned - either - /// the original reference or the new list. - /// - private static List Add(List list, T value) { - if (list == null) { - list = new List(); + /// + /// Returns a read-only version of the given IList, and clears + /// the field used for . If the value + /// is null, an empty list is produced using Lists.Empty. + /// + /// + private static ReadOnlyCollection MakeReadOnly(ref List list) + { + ReadOnlyCollection ret = list == null ? Lists.Empty : new ReadOnlyCollection(list); + list = null; + return ret; + } } - list.Add(value); - return list; - } - - /// - /// Returns a read-only version of the given IList, and clears - /// the field used for . If the value - /// is null, an empty list is produced using Lists.Empty. - /// - /// - private static ReadOnlyCollection MakeReadOnly(ref List list) { - ReadOnlyCollection ret = list == null ? Lists.Empty : new ReadOnlyCollection(list); - list = null; - return ret; - } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/UnknownFieldSet.cs b/src/ProtocolBuffers/UnknownFieldSet.cs index be773e41..ee268c54 100644 --- a/src/ProtocolBuffers/UnknownFieldSet.cs +++ b/src/ProtocolBuffers/UnknownFieldSet.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; @@ -39,730 +41,871 @@ using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.DescriptorProtos; -namespace Google.ProtocolBuffers { - /// - /// Used to keep track of fields which were seen when parsing a protocol message - /// but whose field numbers or types are unrecognized. This most frequently - /// occurs when new fields are added to a message type and then messages containing - /// those fields are read by old software that was built before the new types were - /// added. - /// - /// Every message contains an UnknownFieldSet. - /// - /// Most users will never need to use this class directly. - /// - public sealed class UnknownFieldSet : IMessageLite { - - private static readonly UnknownFieldSet defaultInstance = new UnknownFieldSet(new Dictionary()); - - private readonly IDictionary fields; - - private UnknownFieldSet(IDictionary fields) { - this.fields = fields; - } - - /// - /// Creates a new unknown field set builder. - /// - public static Builder CreateBuilder() { - return new Builder(); - } - - /// - /// Creates a new unknown field set builder - /// and initialize it from . - /// - public static Builder CreateBuilder(UnknownFieldSet original) { - return new Builder().MergeFrom(original); - } - - public static UnknownFieldSet DefaultInstance { - get { return defaultInstance; } - } - +namespace Google.ProtocolBuffers +{ /// - /// Returns a read-only view of the mapping from field numbers to values. + /// Used to keep track of fields which were seen when parsing a protocol message + /// but whose field numbers or types are unrecognized. This most frequently + /// occurs when new fields are added to a message type and then messages containing + /// those fields are read by old software that was built before the new types were + /// added. + /// + /// Every message contains an UnknownFieldSet. + /// + /// Most users will never need to use this class directly. /// - public IDictionary FieldDictionary { - get { return Dictionaries.AsReadOnly(fields); } - } + public sealed class UnknownFieldSet : IMessageLite + { + private static readonly UnknownFieldSet defaultInstance = + new UnknownFieldSet(new Dictionary()); - /// - /// Checks whether or not the given field number is present in the set. - /// - public bool HasField(int field) { - return fields.ContainsKey(field); - } + private readonly IDictionary fields; - /// - /// Fetches a field by number, returning an empty field if not present. - /// Never returns null. - /// - public UnknownField this[int number] { - get { - UnknownField ret; - if (!fields.TryGetValue(number, out ret)) { - ret = UnknownField.DefaultInstance; + private UnknownFieldSet(IDictionary fields) + { + this.fields = fields; } - return ret; - } - } - /// - /// Serializes the set and writes it to . - /// - public void WriteTo(CodedOutputStream output) { - foreach (KeyValuePair entry in fields) { - entry.Value.WriteTo(entry.Key, output); - } - } + /// + /// Creates a new unknown field set builder. + /// + public static Builder CreateBuilder() + { + return new Builder(); + } - /// - /// Gets the number of bytes required to encode this set. - /// - public int SerializedSize { - get { - int result = 0; - foreach (KeyValuePair entry in fields) { - result += entry.Value.GetSerializedSize(entry.Key); + /// + /// Creates a new unknown field set builder + /// and initialize it from . + /// + public static Builder CreateBuilder(UnknownFieldSet original) + { + return new Builder().MergeFrom(original); } - return result; - } - } - /// - /// Converts the set to a string in protocol buffer text format. This - /// is just a trivial wrapper around TextFormat.PrintToString. - /// - public override String ToString() { - return TextFormat.PrintToString(this); - } + public static UnknownFieldSet DefaultInstance + { + get { return defaultInstance; } + } - /// - /// Converts the set to a string in protocol buffer text format. This - /// is just a trivial wrapper around TextFormat.PrintToString. - /// - public void PrintTo(TextWriter writer) { - TextFormat.Print(this, writer); - } + /// + /// Returns a read-only view of the mapping from field numbers to values. + /// + public IDictionary FieldDictionary + { + get { return Dictionaries.AsReadOnly(fields); } + } - /// - /// Serializes the message to a ByteString and returns it. This is - /// just a trivial wrapper around WriteTo(CodedOutputStream). - /// - /// - public ByteString ToByteString() { - ByteString.CodedBuilder codedBuilder = new ByteString.CodedBuilder(SerializedSize); - WriteTo(codedBuilder.CodedOutput); - return codedBuilder.Build(); - } + /// + /// Checks whether or not the given field number is present in the set. + /// + public bool HasField(int field) + { + return fields.ContainsKey(field); + } - /// - /// Serializes the message to a byte array and returns it. This is - /// just a trivial wrapper around WriteTo(CodedOutputStream). - /// - /// - public byte[] ToByteArray() { - byte[] data = new byte[SerializedSize]; - CodedOutputStream output = CodedOutputStream.CreateInstance(data); - WriteTo(output); - output.CheckNoSpaceLeft(); - return data; - } + /// + /// Fetches a field by number, returning an empty field if not present. + /// Never returns null. + /// + public UnknownField this[int number] + { + get + { + UnknownField ret; + if (!fields.TryGetValue(number, out ret)) + { + ret = UnknownField.DefaultInstance; + } + return ret; + } + } - /// - /// Serializes the message and writes it to . This is - /// just a trivial wrapper around WriteTo(CodedOutputStream). - /// - /// - public void WriteTo(Stream output) { - CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output); - WriteTo(codedOutput); - codedOutput.Flush(); - } + /// + /// Serializes the set and writes it to . + /// + public void WriteTo(CodedOutputStream output) + { + foreach (KeyValuePair entry in fields) + { + entry.Value.WriteTo(entry.Key, output); + } + } - /// - /// Serializes the set and writes it to using - /// the MessageSet wire format. - /// - public void WriteAsMessageSetTo(CodedOutputStream output) { - foreach (KeyValuePair entry in fields) { - entry.Value.WriteAsMessageSetExtensionTo(entry.Key, output); - } - } + /// + /// Gets the number of bytes required to encode this set. + /// + public int SerializedSize + { + get + { + int result = 0; + foreach (KeyValuePair entry in fields) + { + result += entry.Value.GetSerializedSize(entry.Key); + } + return result; + } + } - /// - /// Gets the number of bytes required to encode this set using the MessageSet - /// wire format. - /// - public int SerializedSizeAsMessageSet { - get { - int result = 0; - foreach (KeyValuePair entry in fields) { - result += entry.Value.GetSerializedSizeAsMessageSetExtension(entry.Key); + /// + /// Converts the set to a string in protocol buffer text format. This + /// is just a trivial wrapper around TextFormat.PrintToString. + /// + public override String ToString() + { + return TextFormat.PrintToString(this); } - return result; - } - } - public override bool Equals(object other) { - if (ReferenceEquals(this, other)) { - return true; - } - UnknownFieldSet otherSet = other as UnknownFieldSet; - return otherSet != null && Dictionaries.Equals(fields, otherSet.fields); - } + /// + /// Converts the set to a string in protocol buffer text format. This + /// is just a trivial wrapper around TextFormat.PrintToString. + /// + public void PrintTo(TextWriter writer) + { + TextFormat.Print(this, writer); + } - public override int GetHashCode() { - return Dictionaries.GetHashCode(fields); - } + /// + /// Serializes the message to a ByteString and returns it. This is + /// just a trivial wrapper around WriteTo(CodedOutputStream). + /// + /// + public ByteString ToByteString() + { + ByteString.CodedBuilder codedBuilder = new ByteString.CodedBuilder(SerializedSize); + WriteTo(codedBuilder.CodedOutput); + return codedBuilder.Build(); + } - /// - /// Parses an UnknownFieldSet from the given input. - /// - public static UnknownFieldSet ParseFrom(CodedInputStream input) { - return CreateBuilder().MergeFrom(input).Build(); - } + /// + /// Serializes the message to a byte array and returns it. This is + /// just a trivial wrapper around WriteTo(CodedOutputStream). + /// + /// + public byte[] ToByteArray() + { + byte[] data = new byte[SerializedSize]; + CodedOutputStream output = CodedOutputStream.CreateInstance(data); + WriteTo(output); + output.CheckNoSpaceLeft(); + return data; + } - /// - /// Parses an UnknownFieldSet from the given data. - /// - public static UnknownFieldSet ParseFrom(ByteString data) { - return CreateBuilder().MergeFrom(data).Build(); - } + /// + /// Serializes the message and writes it to . This is + /// just a trivial wrapper around WriteTo(CodedOutputStream). + /// + /// + public void WriteTo(Stream output) + { + CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output); + WriteTo(codedOutput); + codedOutput.Flush(); + } - /// - /// Parses an UnknownFieldSet from the given data. - /// - public static UnknownFieldSet ParseFrom(byte[] data) { - return CreateBuilder().MergeFrom(data).Build(); - } + /// + /// Serializes the set and writes it to using + /// the MessageSet wire format. + /// + public void WriteAsMessageSetTo(CodedOutputStream output) + { + foreach (KeyValuePair entry in fields) + { + entry.Value.WriteAsMessageSetExtensionTo(entry.Key, output); + } + } - /// - /// Parses an UnknownFieldSet from the given input. - /// - public static UnknownFieldSet ParseFrom(Stream input) { - return CreateBuilder().MergeFrom(input).Build(); - } + /// + /// Gets the number of bytes required to encode this set using the MessageSet + /// wire format. + /// + public int SerializedSizeAsMessageSet + { + get + { + int result = 0; + foreach (KeyValuePair entry in fields) + { + result += entry.Value.GetSerializedSizeAsMessageSetExtension(entry.Key); + } + return result; + } + } - #region IMessageLite Members + public override bool Equals(object other) + { + if (ReferenceEquals(this, other)) + { + return true; + } + UnknownFieldSet otherSet = other as UnknownFieldSet; + return otherSet != null && Dictionaries.Equals(fields, otherSet.fields); + } - public bool IsInitialized { - get { return fields != null; } - } + public override int GetHashCode() + { + return Dictionaries.GetHashCode(fields); + } - public void WriteDelimitedTo(Stream output) { - CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output); - codedOutput.WriteRawVarint32((uint) SerializedSize); - WriteTo(codedOutput); - codedOutput.Flush(); - } + /// + /// Parses an UnknownFieldSet from the given input. + /// + public static UnknownFieldSet ParseFrom(CodedInputStream input) + { + return CreateBuilder().MergeFrom(input).Build(); + } - public IBuilderLite WeakCreateBuilderForType() { - return new Builder(); - } + /// + /// Parses an UnknownFieldSet from the given data. + /// + public static UnknownFieldSet ParseFrom(ByteString data) + { + return CreateBuilder().MergeFrom(data).Build(); + } - public IBuilderLite WeakToBuilder() { - return new Builder(fields); - } + /// + /// Parses an UnknownFieldSet from the given data. + /// + public static UnknownFieldSet ParseFrom(byte[] data) + { + return CreateBuilder().MergeFrom(data).Build(); + } - public IMessageLite WeakDefaultInstanceForType { - get { return defaultInstance; } - } + /// + /// Parses an UnknownFieldSet from the given input. + /// + public static UnknownFieldSet ParseFrom(Stream input) + { + return CreateBuilder().MergeFrom(input).Build(); + } - #endregion + #region IMessageLite Members - /// - /// Builder for UnknownFieldSets. - /// - public sealed class Builder : IBuilderLite - { - /// - /// Mapping from number to field. Note that by using a SortedList we ensure - /// that the fields will be serialized in ascending order. - /// - private IDictionary fields; - // Optimization: We keep around a builder for the last field that was - // modified so that we can efficiently add to it multiple times in a - // row (important when parsing an unknown repeated field). - private int lastFieldNumber; - private UnknownField.Builder lastField; - - internal Builder() { - fields = new SortedList(); - } - - internal Builder(IDictionary dictionary) { - fields = new SortedList(dictionary); - } - - /// - /// Returns a field builder for the specified field number, including any values - /// which already exist. - /// - private UnknownField.Builder GetFieldBuilder(int number) { - if (lastField != null) { - if (number == lastFieldNumber) { - return lastField; - } - // Note: AddField() will reset lastField and lastFieldNumber. - AddField(lastFieldNumber, lastField.Build()); - } - if (number == 0) { - return null; + public bool IsInitialized + { + get { return fields != null; } } - lastField = UnknownField.CreateBuilder(); - UnknownField existing; - if (fields.TryGetValue(number, out existing)) { - lastField.MergeFrom(existing); + public void WriteDelimitedTo(Stream output) + { + CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output); + codedOutput.WriteRawVarint32((uint) SerializedSize); + WriteTo(codedOutput); + codedOutput.Flush(); } - lastFieldNumber = number; - return lastField; - } - - /// - /// Build the UnknownFieldSet and return it. Once this method has been called, - /// this instance will no longer be usable. Calling any method after this - /// will throw a NullReferenceException. - /// - public UnknownFieldSet Build() { - GetFieldBuilder(0); // Force lastField to be built. - UnknownFieldSet result = fields.Count == 0 ? DefaultInstance : new UnknownFieldSet(fields); - fields = null; - return result; - } - - /// - /// Adds a field to the set. If a field with the same number already exists, it - /// is replaced. - /// - public Builder AddField(int number, UnknownField field) { - if (number == 0) { - throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); + + public IBuilderLite WeakCreateBuilderForType() + { + return new Builder(); } - if (lastField != null && lastFieldNumber == number) { - // Discard this. - lastField = null; - lastFieldNumber = 0; + + public IBuilderLite WeakToBuilder() + { + return new Builder(fields); } - fields[number] = field; - return this; - } - - /// - /// Resets the builder to an empty set. - /// - public Builder Clear() { - fields.Clear(); - lastFieldNumber = 0; - lastField = null; - return this; - } - - /// - /// Parse an entire message from and merge - /// its fields into this set. - /// - public Builder MergeFrom(CodedInputStream input) { - while (true) { - uint tag = input.ReadTag(); - if (tag == 0 || !MergeFieldFrom(tag, input)) { - break; - } + + public IMessageLite WeakDefaultInstanceForType + { + get { return defaultInstance; } } - return this; - } + + #endregion /// - /// Parse a single field from and merge it - /// into this set. + /// Builder for UnknownFieldSets. /// - /// The field's tag number, which was already parsed. - /// The coded input stream containing the field - /// false if the tag is an "end group" tag, true otherwise - [CLSCompliant(false)] - public bool MergeFieldFrom(uint tag, CodedInputStream input) { - int number = WireFormat.GetTagFieldNumber(tag); - switch (WireFormat.GetTagWireType(tag)) { - case WireFormat.WireType.Varint: - GetFieldBuilder(number).AddVarint(input.ReadUInt64()); - return true; - case WireFormat.WireType.Fixed64: - GetFieldBuilder(number).AddFixed64(input.ReadFixed64()); - return true; - case WireFormat.WireType.LengthDelimited: - GetFieldBuilder(number).AddLengthDelimited(input.ReadBytes()); - return true; - case WireFormat.WireType.StartGroup: { - Builder subBuilder = CreateBuilder(); + public sealed class Builder : IBuilderLite + { + /// + /// Mapping from number to field. Note that by using a SortedList we ensure + /// that the fields will be serialized in ascending order. + /// + private IDictionary fields; + + // Optimization: We keep around a builder for the last field that was + // modified so that we can efficiently add to it multiple times in a + // row (important when parsing an unknown repeated field). + private int lastFieldNumber; + private UnknownField.Builder lastField; + + internal Builder() + { + fields = new SortedList(); + } + + internal Builder(IDictionary dictionary) + { + fields = new SortedList(dictionary); + } + + /// + /// Returns a field builder for the specified field number, including any values + /// which already exist. + /// + private UnknownField.Builder GetFieldBuilder(int number) + { + if (lastField != null) + { + if (number == lastFieldNumber) + { + return lastField; + } + // Note: AddField() will reset lastField and lastFieldNumber. + AddField(lastFieldNumber, lastField.Build()); + } + if (number == 0) + { + return null; + } + + lastField = UnknownField.CreateBuilder(); + UnknownField existing; + if (fields.TryGetValue(number, out existing)) + { + lastField.MergeFrom(existing); + } + lastFieldNumber = number; + return lastField; + } + + /// + /// Build the UnknownFieldSet and return it. Once this method has been called, + /// this instance will no longer be usable. Calling any method after this + /// will throw a NullReferenceException. + /// + public UnknownFieldSet Build() + { + GetFieldBuilder(0); // Force lastField to be built. + UnknownFieldSet result = fields.Count == 0 ? DefaultInstance : new UnknownFieldSet(fields); + fields = null; + return result; + } + + /// + /// Adds a field to the set. If a field with the same number already exists, it + /// is replaced. + /// + public Builder AddField(int number, UnknownField field) + { + if (number == 0) + { + throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); + } + if (lastField != null && lastFieldNumber == number) + { + // Discard this. + lastField = null; + lastFieldNumber = 0; + } + fields[number] = field; + return this; + } + + /// + /// Resets the builder to an empty set. + /// + public Builder Clear() + { + fields.Clear(); + lastFieldNumber = 0; + lastField = null; + return this; + } + + /// + /// Parse an entire message from and merge + /// its fields into this set. + /// + public Builder MergeFrom(CodedInputStream input) + { + while (true) + { + uint tag = input.ReadTag(); + if (tag == 0 || !MergeFieldFrom(tag, input)) + { + break; + } + } + return this; + } + + /// + /// Parse a single field from and merge it + /// into this set. + /// + /// The field's tag number, which was already parsed. + /// The coded input stream containing the field + /// false if the tag is an "end group" tag, true otherwise + [CLSCompliant(false)] + public bool MergeFieldFrom(uint tag, CodedInputStream input) + { + int number = WireFormat.GetTagFieldNumber(tag); + switch (WireFormat.GetTagWireType(tag)) + { + case WireFormat.WireType.Varint: + GetFieldBuilder(number).AddVarint(input.ReadUInt64()); + return true; + case WireFormat.WireType.Fixed64: + GetFieldBuilder(number).AddFixed64(input.ReadFixed64()); + return true; + case WireFormat.WireType.LengthDelimited: + GetFieldBuilder(number).AddLengthDelimited(input.ReadBytes()); + return true; + case WireFormat.WireType.StartGroup: + { + Builder subBuilder = CreateBuilder(); #pragma warning disable 0612 - input.ReadUnknownGroup(number, subBuilder); + input.ReadUnknownGroup(number, subBuilder); #pragma warning restore 0612 - GetFieldBuilder(number).AddGroup(subBuilder.Build()); - return true; - } - case WireFormat.WireType.EndGroup: - return false; - case WireFormat.WireType.Fixed32: - GetFieldBuilder(number).AddFixed32(input.ReadFixed32()); - return true; - default: - throw InvalidProtocolBufferException.InvalidWireType(); - } - } - - /// - /// Parses as an UnknownFieldSet and merge it - /// with the set being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). - /// - public Builder MergeFrom(Stream input) { - CodedInputStream codedInput = CodedInputStream.CreateInstance(input); - MergeFrom(codedInput); - codedInput.CheckLastTagWas(0); - return this; - } - - /// - /// Parses as an UnknownFieldSet and merge it - /// with the set being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). - /// - public Builder MergeFrom(ByteString data) { - CodedInputStream input = data.CreateCodedInput(); - MergeFrom(input); - input.CheckLastTagWas(0); - return this; - } - - /// - /// Parses as an UnknownFieldSet and merge it - /// with the set being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream). - /// - public Builder MergeFrom(byte[] data) { - CodedInputStream input = CodedInputStream.CreateInstance(data); - MergeFrom(input); - input.CheckLastTagWas(0); - return this; - } - - /// - /// Convenience method for merging a new field containing a single varint - /// value. This is used in particular when an unknown enum value is - /// encountered. - /// - [CLSCompliant(false)] - public Builder MergeVarintField(int number, ulong value) { - if (number == 0) { - throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); - } - GetFieldBuilder(number).AddVarint(value); - return this; - } - - /// - /// Merges the fields from into this set. - /// If a field number exists in both sets, the values in - /// will be appended to the values in this set. - /// - public Builder MergeFrom(UnknownFieldSet other) { - if (other != DefaultInstance) { - foreach(KeyValuePair entry in other.fields) { - MergeField(entry.Key, entry.Value); - } - } - return this; - } - - /// - /// Checks if the given field number is present in the set. - /// - public bool HasField(int number) { - if (number == 0) { - throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); - } - return number == lastFieldNumber || fields.ContainsKey(number); - } - - /// - /// Adds a field to the unknown field set. If a field with the same - /// number already exists, the two are merged. - /// - public Builder MergeField(int number, UnknownField field) { - if (number == 0) { - throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); - } - if (HasField(number)) { - GetFieldBuilder(number).MergeFrom(field); - } else { - // Optimization: We could call getFieldBuilder(number).mergeFrom(field) - // in this case, but that would create a copy of the Field object. - // We'd rather reuse the one passed to us, so call AddField() instead. - AddField(number, field); - } - return this; - } - - internal void MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder) { - while (true) { - uint tag = input.ReadTag(); - if (tag == 0) { - break; - } - - if (!MergeFieldFrom(input, extensionRegistry, builder, tag)) { - // end group tag - break; - } - } - } - - /// - /// Like - /// but parses a single field. - /// - /// The input to read the field from - /// Registry to use when an extension field is encountered - /// Builder to merge field into, if it's a known field - /// The tag, which should already have been read from the input - /// true unless the tag is an end-group tag - internal bool MergeFieldFrom(CodedInputStream input, - ExtensionRegistry extensionRegistry, IBuilder builder, uint tag) { - - MessageDescriptor type = builder.DescriptorForType; - if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart) { - MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder); - return true; - } + GetFieldBuilder(number).AddGroup(subBuilder.Build()); + return true; + } + case WireFormat.WireType.EndGroup: + return false; + case WireFormat.WireType.Fixed32: + GetFieldBuilder(number).AddFixed32(input.ReadFixed32()); + return true; + default: + throw InvalidProtocolBufferException.InvalidWireType(); + } + } - WireFormat.WireType wireType = WireFormat.GetTagWireType(tag); - int fieldNumber = WireFormat.GetTagFieldNumber(tag); - - FieldDescriptor field; - IMessageLite defaultFieldInstance = null; - - if (type.IsExtensionNumber(fieldNumber)) { - ExtensionInfo extension = extensionRegistry[type, fieldNumber]; - if (extension == null) { - field = null; - } else { - field = extension.Descriptor; - defaultFieldInstance = extension.DefaultInstance; - } - } else { - field = type.FindFieldByNumber(fieldNumber); - } + /// + /// Parses as an UnknownFieldSet and merge it + /// with the set being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). + /// + public Builder MergeFrom(Stream input) + { + CodedInputStream codedInput = CodedInputStream.CreateInstance(input); + MergeFrom(codedInput); + codedInput.CheckLastTagWas(0); + return this; + } - // Unknown field or wrong wire type. Skip. - if (field == null || wireType != WireFormat.GetWireType(field)) { - return MergeFieldFrom(tag, input); - } + /// + /// Parses as an UnknownFieldSet and merge it + /// with the set being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). + /// + public Builder MergeFrom(ByteString data) + { + CodedInputStream input = data.CreateCodedInput(); + MergeFrom(input); + input.CheckLastTagWas(0); + return this; + } - if (field.IsPacked) { - int length = (int)input.ReadRawVarint32(); - int limit = input.PushLimit(length); - if (field.FieldType == FieldType.Enum) { - while (!input.ReachedLimit) { - int rawValue = input.ReadEnum(); - object value = field.EnumType.FindValueByNumber(rawValue); - if (value == null) { - // If the number isn't recognized as a valid value for this - // enum, drop it (don't even add it to unknownFields). - return true; - } - builder.WeakAddRepeatedField(field, value); - } - } else { - while (!input.ReachedLimit) { - Object value = input.ReadPrimitiveField(field.FieldType); - builder.WeakAddRepeatedField(field, value); - } - } - input.PopLimit(limit); - } else { - object value; - switch (field.FieldType) { - case FieldType.Group: - case FieldType.Message: { - IBuilderLite subBuilder; - if (defaultFieldInstance != null) { - subBuilder = defaultFieldInstance.WeakCreateBuilderForType(); - } else { - subBuilder = builder.CreateBuilderForField(field); + /// + /// Parses as an UnknownFieldSet and merge it + /// with the set being built. This is just a small wrapper around + /// MergeFrom(CodedInputStream). + /// + public Builder MergeFrom(byte[] data) + { + CodedInputStream input = CodedInputStream.CreateInstance(data); + MergeFrom(input); + input.CheckLastTagWas(0); + return this; + } + + /// + /// Convenience method for merging a new field containing a single varint + /// value. This is used in particular when an unknown enum value is + /// encountered. + /// + [CLSCompliant(false)] + public Builder MergeVarintField(int number, ulong value) + { + if (number == 0) + { + throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); } - if (!field.IsRepeated) { - subBuilder.WeakMergeFrom((IMessageLite)builder[field]); + GetFieldBuilder(number).AddVarint(value); + return this; + } + + /// + /// Merges the fields from into this set. + /// If a field number exists in both sets, the values in + /// will be appended to the values in this set. + /// + public Builder MergeFrom(UnknownFieldSet other) + { + if (other != DefaultInstance) + { + foreach (KeyValuePair entry in other.fields) + { + MergeField(entry.Key, entry.Value); + } } - if (field.FieldType == FieldType.Group) { - input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry); - } else { - input.ReadMessage(subBuilder, extensionRegistry); + return this; + } + + /// + /// Checks if the given field number is present in the set. + /// + public bool HasField(int number) + { + if (number == 0) + { + throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); } - value = subBuilder.WeakBuild(); - break; - } - case FieldType.Enum: { - int rawValue = input.ReadEnum(); - value = field.EnumType.FindValueByNumber(rawValue); - // If the number isn't recognized as a valid value for this enum, - // drop it. - if (value == null) { - MergeVarintField(fieldNumber, (ulong)rawValue); - return true; + return number == lastFieldNumber || fields.ContainsKey(number); + } + + /// + /// Adds a field to the unknown field set. If a field with the same + /// number already exists, the two are merged. + /// + public Builder MergeField(int number, UnknownField field) + { + if (number == 0) + { + throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); } - break; - } - default: - value = input.ReadPrimitiveField(field.FieldType); - break; - } - if (field.IsRepeated) { - builder.WeakAddRepeatedField(field, value); - } else { - builder[field] = value; - } - } - return true; - } - - /// - /// Called by MergeFieldFrom to parse a MessageSet extension. - /// - private void MergeMessageSetExtensionFromCodedStream(CodedInputStream input, - ExtensionRegistry extensionRegistry, IBuilder builder) { - MessageDescriptor type = builder.DescriptorForType; - - // The wire format for MessageSet is: - // message MessageSet { - // repeated group Item = 1 { - // required int32 typeId = 2; - // required bytes message = 3; - // } - // } - // "typeId" is the extension's field number. The extension can only be - // a message type, where "message" contains the encoded bytes of that - // message. - // - // In practice, we will probably never see a MessageSet item in which - // the message appears before the type ID, or where either field does not - // appear exactly once. However, in theory such cases are valid, so we - // should be prepared to accept them. - - int typeId = 0; - ByteString rawBytes = null; // If we encounter "message" before "typeId" - IBuilderLite subBuilder = null; - FieldDescriptor field = null; - - while (true) { - uint tag = input.ReadTag(); - if (tag == 0) { - break; - } - - if (tag == WireFormat.MessageSetTag.TypeID) { - typeId = input.ReadInt32(); - // Zero is not a valid type ID. - if (typeId != 0) { - ExtensionInfo extension = extensionRegistry[type, typeId]; - if (extension != null) { - field = extension.Descriptor; - subBuilder = extension.DefaultInstance.WeakCreateBuilderForType(); - IMessageLite originalMessage = (IMessageLite)builder[field]; - if (originalMessage != null) { - subBuilder.WeakMergeFrom(originalMessage); + if (HasField(number)) + { + GetFieldBuilder(number).MergeFrom(field); } - if (rawBytes != null) { - // We already encountered the message. Parse it now. - // TODO(jonskeet): Check this is okay. It's subtly different from the Java, as it doesn't create an input stream from rawBytes. - // In fact, why don't we just call MergeFrom(rawBytes)? And what about the extension registry? - subBuilder.WeakMergeFrom(rawBytes.CreateCodedInput()); - rawBytes = null; + else + { + // Optimization: We could call getFieldBuilder(number).mergeFrom(field) + // in this case, but that would create a copy of the Field object. + // We'd rather reuse the one passed to us, so call AddField() instead. + AddField(number, field); } - } else { - // Unknown extension number. If we already saw data, put it - // in rawBytes. - if (rawBytes != null) { - MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(rawBytes).Build()); - rawBytes = null; + return this; + } + + internal void MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder) + { + while (true) + { + uint tag = input.ReadTag(); + if (tag == 0) + { + break; + } + + if (!MergeFieldFrom(input, extensionRegistry, builder, tag)) + { + // end group tag + break; + } } - } - } - } else if (tag == WireFormat.MessageSetTag.Message) { - if (typeId == 0) { - // We haven't seen a type ID yet, so we have to store the raw bytes for now. - rawBytes = input.ReadBytes(); - } else if (subBuilder == null) { - // We don't know how to parse this. Ignore it. - MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(input.ReadBytes()).Build()); - } else { - // We already know the type, so we can parse directly from the input - // with no copying. Hooray! - input.ReadMessage(subBuilder, extensionRegistry); - } - } else { - // Unknown tag. Skip it. - if (!input.SkipField(tag)) { - break; // end of group - } - } - } + } - input.CheckLastTagWas(WireFormat.MessageSetTag.ItemEnd); + /// + /// Like + /// but parses a single field. + /// + /// The input to read the field from + /// Registry to use when an extension field is encountered + /// Builder to merge field into, if it's a known field + /// The tag, which should already have been read from the input + /// true unless the tag is an end-group tag + internal bool MergeFieldFrom(CodedInputStream input, + ExtensionRegistry extensionRegistry, IBuilder builder, uint tag) + { + MessageDescriptor type = builder.DescriptorForType; + if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart) + { + MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder); + return true; + } - if (subBuilder != null) { - builder[field] = subBuilder.WeakBuild(); - } - } + WireFormat.WireType wireType = WireFormat.GetTagWireType(tag); + int fieldNumber = WireFormat.GetTagFieldNumber(tag); + + FieldDescriptor field; + IMessageLite defaultFieldInstance = null; + + if (type.IsExtensionNumber(fieldNumber)) + { + ExtensionInfo extension = extensionRegistry[type, fieldNumber]; + if (extension == null) + { + field = null; + } + else + { + field = extension.Descriptor; + defaultFieldInstance = extension.DefaultInstance; + } + } + else + { + field = type.FindFieldByNumber(fieldNumber); + } - #region IBuilderLite Members + // Unknown field or wrong wire type. Skip. + if (field == null || wireType != WireFormat.GetWireType(field)) + { + return MergeFieldFrom(tag, input); + } - bool IBuilderLite.IsInitialized { - get { return fields != null; } - } + if (field.IsPacked) + { + int length = (int) input.ReadRawVarint32(); + int limit = input.PushLimit(length); + if (field.FieldType == FieldType.Enum) + { + while (!input.ReachedLimit) + { + int rawValue = input.ReadEnum(); + object value = field.EnumType.FindValueByNumber(rawValue); + if (value == null) + { + // If the number isn't recognized as a valid value for this + // enum, drop it (don't even add it to unknownFields). + return true; + } + builder.WeakAddRepeatedField(field, value); + } + } + else + { + while (!input.ReachedLimit) + { + Object value = input.ReadPrimitiveField(field.FieldType); + builder.WeakAddRepeatedField(field, value); + } + } + input.PopLimit(limit); + } + else + { + object value; + switch (field.FieldType) + { + case FieldType.Group: + case FieldType.Message: + { + IBuilderLite subBuilder; + if (defaultFieldInstance != null) + { + subBuilder = defaultFieldInstance.WeakCreateBuilderForType(); + } + else + { + subBuilder = builder.CreateBuilderForField(field); + } + if (!field.IsRepeated) + { + subBuilder.WeakMergeFrom((IMessageLite) builder[field]); + } + if (field.FieldType == FieldType.Group) + { + input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry); + } + else + { + input.ReadMessage(subBuilder, extensionRegistry); + } + value = subBuilder.WeakBuild(); + break; + } + case FieldType.Enum: + { + int rawValue = input.ReadEnum(); + value = field.EnumType.FindValueByNumber(rawValue); + // If the number isn't recognized as a valid value for this enum, + // drop it. + if (value == null) + { + MergeVarintField(fieldNumber, (ulong) rawValue); + return true; + } + break; + } + default: + value = input.ReadPrimitiveField(field.FieldType); + break; + } + if (field.IsRepeated) + { + builder.WeakAddRepeatedField(field, value); + } + else + { + builder[field] = value; + } + } + return true; + } - IBuilderLite IBuilderLite.WeakClear() { - return Clear(); - } + /// + /// Called by MergeFieldFrom to parse a MessageSet extension. + /// + private void MergeMessageSetExtensionFromCodedStream(CodedInputStream input, + ExtensionRegistry extensionRegistry, IBuilder builder) + { + MessageDescriptor type = builder.DescriptorForType; + + // The wire format for MessageSet is: + // message MessageSet { + // repeated group Item = 1 { + // required int32 typeId = 2; + // required bytes message = 3; + // } + // } + // "typeId" is the extension's field number. The extension can only be + // a message type, where "message" contains the encoded bytes of that + // message. + // + // In practice, we will probably never see a MessageSet item in which + // the message appears before the type ID, or where either field does not + // appear exactly once. However, in theory such cases are valid, so we + // should be prepared to accept them. + + int typeId = 0; + ByteString rawBytes = null; // If we encounter "message" before "typeId" + IBuilderLite subBuilder = null; + FieldDescriptor field = null; + + while (true) + { + uint tag = input.ReadTag(); + if (tag == 0) + { + break; + } + + if (tag == WireFormat.MessageSetTag.TypeID) + { + typeId = input.ReadInt32(); + // Zero is not a valid type ID. + if (typeId != 0) + { + ExtensionInfo extension = extensionRegistry[type, typeId]; + if (extension != null) + { + field = extension.Descriptor; + subBuilder = extension.DefaultInstance.WeakCreateBuilderForType(); + IMessageLite originalMessage = (IMessageLite) builder[field]; + if (originalMessage != null) + { + subBuilder.WeakMergeFrom(originalMessage); + } + if (rawBytes != null) + { + // We already encountered the message. Parse it now. + // TODO(jonskeet): Check this is okay. It's subtly different from the Java, as it doesn't create an input stream from rawBytes. + // In fact, why don't we just call MergeFrom(rawBytes)? And what about the extension registry? + subBuilder.WeakMergeFrom(rawBytes.CreateCodedInput()); + rawBytes = null; + } + } + else + { + // Unknown extension number. If we already saw data, put it + // in rawBytes. + if (rawBytes != null) + { + MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(rawBytes).Build()); + rawBytes = null; + } + } + } + } + else if (tag == WireFormat.MessageSetTag.Message) + { + if (typeId == 0) + { + // We haven't seen a type ID yet, so we have to store the raw bytes for now. + rawBytes = input.ReadBytes(); + } + else if (subBuilder == null) + { + // We don't know how to parse this. Ignore it. + MergeField(typeId, + UnknownField.CreateBuilder().AddLengthDelimited(input.ReadBytes()).Build()); + } + else + { + // We already know the type, so we can parse directly from the input + // with no copying. Hooray! + input.ReadMessage(subBuilder, extensionRegistry); + } + } + else + { + // Unknown tag. Skip it. + if (!input.SkipField(tag)) + { + break; // end of group + } + } + } - IBuilderLite IBuilderLite.WeakMergeFrom(IMessageLite message) { - return MergeFrom((UnknownFieldSet)message); - } + input.CheckLastTagWas(WireFormat.MessageSetTag.ItemEnd); - IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data) { - return MergeFrom(data); - } + if (subBuilder != null) + { + builder[field] = subBuilder.WeakBuild(); + } + } - IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistry registry) { - return MergeFrom(data); - } + #region IBuilderLite Members - IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input) { - return MergeFrom(input); - } + bool IBuilderLite.IsInitialized + { + get { return fields != null; } + } - IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) { - return MergeFrom(input); - } + IBuilderLite IBuilderLite.WeakClear() + { + return Clear(); + } - IMessageLite IBuilderLite.WeakBuild() { - return Build(); - } + IBuilderLite IBuilderLite.WeakMergeFrom(IMessageLite message) + { + return MergeFrom((UnknownFieldSet) message); + } - IMessageLite IBuilderLite.WeakBuildPartial() { - return Build(); - } + IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data) + { + return MergeFrom(data); + } - IBuilderLite IBuilderLite.WeakClone() { - return Build().WeakToBuilder(); - } + IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistry registry) + { + return MergeFrom(data); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input) + { + return MergeFrom(input); + } - IMessageLite IBuilderLite.WeakDefaultInstanceForType { - get { return DefaultInstance; } - } + IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) + { + return MergeFrom(input); + } - #endregion + IMessageLite IBuilderLite.WeakBuild() + { + return Build(); + } + + IMessageLite IBuilderLite.WeakBuildPartial() + { + return Build(); + } + + IBuilderLite IBuilderLite.WeakClone() + { + return Build().WeakToBuilder(); + } + + IMessageLite IBuilderLite.WeakDefaultInstanceForType + { + get { return DefaultInstance; } + } + + #endregion + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffers/WireFormat.cs b/src/ProtocolBuffers/WireFormat.cs index 953364ad..53a5c826 100644 --- a/src/ProtocolBuffers/WireFormat.cs +++ b/src/ProtocolBuffers/WireFormat.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,149 +31,165 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #endregion using System; + #if !LITE using Google.ProtocolBuffers.Descriptors; + #endif -namespace Google.ProtocolBuffers { - - /// - /// This class is used internally by the Protocol Buffer Library and generated - /// message implementations. It is public only for the sake of those generated - /// messages. Others should not use this class directly. - /// - /// This class contains constants and helper functions useful for dealing with - /// the Protocol Buffer wire format. - /// - /// - public static class WireFormat { - -#region Fixed sizes. - // TODO(jonskeet): Move these somewhere else. They're messy. Consider making FieldType a smarter kind of enum - public const int Fixed32Size = 4; - public const int Fixed64Size = 8; - public const int SFixed32Size = 4; - public const int SFixed64Size = 8; - public const int FloatSize = 4; - public const int DoubleSize = 8; - public const int BoolSize = 1; -#endregion +namespace Google.ProtocolBuffers +{ + /// + /// This class is used internally by the Protocol Buffer Library and generated + /// message implementations. It is public only for the sake of those generated + /// messages. Others should not use this class directly. + /// + /// This class contains constants and helper functions useful for dealing with + /// the Protocol Buffer wire format. + /// + /// + public static class WireFormat + { + #region Fixed sizes. - [CLSCompliant(false)] - public enum WireType : uint { - Varint = 0, - Fixed64 = 1, - LengthDelimited = 2, - StartGroup = 3, - EndGroup = 4, - Fixed32 = 5 - } + // TODO(jonskeet): Move these somewhere else. They're messy. Consider making FieldType a smarter kind of enum + public const int Fixed32Size = 4; + public const int Fixed64Size = 8; + public const int SFixed32Size = 4; + public const int SFixed64Size = 8; + public const int FloatSize = 4; + public const int DoubleSize = 8; + public const int BoolSize = 1; - internal static class MessageSetField { - internal const int Item = 1; - internal const int TypeID = 2; - internal const int Message = 3; - } + #endregion - internal static class MessageSetTag { - internal static readonly uint ItemStart = MakeTag(MessageSetField.Item, WireType.StartGroup); - internal static readonly uint ItemEnd = MakeTag(MessageSetField.Item, WireType.EndGroup); - internal static readonly uint TypeID = MakeTag(MessageSetField.TypeID, WireType.Varint); - internal static readonly uint Message = MakeTag(MessageSetField.Message, WireType.LengthDelimited); - } - - private const int TagTypeBits = 3; - private const uint TagTypeMask = (1 << TagTypeBits) - 1; + [CLSCompliant(false)] + public enum WireType : uint + { + Varint = 0, + Fixed64 = 1, + LengthDelimited = 2, + StartGroup = 3, + EndGroup = 4, + Fixed32 = 5 + } - /// - /// Given a tag value, determines the wire type (lower 3 bits). - /// - [CLSCompliant(false)] - public static WireType GetTagWireType(uint tag) { - return (WireType) (tag & TagTypeMask); - } + internal static class MessageSetField + { + internal const int Item = 1; + internal const int TypeID = 2; + internal const int Message = 3; + } - [CLSCompliant(false)] - public static bool IsEndGroupTag(uint tag) { - return (WireType)(tag & TagTypeMask) == WireType.EndGroup; - } + internal static class MessageSetTag + { + internal static readonly uint ItemStart = MakeTag(MessageSetField.Item, WireType.StartGroup); + internal static readonly uint ItemEnd = MakeTag(MessageSetField.Item, WireType.EndGroup); + internal static readonly uint TypeID = MakeTag(MessageSetField.TypeID, WireType.Varint); + internal static readonly uint Message = MakeTag(MessageSetField.Message, WireType.LengthDelimited); + } - /// - /// Given a tag value, determines the field number (the upper 29 bits). - /// - [CLSCompliant(false)] - public static int GetTagFieldNumber(uint tag) { - return (int) tag >> TagTypeBits; - } + private const int TagTypeBits = 3; + private const uint TagTypeMask = (1 << TagTypeBits) - 1; - /// - /// Makes a tag value given a field number and wire type. - /// TODO(jonskeet): Should we just have a Tag structure? - /// - [CLSCompliant(false)] - public static uint MakeTag(int fieldNumber, WireType wireType) { - return (uint) (fieldNumber << TagTypeBits) | (uint) wireType; - } + /// + /// Given a tag value, determines the wire type (lower 3 bits). + /// + [CLSCompliant(false)] + public static WireType GetTagWireType(uint tag) + { + return (WireType) (tag & TagTypeMask); + } + + [CLSCompliant(false)] + public static bool IsEndGroupTag(uint tag) + { + return (WireType) (tag & TagTypeMask) == WireType.EndGroup; + } + + /// + /// Given a tag value, determines the field number (the upper 29 bits). + /// + [CLSCompliant(false)] + public static int GetTagFieldNumber(uint tag) + { + return (int) tag >> TagTypeBits; + } + + /// + /// Makes a tag value given a field number and wire type. + /// TODO(jonskeet): Should we just have a Tag structure? + /// + [CLSCompliant(false)] + public static uint MakeTag(int fieldNumber, WireType wireType) + { + return (uint) (fieldNumber << TagTypeBits) | (uint) wireType; + } #if !LITE - [CLSCompliant(false)] - public static uint MakeTag(FieldDescriptor field) { - return MakeTag(field.FieldNumber, GetWireType(field)); - } + [CLSCompliant(false)] + public static uint MakeTag(FieldDescriptor field) + { + return MakeTag(field.FieldNumber, GetWireType(field)); + } - /// - /// Returns the wire type for the given field descriptor. This differs - /// from GetWireType(FieldType) for packed repeated fields. - /// - internal static WireType GetWireType(FieldDescriptor descriptor) { - return descriptor.IsPacked ? WireType.LengthDelimited : GetWireType(descriptor.FieldType); - } + /// + /// Returns the wire type for the given field descriptor. This differs + /// from GetWireType(FieldType) for packed repeated fields. + /// + internal static WireType GetWireType(FieldDescriptor descriptor) + { + return descriptor.IsPacked ? WireType.LengthDelimited : GetWireType(descriptor.FieldType); + } - /// - /// Converts a field type to its wire type. Done with a switch for the sake - /// of speed - this is significantly faster than a dictionary lookup. - /// - [CLSCompliant(false)] - public static WireType GetWireType(FieldType fieldType) { - switch (fieldType) { - case FieldType.Double: - return WireType.Fixed64; - case FieldType.Float: - return WireType.Fixed32; - case FieldType.Int64: - case FieldType.UInt64: - case FieldType.Int32: - return WireType.Varint; - case FieldType.Fixed64: - return WireType.Fixed64; - case FieldType.Fixed32: - return WireType.Fixed32; - case FieldType.Bool: - return WireType.Varint; - case FieldType.String: - return WireType.LengthDelimited; - case FieldType.Group: - return WireType.StartGroup; - case FieldType.Message: - case FieldType.Bytes: - return WireType.LengthDelimited; - case FieldType.UInt32: - return WireType.Varint; - case FieldType.SFixed32: - return WireType.Fixed32; - case FieldType.SFixed64: - return WireType.Fixed64; - case FieldType.SInt32: - case FieldType.SInt64: - case FieldType.Enum: - return WireType.Varint; - default: - throw new ArgumentOutOfRangeException("No such field type"); - } - } + /// + /// Converts a field type to its wire type. Done with a switch for the sake + /// of speed - this is significantly faster than a dictionary lookup. + /// + [CLSCompliant(false)] + public static WireType GetWireType(FieldType fieldType) + { + switch (fieldType) + { + case FieldType.Double: + return WireType.Fixed64; + case FieldType.Float: + return WireType.Fixed32; + case FieldType.Int64: + case FieldType.UInt64: + case FieldType.Int32: + return WireType.Varint; + case FieldType.Fixed64: + return WireType.Fixed64; + case FieldType.Fixed32: + return WireType.Fixed32; + case FieldType.Bool: + return WireType.Varint; + case FieldType.String: + return WireType.LengthDelimited; + case FieldType.Group: + return WireType.StartGroup; + case FieldType.Message: + case FieldType.Bytes: + return WireType.LengthDelimited; + case FieldType.UInt32: + return WireType.Varint; + case FieldType.SFixed32: + return WireType.Fixed32; + case FieldType.SFixed64: + return WireType.Fixed64; + case FieldType.SInt32: + case FieldType.SInt64: + case FieldType.Enum: + return WireType.Varint; + default: + throw new ArgumentOutOfRangeException("No such field type"); + } + } #endif - } -} + } +} \ No newline at end of file diff --git a/src/ProtocolBuffersLite.Test/AbstractBuilderLiteTest.cs b/src/ProtocolBuffersLite.Test/AbstractBuilderLiteTest.cs index b2c743f3..2a612a9c 100644 --- a/src/ProtocolBuffersLite.Test/AbstractBuilderLiteTest.cs +++ b/src/ProtocolBuffersLite.Test/AbstractBuilderLiteTest.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; @@ -39,230 +41,269 @@ using Google.ProtocolBuffers; using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; -namespace Google.ProtocolBuffers { - [TestFixture] - public class AbstractBuilderLiteTest { - - [Test] - public void TestMergeFromCodedInputStream() { - TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder() - .SetOptionalUint32(uint.MaxValue).Build(); - - copy = TestAllTypesLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - using (MemoryStream ms = new MemoryStream(msg.ToByteArray())) { - CodedInputStream ci = CodedInputStream.CreateInstance(ms); - copy = copy.ToBuilder().MergeFrom(ci).Build(); - } - - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestIBuilderLiteWeakClear() { - TestAllTypesLite copy, msg = TestAllTypesLite.DefaultInstance; - - copy = msg.ToBuilder().SetOptionalString("Should be removed.").Build(); - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakClear().WeakBuild(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestBuilderLiteMergeFromCodedInputStream() { - TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder() - .SetOptionalString("Should be merged.").Build(); - - copy = TestAllTypesLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - copy = copy.ToBuilder().MergeFrom(CodedInputStream.CreateInstance(new MemoryStream(msg.ToByteArray()))).Build(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestBuilderLiteMergeDelimitedFrom() { - TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder() - .SetOptionalString("Should be merged.").Build(); - - copy = TestAllTypesLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - Stream s = new MemoryStream(); - msg.WriteDelimitedTo(s); - s.Position = 0; - copy = copy.ToBuilder().MergeDelimitedFrom(s).Build(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestBuilderLiteMergeDelimitedFromExtensions() { - TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build(); - - copy = TestAllExtensionsLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - Stream s = new MemoryStream(); - msg.WriteDelimitedTo(s); - s.Position = 0; - - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestLiteProtoFile.RegisterAllExtensions(registry); - - copy = copy.ToBuilder().MergeDelimitedFrom(s, registry).Build(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite)); - } - - [Test] - public void TestBuilderLiteMergeFromStream() { - TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder() - .SetOptionalString("Should be merged.").Build(); - - copy = TestAllTypesLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - Stream s = new MemoryStream(); - msg.WriteTo(s); - s.Position = 0; - copy = copy.ToBuilder().MergeFrom(s).Build(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestBuilderLiteMergeFromStreamExtensions() { - TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build(); - - copy = TestAllExtensionsLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - Stream s = new MemoryStream(); - msg.WriteTo(s); - s.Position = 0; - - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestLiteProtoFile.RegisterAllExtensions(registry); - - copy = copy.ToBuilder().MergeFrom(s, registry).Build(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite)); - } - - [Test] - public void TestIBuilderLiteWeakMergeFromIMessageLite() { - TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder() - .SetOptionalString("Should be merged.").Build(); - - copy = TestAllTypesLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom((IMessageLite)msg).WeakBuild(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestIBuilderLiteWeakMergeFromByteString() { - TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder() - .SetOptionalString("Should be merged.").Build(); - - copy = TestAllTypesLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString()).WeakBuild(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestIBuilderLiteWeakMergeFromByteStringExtensions() { - TestAllExtensionsLite copy, msg = TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Should be merged.").Build(); - - copy = TestAllExtensionsLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - copy = (TestAllExtensionsLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString(), ExtensionRegistry.Empty).WeakBuild(); - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestLiteProtoFile.RegisterAllExtensions(registry); - - copy = (TestAllExtensionsLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(msg.ToByteString(), registry).WeakBuild(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite)); - } - - [Test] - public void TestIBuilderLiteWeakMergeFromCodedInputStream() { - TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder() - .SetOptionalUint32(uint.MaxValue).Build(); - - copy = TestAllTypesLite.DefaultInstance; - Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); - - using (MemoryStream ms = new MemoryStream(msg.ToByteArray())) { - CodedInputStream ci = CodedInputStream.CreateInstance(ms); - copy = (TestAllTypesLite)((IBuilderLite)copy.ToBuilder()).WeakMergeFrom(ci).WeakBuild(); - } - - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestIBuilderLiteWeakBuildPartial() { - IBuilderLite builder = TestRequiredLite.CreateBuilder(); - Assert.IsFalse(builder.IsInitialized); - - IMessageLite msg = builder.WeakBuildPartial(); - Assert.IsFalse(msg.IsInitialized); - - Assert.AreEqual(msg.ToByteArray(), TestRequiredLite.DefaultInstance.ToByteArray()); - } - - [Test, ExpectedException(typeof(UninitializedMessageException ))] - public void TestIBuilderLiteWeakBuildUninitialized() { - IBuilderLite builder = TestRequiredLite.CreateBuilder(); - Assert.IsFalse(builder.IsInitialized); - builder.WeakBuild(); - } - - [Test] - public void TestIBuilderLiteWeakBuild() { - IBuilderLite builder = TestRequiredLite.CreateBuilder() - .SetD(0) - .SetEn(ExtraEnum.EXLITE_BAZ); - Assert.IsTrue(builder.IsInitialized); - builder.WeakBuild(); - } - - [Test] - public void TestIBuilderLiteWeakClone() { - TestRequiredLite msg = TestRequiredLite.CreateBuilder() - .SetD(1).SetEn(ExtraEnum.EXLITE_BAR).Build(); - Assert.IsTrue(msg.IsInitialized); - - IMessageLite copy = ((IBuilderLite)msg.ToBuilder()).WeakClone().WeakBuild(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestIBuilderLiteWeakDefaultInstance() { - Assert.IsTrue(ReferenceEquals(TestRequiredLite.DefaultInstance, - ((IBuilderLite)TestRequiredLite.CreateBuilder()).WeakDefaultInstanceForType)); - } - - [Test] - public void TestGeneratedBuilderLiteAddRange() { - TestAllTypesLite copy, msg = TestAllTypesLite.CreateBuilder() - .SetOptionalUint32(123) - .AddRepeatedInt32(1) - .AddRepeatedInt32(2) - .AddRepeatedInt32(3) - .Build(); - - copy = msg.DefaultInstanceForType.ToBuilder().MergeFrom(msg).Build(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); +namespace Google.ProtocolBuffers +{ + [TestFixture] + public class AbstractBuilderLiteTest + { + [Test] + public void TestMergeFromCodedInputStream() + { + TestAllTypesLite copy, + msg = TestAllTypesLite.CreateBuilder() + .SetOptionalUint32(uint.MaxValue).Build(); + + copy = TestAllTypesLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + using (MemoryStream ms = new MemoryStream(msg.ToByteArray())) + { + CodedInputStream ci = CodedInputStream.CreateInstance(ms); + copy = copy.ToBuilder().MergeFrom(ci).Build(); + } + + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestIBuilderLiteWeakClear() + { + TestAllTypesLite copy, msg = TestAllTypesLite.DefaultInstance; + + copy = msg.ToBuilder().SetOptionalString("Should be removed.").Build(); + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + copy = (TestAllTypesLite) ((IBuilderLite) copy.ToBuilder()).WeakClear().WeakBuild(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestBuilderLiteMergeFromCodedInputStream() + { + TestAllTypesLite copy, + msg = TestAllTypesLite.CreateBuilder() + .SetOptionalString("Should be merged.").Build(); + + copy = TestAllTypesLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + copy = + copy.ToBuilder().MergeFrom(CodedInputStream.CreateInstance(new MemoryStream(msg.ToByteArray()))).Build(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestBuilderLiteMergeDelimitedFrom() + { + TestAllTypesLite copy, + msg = TestAllTypesLite.CreateBuilder() + .SetOptionalString("Should be merged.").Build(); + + copy = TestAllTypesLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + Stream s = new MemoryStream(); + msg.WriteDelimitedTo(s); + s.Position = 0; + copy = copy.ToBuilder().MergeDelimitedFrom(s).Build(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestBuilderLiteMergeDelimitedFromExtensions() + { + TestAllExtensionsLite copy, + msg = TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, + "Should be merged.").Build(); + + copy = TestAllExtensionsLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + Stream s = new MemoryStream(); + msg.WriteDelimitedTo(s); + s.Position = 0; + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestLiteProtoFile.RegisterAllExtensions(registry); + + copy = copy.ToBuilder().MergeDelimitedFrom(s, registry).Build(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite)); + } + + [Test] + public void TestBuilderLiteMergeFromStream() + { + TestAllTypesLite copy, + msg = TestAllTypesLite.CreateBuilder() + .SetOptionalString("Should be merged.").Build(); + + copy = TestAllTypesLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + Stream s = new MemoryStream(); + msg.WriteTo(s); + s.Position = 0; + copy = copy.ToBuilder().MergeFrom(s).Build(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestBuilderLiteMergeFromStreamExtensions() + { + TestAllExtensionsLite copy, + msg = TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, + "Should be merged.").Build(); + + copy = TestAllExtensionsLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + Stream s = new MemoryStream(); + msg.WriteTo(s); + s.Position = 0; + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestLiteProtoFile.RegisterAllExtensions(registry); + + copy = copy.ToBuilder().MergeFrom(s, registry).Build(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite)); + } + + [Test] + public void TestIBuilderLiteWeakMergeFromIMessageLite() + { + TestAllTypesLite copy, + msg = TestAllTypesLite.CreateBuilder() + .SetOptionalString("Should be merged.").Build(); + + copy = TestAllTypesLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + copy = (TestAllTypesLite) ((IBuilderLite) copy.ToBuilder()).WeakMergeFrom((IMessageLite) msg).WeakBuild(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestIBuilderLiteWeakMergeFromByteString() + { + TestAllTypesLite copy, + msg = TestAllTypesLite.CreateBuilder() + .SetOptionalString("Should be merged.").Build(); + + copy = TestAllTypesLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + copy = (TestAllTypesLite) ((IBuilderLite) copy.ToBuilder()).WeakMergeFrom(msg.ToByteString()).WeakBuild(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestIBuilderLiteWeakMergeFromByteStringExtensions() + { + TestAllExtensionsLite copy, + msg = TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, + "Should be merged.").Build(); + + copy = TestAllExtensionsLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + copy = + (TestAllExtensionsLite) + ((IBuilderLite) copy.ToBuilder()).WeakMergeFrom(msg.ToByteString(), ExtensionRegistry.Empty).WeakBuild(); + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestLiteProtoFile.RegisterAllExtensions(registry); + + copy = + (TestAllExtensionsLite) + ((IBuilderLite) copy.ToBuilder()).WeakMergeFrom(msg.ToByteString(), registry).WeakBuild(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + Assert.AreEqual("Should be merged.", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite)); + } + + [Test] + public void TestIBuilderLiteWeakMergeFromCodedInputStream() + { + TestAllTypesLite copy, + msg = TestAllTypesLite.CreateBuilder() + .SetOptionalUint32(uint.MaxValue).Build(); + + copy = TestAllTypesLite.DefaultInstance; + Assert.AreNotEqual(msg.ToByteArray(), copy.ToByteArray()); + + using (MemoryStream ms = new MemoryStream(msg.ToByteArray())) + { + CodedInputStream ci = CodedInputStream.CreateInstance(ms); + copy = (TestAllTypesLite) ((IBuilderLite) copy.ToBuilder()).WeakMergeFrom(ci).WeakBuild(); + } + + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestIBuilderLiteWeakBuildPartial() + { + IBuilderLite builder = TestRequiredLite.CreateBuilder(); + Assert.IsFalse(builder.IsInitialized); + + IMessageLite msg = builder.WeakBuildPartial(); + Assert.IsFalse(msg.IsInitialized); + + Assert.AreEqual(msg.ToByteArray(), TestRequiredLite.DefaultInstance.ToByteArray()); + } + + [Test, ExpectedException(typeof (UninitializedMessageException))] + public void TestIBuilderLiteWeakBuildUninitialized() + { + IBuilderLite builder = TestRequiredLite.CreateBuilder(); + Assert.IsFalse(builder.IsInitialized); + builder.WeakBuild(); + } + + [Test] + public void TestIBuilderLiteWeakBuild() + { + IBuilderLite builder = TestRequiredLite.CreateBuilder() + .SetD(0) + .SetEn(ExtraEnum.EXLITE_BAZ); + Assert.IsTrue(builder.IsInitialized); + builder.WeakBuild(); + } + + [Test] + public void TestIBuilderLiteWeakClone() + { + TestRequiredLite msg = TestRequiredLite.CreateBuilder() + .SetD(1).SetEn(ExtraEnum.EXLITE_BAR).Build(); + Assert.IsTrue(msg.IsInitialized); + + IMessageLite copy = ((IBuilderLite) msg.ToBuilder()).WeakClone().WeakBuild(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestIBuilderLiteWeakDefaultInstance() + { + Assert.IsTrue(ReferenceEquals(TestRequiredLite.DefaultInstance, + ((IBuilderLite) TestRequiredLite.CreateBuilder()).WeakDefaultInstanceForType)); + } + + [Test] + public void TestGeneratedBuilderLiteAddRange() + { + TestAllTypesLite copy, + msg = TestAllTypesLite.CreateBuilder() + .SetOptionalUint32(123) + .AddRepeatedInt32(1) + .AddRepeatedInt32(2) + .AddRepeatedInt32(3) + .Build(); + + copy = msg.DefaultInstanceForType.ToBuilder().MergeFrom(msg).Build(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffersLite.Test/AbstractMessageLiteTest.cs b/src/ProtocolBuffersLite.Test/AbstractMessageLiteTest.cs index 0391308b..5ef9636d 100644 --- a/src/ProtocolBuffersLite.Test/AbstractMessageLiteTest.cs +++ b/src/ProtocolBuffersLite.Test/AbstractMessageLiteTest.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; @@ -39,88 +41,96 @@ using Google.ProtocolBuffers; using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; -namespace Google.ProtocolBuffers { - [TestFixture] - public class AbstractMessageLiteTest { - - [Test] - public void TestMessageLiteToByteString() { - TestRequiredLite msg = TestRequiredLite.CreateBuilder() - .SetD(42) - .SetEn(ExtraEnum.EXLITE_BAZ) - .Build(); - - ByteString b = msg.ToByteString(); - Assert.AreEqual(4, b.Length); - Assert.AreEqual(TestRequiredLite.DFieldNumber << 3, b[0]); - Assert.AreEqual(42, b[1]); - Assert.AreEqual(TestRequiredLite.EnFieldNumber << 3, b[2]); - Assert.AreEqual((int)ExtraEnum.EXLITE_BAZ, b[3]); - } +namespace Google.ProtocolBuffers +{ + [TestFixture] + public class AbstractMessageLiteTest + { + [Test] + public void TestMessageLiteToByteString() + { + TestRequiredLite msg = TestRequiredLite.CreateBuilder() + .SetD(42) + .SetEn(ExtraEnum.EXLITE_BAZ) + .Build(); - [Test] - public void TestMessageLiteToByteArray() { - TestRequiredLite msg = TestRequiredLite.CreateBuilder() - .SetD(42) - .SetEn(ExtraEnum.EXLITE_BAZ) - .Build(); + ByteString b = msg.ToByteString(); + Assert.AreEqual(4, b.Length); + Assert.AreEqual(TestRequiredLite.DFieldNumber << 3, b[0]); + Assert.AreEqual(42, b[1]); + Assert.AreEqual(TestRequiredLite.EnFieldNumber << 3, b[2]); + Assert.AreEqual((int) ExtraEnum.EXLITE_BAZ, b[3]); + } - ByteString b = msg.ToByteString(); - ByteString copy = ByteString.CopyFrom(msg.ToByteArray()); - Assert.AreEqual(b, copy); - } + [Test] + public void TestMessageLiteToByteArray() + { + TestRequiredLite msg = TestRequiredLite.CreateBuilder() + .SetD(42) + .SetEn(ExtraEnum.EXLITE_BAZ) + .Build(); - [Test] - public void TestMessageLiteWriteTo() { - TestRequiredLite msg = TestRequiredLite.CreateBuilder() - .SetD(42) - .SetEn(ExtraEnum.EXLITE_BAZ) - .Build(); + ByteString b = msg.ToByteString(); + ByteString copy = ByteString.CopyFrom(msg.ToByteArray()); + Assert.AreEqual(b, copy); + } - MemoryStream ms = new MemoryStream(); - msg.WriteTo(ms); - Assert.AreEqual(msg.ToByteArray(), ms.ToArray()); - } + [Test] + public void TestMessageLiteWriteTo() + { + TestRequiredLite msg = TestRequiredLite.CreateBuilder() + .SetD(42) + .SetEn(ExtraEnum.EXLITE_BAZ) + .Build(); - [Test] - public void TestMessageLiteWriteDelimitedTo() { - TestRequiredLite msg = TestRequiredLite.CreateBuilder() - .SetD(42) - .SetEn(ExtraEnum.EXLITE_BAZ) - .Build(); - - MemoryStream ms = new MemoryStream(); - msg.WriteDelimitedTo(ms); - byte[] buffer = ms.ToArray(); - - Assert.AreEqual(5, buffer.Length); - Assert.AreEqual(4, buffer[0]); - byte[] msgBytes = new byte[4]; - Array.Copy(buffer, 1, msgBytes, 0, 4); - Assert.AreEqual(msg.ToByteArray(), msgBytes); - } + MemoryStream ms = new MemoryStream(); + msg.WriteTo(ms); + Assert.AreEqual(msg.ToByteArray(), ms.ToArray()); + } - [Test] - public void TestIMessageLiteWeakCreateBuilderForType() { - IMessageLite msg = TestRequiredLite.DefaultInstance; - Assert.AreEqual(typeof(TestRequiredLite.Builder), msg.WeakCreateBuilderForType().GetType()); - } + [Test] + public void TestMessageLiteWriteDelimitedTo() + { + TestRequiredLite msg = TestRequiredLite.CreateBuilder() + .SetD(42) + .SetEn(ExtraEnum.EXLITE_BAZ) + .Build(); - [Test] - public void TestMessageLiteWeakToBuilder() { - IMessageLite msg = TestRequiredLite.CreateBuilder() - .SetD(42) - .SetEn(ExtraEnum.EXLITE_BAZ) - .Build(); + MemoryStream ms = new MemoryStream(); + msg.WriteDelimitedTo(ms); + byte[] buffer = ms.ToArray(); - IMessageLite copy = msg.WeakToBuilder().WeakBuild(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } + Assert.AreEqual(5, buffer.Length); + Assert.AreEqual(4, buffer[0]); + byte[] msgBytes = new byte[4]; + Array.Copy(buffer, 1, msgBytes, 0, 4); + Assert.AreEqual(msg.ToByteArray(), msgBytes); + } + + [Test] + public void TestIMessageLiteWeakCreateBuilderForType() + { + IMessageLite msg = TestRequiredLite.DefaultInstance; + Assert.AreEqual(typeof (TestRequiredLite.Builder), msg.WeakCreateBuilderForType().GetType()); + } + + [Test] + public void TestMessageLiteWeakToBuilder() + { + IMessageLite msg = TestRequiredLite.CreateBuilder() + .SetD(42) + .SetEn(ExtraEnum.EXLITE_BAZ) + .Build(); + + IMessageLite copy = msg.WeakToBuilder().WeakBuild(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } - [Test] - public void TestMessageLiteWeakDefaultInstanceForType() { - IMessageLite msg = TestRequiredLite.DefaultInstance; - Assert.IsTrue(Object.ReferenceEquals(TestRequiredLite.DefaultInstance, msg.WeakDefaultInstanceForType)); + [Test] + public void TestMessageLiteWeakDefaultInstanceForType() + { + IMessageLite msg = TestRequiredLite.DefaultInstance; + Assert.IsTrue(Object.ReferenceEquals(TestRequiredLite.DefaultInstance, msg.WeakDefaultInstanceForType)); + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffersLite.Test/ExtendableBuilderLiteTest.cs b/src/ProtocolBuffersLite.Test/ExtendableBuilderLiteTest.cs index f4e7fccc..75580473 100644 --- a/src/ProtocolBuffersLite.Test/ExtendableBuilderLiteTest.cs +++ b/src/ProtocolBuffersLite.Test/ExtendableBuilderLiteTest.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; @@ -39,229 +41,249 @@ using Google.ProtocolBuffers; using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; -namespace Google.ProtocolBuffers { - [TestFixture] - public class ExtendableBuilderLiteTest { - - [Test] - public void TestHasExtensionT() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123); - - Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - } - - [Test] - public void TestHasExtensionTMissing() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - } - - [Test] - public void TestGetExtensionCountT() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 3); - - Assert.AreEqual(3, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - } - - [Test] - public void TestGetExtensionCountTEmpty() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - } - - [Test] - public void TestGetExtensionTNull() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - string value = builder.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite); - Assert.IsNull(value); - } - - [Test] - public void TestGetExtensionTValue() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 3); - - Assert.AreEqual(3, builder.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - } - - [Test] - public void TestGetExtensionTEmpty() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - Assert.AreEqual(0, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite).Count); - } - - [Test] - public void TestGetExtensionTList() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 3); - - IList values = builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite); - Assert.AreEqual(3, values.Count); - } - - [Test] - public void TestGetExtensionTIndex() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2); - - for(int i = 0; i < 3; i++ ) - Assert.AreEqual(i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i)); - } - - [Test,ExpectedException(typeof(ArgumentOutOfRangeException))] - public void TestGetExtensionTIndexOutOfRange() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); - } - - [Test] - public void TestSetExtensionTIndex() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2); - - for (int i = 0; i < 3; i++) - Assert.AreEqual(i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i)); - - builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0, 5); - builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1, 6); - builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2, 7); - - for (int i = 0; i < 3; i++) - Assert.AreEqual(5 + i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i)); - } - - [Test, ExpectedException(typeof(ArgumentOutOfRangeException))] - public void TestSetExtensionTIndexOutOfRange() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0, -1); - } - - [Test] - public void TestClearExtensionTList() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); - Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - - builder.ClearExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite); - Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - } - - [Test] - public void TestClearExtensionTValue() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 0); - Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - - builder.ClearExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite); - Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - } - - [Test] - public void TestIndexedByDescriptor() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - - builder[UnitTestLiteProtoFile.OptionalInt32ExtensionLite.Descriptor] = 123; - - Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - } - - [Test] - public void TestIndexedByDescriptorAndOrdinal() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); - Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - - IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor; - builder[f, 0] = 123; - - Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0)); - } - - [Test, ExpectedException(typeof(ArgumentOutOfRangeException))] - public void TestIndexedByDescriptorAndOrdinalOutOfRange() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - - IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor; - builder[f, 0] = 123; - } - - [Test] - public void TestClearFieldByDescriptor() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); - Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - - IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor; - builder.ClearField(f); - Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - } - - [Test] - public void TestAddRepeatedFieldByDescriptor() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); - Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - - IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor; - builder.AddRepeatedField(f, 123); - Assert.AreEqual(2, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); - Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)); - } - - [Test] - public void TestMissingExtensionsLite() - { - const int optionalInt32 = 12345678; - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); - builder.SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, optionalInt32); - builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.1); - builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.2); - builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.3); - TestAllExtensionsLite msg = builder.Build(); - - Assert.IsTrue(msg.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - Assert.AreEqual(3, msg.GetExtensionCount(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite)); - - byte[] bits = msg.ToByteArray(); - TestAllExtensionsLite copy = TestAllExtensionsLite.ParseFrom(bits); - Assert.IsFalse(copy.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - Assert.AreEqual(0, copy.GetExtensionCount(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite)); - Assert.AreNotEqual(msg, copy); - - //The lite runtime removes all unknown fields and extensions - byte[] copybits = copy.ToByteArray(); - Assert.AreEqual(0, copybits.Length); - } - - [Test] - public void TestMissingFieldsLite() +namespace Google.ProtocolBuffers +{ + [TestFixture] + public class ExtendableBuilderLiteTest { - TestAllTypesLite msg = TestAllTypesLite.CreateBuilder() - .SetOptionalInt32(123) - .SetOptionalString("123") - .Build(); - - byte[] bits = msg.ToByteArray(); - TestAllExtensionsLite copy = TestAllExtensionsLite.ParseFrom(bits); - Assert.AreNotEqual(msg, copy); - - //The lite runtime removes all unknown fields and extensions - byte[] copybits = copy.ToByteArray(); - Assert.AreEqual(0, copybits.Length); + [Test] + public void TestHasExtensionT() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123); + + Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + } + + [Test] + public void TestHasExtensionTMissing() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + } + + [Test] + public void TestGetExtensionCountT() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 3); + + Assert.AreEqual(3, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + } + + [Test] + public void TestGetExtensionCountTEmpty() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + } + + [Test] + public void TestGetExtensionTNull() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + string value = builder.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite); + Assert.IsNull(value); + } + + [Test] + public void TestGetExtensionTValue() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 3); + + Assert.AreEqual(3, builder.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + } + + [Test] + public void TestGetExtensionTEmpty() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + Assert.AreEqual(0, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite).Count); + } + + [Test] + public void TestGetExtensionTList() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 3); + + IList values = builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite); + Assert.AreEqual(3, values.Count); + } + + [Test] + public void TestGetExtensionTIndex() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2); + + for (int i = 0; i < 3; i++) + Assert.AreEqual(i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i)); + } + + [Test, ExpectedException(typeof (ArgumentOutOfRangeException))] + public void TestGetExtensionTIndexOutOfRange() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); + } + + [Test] + public void TestSetExtensionTIndex() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2); + + for (int i = 0; i < 3; i++) + Assert.AreEqual(i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i)); + + builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0, 5); + builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1, 6); + builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 2, 7); + + for (int i = 0; i < 3; i++) + Assert.AreEqual(5 + i, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, i)); + } + + [Test, ExpectedException(typeof (ArgumentOutOfRangeException))] + public void TestSetExtensionTIndexOutOfRange() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + builder.SetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0, -1); + } + + [Test] + public void TestClearExtensionTList() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); + Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + + builder.ClearExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite); + Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + } + + [Test] + public void TestClearExtensionTValue() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 0); + Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + + builder.ClearExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite); + Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + } + + [Test] + public void TestIndexedByDescriptor() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + Assert.IsFalse(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + + builder[UnitTestLiteProtoFile.OptionalInt32ExtensionLite.Descriptor] = 123; + + Assert.IsTrue(builder.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + } + + [Test] + public void TestIndexedByDescriptorAndOrdinal() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); + Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + + IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor; + builder[f, 0] = 123; + + Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0)); + } + + [Test, ExpectedException(typeof (ArgumentOutOfRangeException))] + public void TestIndexedByDescriptorAndOrdinalOutOfRange() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + + IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor; + builder[f, 0] = 123; + } + + [Test] + public void TestClearFieldByDescriptor() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); + Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + + IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor; + builder.ClearField(f); + Assert.AreEqual(0, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + } + + [Test] + public void TestAddRepeatedFieldByDescriptor() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0); + Assert.AreEqual(1, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + + IFieldDescriptorLite f = UnitTestLiteProtoFile.RepeatedInt32ExtensionLite.Descriptor; + builder.AddRepeatedField(f, 123); + Assert.AreEqual(2, builder.GetExtensionCount(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite)); + Assert.AreEqual(123, builder.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 1)); + } + + [Test] + public void TestMissingExtensionsLite() + { + const int optionalInt32 = 12345678; + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder(); + builder.SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, optionalInt32); + builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.1); + builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.2); + builder.AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 1.3); + TestAllExtensionsLite msg = builder.Build(); + + Assert.IsTrue(msg.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + Assert.AreEqual(3, msg.GetExtensionCount(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite)); + + byte[] bits = msg.ToByteArray(); + TestAllExtensionsLite copy = TestAllExtensionsLite.ParseFrom(bits); + Assert.IsFalse(copy.HasExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + Assert.AreEqual(0, copy.GetExtensionCount(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite)); + Assert.AreNotEqual(msg, copy); + + //The lite runtime removes all unknown fields and extensions + byte[] copybits = copy.ToByteArray(); + Assert.AreEqual(0, copybits.Length); + } + + [Test] + public void TestMissingFieldsLite() + { + TestAllTypesLite msg = TestAllTypesLite.CreateBuilder() + .SetOptionalInt32(123) + .SetOptionalString("123") + .Build(); + + byte[] bits = msg.ToByteArray(); + TestAllExtensionsLite copy = TestAllExtensionsLite.ParseFrom(bits); + Assert.AreNotEqual(msg, copy); + + //The lite runtime removes all unknown fields and extensions + byte[] copybits = copy.ToByteArray(); + Assert.AreEqual(0, copybits.Length); + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffersLite.Test/ExtendableMessageLiteTest.cs b/src/ProtocolBuffersLite.Test/ExtendableMessageLiteTest.cs index 05ad064e..399e3082 100644 --- a/src/ProtocolBuffersLite.Test/ExtendableMessageLiteTest.cs +++ b/src/ProtocolBuffersLite.Test/ExtendableMessageLiteTest.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; @@ -39,266 +41,292 @@ using Google.ProtocolBuffers; using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; -namespace Google.ProtocolBuffers { - [TestFixture] - public class ExtendableMessageLiteTest { - - [Test, Ignore("Not implemented, no assertion made"), ExpectedException(typeof(ArgumentException))] - public void ExtensionWriterInvalidExtension() { - TestPackedExtensionsLite.CreateBuilder()[UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite.Descriptor] = - ForeignMessageLite.DefaultInstance; - } - - [Test] - public void ExtensionWriterTestMessages() { - TestAllExtensionsLite.Builder b = TestAllExtensionsLite.CreateBuilder().SetExtension( - UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite, ForeignMessageLite.CreateBuilder().SetC(123).Build()); - TestAllExtensionsLite copy, msg = b.Build(); +namespace Google.ProtocolBuffers +{ + [TestFixture] + public class ExtendableMessageLiteTest + { + [Test, Ignore("Not implemented, no assertion made"), ExpectedException(typeof (ArgumentException))] + public void ExtensionWriterInvalidExtension() + { + TestPackedExtensionsLite.CreateBuilder()[ + UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite.Descriptor] = + ForeignMessageLite.DefaultInstance; + } - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestLiteProtoFile.RegisterAllExtensions(registry); + [Test] + public void ExtensionWriterTestMessages() + { + TestAllExtensionsLite.Builder b = TestAllExtensionsLite.CreateBuilder().SetExtension( + UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite, + ForeignMessageLite.CreateBuilder().SetC(123).Build()); + TestAllExtensionsLite copy, msg = b.Build(); - copy = TestAllExtensionsLite.ParseFrom(msg.ToByteArray(), registry); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestLiteProtoFile.RegisterAllExtensions(registry); - [Test] - public void ExtensionWriterIsInitialized() { - Assert.IsTrue(ForeignMessageLite.DefaultInstance.IsInitialized); - Assert.IsTrue(TestPackedExtensionsLite.CreateBuilder().IsInitialized); - Assert.IsTrue(TestAllExtensionsLite.CreateBuilder().SetExtension( - UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite, ForeignMessageLite.DefaultInstance) - .IsInitialized); - } + copy = TestAllExtensionsLite.ParseFrom(msg.ToByteArray(), registry); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } - [Test] - public void ExtensionWriterTestSetExtensionLists() { - TestAllExtensionsLite msg, copy; - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, new[] { true, false }) - .SetExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, new[] { "123", "456" }) - .SetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, new[] { ForeignEnumLite.FOREIGN_LITE_BAZ, ForeignEnumLite.FOREIGN_LITE_FOO }) - ; + [Test] + public void ExtensionWriterIsInitialized() + { + Assert.IsTrue(ForeignMessageLite.DefaultInstance.IsInitialized); + Assert.IsTrue(TestPackedExtensionsLite.CreateBuilder().IsInitialized); + Assert.IsTrue(TestAllExtensionsLite.CreateBuilder().SetExtension( + UnitTestLiteProtoFile.OptionalForeignMessageExtensionLite, ForeignMessageLite.DefaultInstance) + .IsInitialized); + } - msg = builder.Build(); - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestLiteProtoFile.RegisterAllExtensions(registry); + [Test] + public void ExtensionWriterTestSetExtensionLists() + { + TestAllExtensionsLite msg, copy; + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, new[] {true, false}) + .SetExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, new[] {"123", "456"}) + .SetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, + new[] {ForeignEnumLite.FOREIGN_LITE_BAZ, ForeignEnumLite.FOREIGN_LITE_FOO}) + ; - copy = TestAllExtensionsLite.ParseFrom(msg.ToByteArray(), registry); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + msg = builder.Build(); + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestLiteProtoFile.RegisterAllExtensions(registry); - Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_FOO, copy.GetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, 1)); - } + copy = TestAllExtensionsLite.ParseFrom(msg.ToByteArray(), registry); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - [Test] - public void ExtensionWriterTest() { - TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.DefaultBoolExtensionLite, true) - .SetExtension(UnitTestLiteProtoFile.DefaultBytesExtensionLite, ByteString.CopyFromUtf8("123")) - .SetExtension(UnitTestLiteProtoFile.DefaultCordExtensionLite, "123") - .SetExtension(UnitTestLiteProtoFile.DefaultDoubleExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.DefaultFixed32ExtensionLite, 123u) - .SetExtension(UnitTestLiteProtoFile.DefaultFixed64ExtensionLite, 123u) - .SetExtension(UnitTestLiteProtoFile.DefaultFloatExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.DefaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ) - .SetExtension(UnitTestLiteProtoFile.DefaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ) - .SetExtension(UnitTestLiteProtoFile.DefaultInt32ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.DefaultInt64ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.DefaultNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO) - .SetExtension(UnitTestLiteProtoFile.DefaultSfixed32ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.DefaultSfixed64ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.DefaultSint32ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.DefaultSint64ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.DefaultStringExtensionLite, "123") - .SetExtension(UnitTestLiteProtoFile.DefaultStringPieceExtensionLite, "123") - .SetExtension(UnitTestLiteProtoFile.DefaultUint32ExtensionLite, 123u) - .SetExtension(UnitTestLiteProtoFile.DefaultUint64ExtensionLite, 123u) - //Optional - .SetExtension(UnitTestLiteProtoFile.OptionalBoolExtensionLite, true) - .SetExtension(UnitTestLiteProtoFile.OptionalBytesExtensionLite, ByteString.CopyFromUtf8("123")) - .SetExtension(UnitTestLiteProtoFile.OptionalCordExtensionLite, "123") - .SetExtension(UnitTestLiteProtoFile.OptionalDoubleExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.OptionalFixed32ExtensionLite, 123u) - .SetExtension(UnitTestLiteProtoFile.OptionalFixed64ExtensionLite, 123u) - .SetExtension(UnitTestLiteProtoFile.OptionalFloatExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.OptionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ) - .SetExtension(UnitTestLiteProtoFile.OptionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ) - .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.OptionalInt64ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO) - .SetExtension(UnitTestLiteProtoFile.OptionalSfixed32ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.OptionalSfixed64ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.OptionalSint32ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.OptionalSint64ExtensionLite, 123) - .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "123") - .SetExtension(UnitTestLiteProtoFile.OptionalStringPieceExtensionLite, "123") - .SetExtension(UnitTestLiteProtoFile.OptionalUint32ExtensionLite, 123u) - .SetExtension(UnitTestLiteProtoFile.OptionalUint64ExtensionLite, 123u) - //Repeated - .AddExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, true) - .AddExtension(UnitTestLiteProtoFile.RepeatedBytesExtensionLite, ByteString.CopyFromUtf8("123")) - .AddExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, "123") - .AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedFixed32ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.RepeatedFixed64ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.RepeatedFloatExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ) - .AddExtension(UnitTestLiteProtoFile.RepeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedInt64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedNestedEnumExtensionLite, TestAllTypesLite.Types.NestedEnum.FOO) - .AddExtension(UnitTestLiteProtoFile.RepeatedSfixed32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedSfixed64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedSint32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedSint64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, "123") - .AddExtension(UnitTestLiteProtoFile.RepeatedStringPieceExtensionLite, "123") - .AddExtension(UnitTestLiteProtoFile.RepeatedUint32ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.RepeatedUint64ExtensionLite, 123u) - ; - TestAllExtensionsLite msg = builder.Build(); + Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_FOO, + copy.GetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, 1)); + } - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestLiteProtoFile.RegisterAllExtensions(registry); + [Test] + public void ExtensionWriterTest() + { + TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.DefaultBoolExtensionLite, true) + .SetExtension(UnitTestLiteProtoFile.DefaultBytesExtensionLite, ByteString.CopyFromUtf8("123")) + .SetExtension(UnitTestLiteProtoFile.DefaultCordExtensionLite, "123") + .SetExtension(UnitTestLiteProtoFile.DefaultDoubleExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.DefaultFixed32ExtensionLite, 123u) + .SetExtension(UnitTestLiteProtoFile.DefaultFixed64ExtensionLite, 123u) + .SetExtension(UnitTestLiteProtoFile.DefaultFloatExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.DefaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ) + .SetExtension(UnitTestLiteProtoFile.DefaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ) + .SetExtension(UnitTestLiteProtoFile.DefaultInt32ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.DefaultInt64ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.DefaultNestedEnumExtensionLite, + TestAllTypesLite.Types.NestedEnum.FOO) + .SetExtension(UnitTestLiteProtoFile.DefaultSfixed32ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.DefaultSfixed64ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.DefaultSint32ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.DefaultSint64ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.DefaultStringExtensionLite, "123") + .SetExtension(UnitTestLiteProtoFile.DefaultStringPieceExtensionLite, "123") + .SetExtension(UnitTestLiteProtoFile.DefaultUint32ExtensionLite, 123u) + .SetExtension(UnitTestLiteProtoFile.DefaultUint64ExtensionLite, 123u) + //Optional + .SetExtension(UnitTestLiteProtoFile.OptionalBoolExtensionLite, true) + .SetExtension(UnitTestLiteProtoFile.OptionalBytesExtensionLite, ByteString.CopyFromUtf8("123")) + .SetExtension(UnitTestLiteProtoFile.OptionalCordExtensionLite, "123") + .SetExtension(UnitTestLiteProtoFile.OptionalDoubleExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.OptionalFixed32ExtensionLite, 123u) + .SetExtension(UnitTestLiteProtoFile.OptionalFixed64ExtensionLite, 123u) + .SetExtension(UnitTestLiteProtoFile.OptionalFloatExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.OptionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ) + .SetExtension(UnitTestLiteProtoFile.OptionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ) + .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.OptionalInt64ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite, + TestAllTypesLite.Types.NestedEnum.FOO) + .SetExtension(UnitTestLiteProtoFile.OptionalSfixed32ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.OptionalSfixed64ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.OptionalSint32ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.OptionalSint64ExtensionLite, 123) + .SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "123") + .SetExtension(UnitTestLiteProtoFile.OptionalStringPieceExtensionLite, "123") + .SetExtension(UnitTestLiteProtoFile.OptionalUint32ExtensionLite, 123u) + .SetExtension(UnitTestLiteProtoFile.OptionalUint64ExtensionLite, 123u) + //Repeated + .AddExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, true) + .AddExtension(UnitTestLiteProtoFile.RepeatedBytesExtensionLite, ByteString.CopyFromUtf8("123")) + .AddExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, "123") + .AddExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedFixed32ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.RepeatedFixed64ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.RepeatedFloatExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ) + .AddExtension(UnitTestLiteProtoFile.RepeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedInt64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedNestedEnumExtensionLite, + TestAllTypesLite.Types.NestedEnum.FOO) + .AddExtension(UnitTestLiteProtoFile.RepeatedSfixed32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedSfixed64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedSint32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedSint64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, "123") + .AddExtension(UnitTestLiteProtoFile.RepeatedStringPieceExtensionLite, "123") + .AddExtension(UnitTestLiteProtoFile.RepeatedUint32ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.RepeatedUint64ExtensionLite, 123u) + ; + TestAllExtensionsLite msg = builder.Build(); - TestAllExtensionsLite.Builder copyBuilder = TestAllExtensionsLite.CreateBuilder().MergeFrom(msg.ToByteArray(), registry); - TestAllExtensionsLite copy = copyBuilder.Build(); + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestLiteProtoFile.RegisterAllExtensions(registry); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + TestAllExtensionsLite.Builder copyBuilder = + TestAllExtensionsLite.CreateBuilder().MergeFrom(msg.ToByteArray(), registry); + TestAllExtensionsLite copy = copyBuilder.Build(); - Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.DefaultBoolExtensionLite)); - Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.DefaultBytesExtensionLite)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultCordExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultDoubleExtensionLite)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultFixed32ExtensionLite)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultFixed64ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultFloatExtensionLite)); - Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.DefaultForeignEnumExtensionLite)); - Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.DefaultImportEnumExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultInt32ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultInt64ExtensionLite)); - Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.DefaultNestedEnumExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSfixed32ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSfixed64ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSint32ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSint64ExtensionLite)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultStringExtensionLite)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultStringPieceExtensionLite)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultUint32ExtensionLite)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultUint64ExtensionLite)); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.OptionalBoolExtensionLite)); - Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.OptionalBytesExtensionLite)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalCordExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalDoubleExtensionLite)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalFixed32ExtensionLite)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalFixed64ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalFloatExtensionLite)); - Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.OptionalForeignEnumExtensionLite)); - Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.OptionalImportEnumExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalInt64ExtensionLite)); - Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSfixed32ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSfixed64ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSint32ExtensionLite)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSint64ExtensionLite)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringPieceExtensionLite)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalUint32ExtensionLite)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalUint64ExtensionLite)); - - Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, 0)); - Assert.AreEqual(ByteString.CopyFromUtf8("123"), copy.GetExtension(UnitTestLiteProtoFile.RepeatedBytesExtensionLite, 0)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 0)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFixed32ExtensionLite, 0)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFixed64ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFloatExtensionLite, 0)); - Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, 0)); - Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, copy.GetExtension(UnitTestLiteProtoFile.RepeatedImportEnumExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedInt64ExtensionLite, 0)); - Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, copy.GetExtension(UnitTestLiteProtoFile.RepeatedNestedEnumExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSfixed32ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSfixed64ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSint32ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSint64ExtensionLite, 0)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, 0)); - Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedStringPieceExtensionLite, 0)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedUint32ExtensionLite, 0)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedUint64ExtensionLite, 0)); - } + Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.DefaultBoolExtensionLite)); + Assert.AreEqual(ByteString.CopyFromUtf8("123"), + copy.GetExtension(UnitTestLiteProtoFile.DefaultBytesExtensionLite)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultCordExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultDoubleExtensionLite)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultFixed32ExtensionLite)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultFixed64ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultFloatExtensionLite)); + Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, + copy.GetExtension(UnitTestLiteProtoFile.DefaultForeignEnumExtensionLite)); + Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, + copy.GetExtension(UnitTestLiteProtoFile.DefaultImportEnumExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultInt32ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultInt64ExtensionLite)); + Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, + copy.GetExtension(UnitTestLiteProtoFile.DefaultNestedEnumExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSfixed32ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSfixed64ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSint32ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.DefaultSint64ExtensionLite)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultStringExtensionLite)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.DefaultStringPieceExtensionLite)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultUint32ExtensionLite)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.DefaultUint64ExtensionLite)); - [Test] - public void ExtensionWriterTestPacked() { + Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.OptionalBoolExtensionLite)); + Assert.AreEqual(ByteString.CopyFromUtf8("123"), + copy.GetExtension(UnitTestLiteProtoFile.OptionalBytesExtensionLite)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalCordExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalDoubleExtensionLite)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalFixed32ExtensionLite)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalFixed64ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalFloatExtensionLite)); + Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, + copy.GetExtension(UnitTestLiteProtoFile.OptionalForeignEnumExtensionLite)); + Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, + copy.GetExtension(UnitTestLiteProtoFile.OptionalImportEnumExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalInt64ExtensionLite)); + Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, + copy.GetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSfixed32ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSfixed64ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSint32ExtensionLite)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.OptionalSint64ExtensionLite)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.OptionalStringPieceExtensionLite)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalUint32ExtensionLite)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.OptionalUint64ExtensionLite)); - TestPackedExtensionsLite.Builder builder = TestPackedExtensionsLite.CreateBuilder() - .AddExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, true) - .AddExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, true) - .AddExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 123u) - .AddExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 123u); + Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.RepeatedBoolExtensionLite, 0)); + Assert.AreEqual(ByteString.CopyFromUtf8("123"), + copy.GetExtension(UnitTestLiteProtoFile.RepeatedBytesExtensionLite, 0)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedCordExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedDoubleExtensionLite, 0)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFixed32ExtensionLite, 0)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFixed64ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedFloatExtensionLite, 0)); + Assert.AreEqual(ForeignEnumLite.FOREIGN_LITE_BAZ, + copy.GetExtension(UnitTestLiteProtoFile.RepeatedForeignEnumExtensionLite, 0)); + Assert.AreEqual(ImportEnumLite.IMPORT_LITE_BAZ, + copy.GetExtension(UnitTestLiteProtoFile.RepeatedImportEnumExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedInt32ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedInt64ExtensionLite, 0)); + Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.FOO, + copy.GetExtension(UnitTestLiteProtoFile.RepeatedNestedEnumExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSfixed32ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSfixed64ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSint32ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.RepeatedSint64ExtensionLite, 0)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, 0)); + Assert.AreEqual("123", copy.GetExtension(UnitTestLiteProtoFile.RepeatedStringPieceExtensionLite, 0)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedUint32ExtensionLite, 0)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.RepeatedUint64ExtensionLite, 0)); + } - TestPackedExtensionsLite msg = builder.Build(); + [Test] + public void ExtensionWriterTestPacked() + { + TestPackedExtensionsLite.Builder builder = TestPackedExtensionsLite.CreateBuilder() + .AddExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, true) + .AddExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, true) + .AddExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 123u) + .AddExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 123u); - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestLiteProtoFile.RegisterAllExtensions(registry); + TestPackedExtensionsLite msg = builder.Build(); - TestPackedExtensionsLite.Builder copyBuilder = TestPackedExtensionsLite.CreateBuilder().MergeFrom(msg.ToByteArray(), registry); - TestPackedExtensionsLite copy = copyBuilder.Build(); + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestLiteProtoFile.RegisterAllExtensions(registry); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + TestPackedExtensionsLite.Builder copyBuilder = + TestPackedExtensionsLite.CreateBuilder().MergeFrom(msg.ToByteArray(), registry); + TestPackedExtensionsLite copy = copyBuilder.Build(); - Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 0)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 0)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 0)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 0)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 0)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 0)); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, 1)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 1)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 1)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 1)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 1)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 1)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 1)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 1)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 1)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 1)); - Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 1)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 1)); - Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 1)); + Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 0)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 0)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 0)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 0)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 0)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 0)); + Assert.AreEqual(true, copy.GetExtension(UnitTestLiteProtoFile.PackedBoolExtensionLite, 1)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedDoubleExtensionLite, 1)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed32ExtensionLite, 1)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedFixed64ExtensionLite, 1)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedFloatExtensionLite, 1)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt32ExtensionLite, 1)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedInt64ExtensionLite, 1)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed32ExtensionLite, 1)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSfixed64ExtensionLite, 1)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint32ExtensionLite, 1)); + Assert.AreEqual(123, copy.GetExtension(UnitTestLiteProtoFile.PackedSint64ExtensionLite, 1)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint32ExtensionLite, 1)); + Assert.AreEqual(123u, copy.GetExtension(UnitTestLiteProtoFile.PackedUint64ExtensionLite, 1)); + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffersLite.Test/InteropLiteTest.cs b/src/ProtocolBuffersLite.Test/InteropLiteTest.cs index 48537e56..c49e0350 100644 --- a/src/ProtocolBuffersLite.Test/InteropLiteTest.cs +++ b/src/ProtocolBuffersLite.Test/InteropLiteTest.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; @@ -38,125 +40,147 @@ using Google.ProtocolBuffers; using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; -namespace Google.ProtocolBuffers { - [TestFixture] - public class InteropLiteTest { - - [Test] - public void TestConvertFromFullMinimal() { - TestInteropPerson person = TestInteropPerson.CreateBuilder() - .SetId(123) - .SetName("abc") - .Build(); - Assert.IsTrue(person.IsInitialized); - - TestInteropPersonLite copy = TestInteropPersonLite.ParseFrom(person.ToByteArray()); - - Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestConvertFromFullComplete() { - TestInteropPerson person = TestInteropPerson.CreateBuilder() - .SetId(123) - .SetName("abc") - .SetEmail("abc@123.com") - .AddRangeCodes(new[] { 1, 2, 3 }) - .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build()) - .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build()) - .AddAddresses(TestInteropPerson.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build()) - .SetExtension(UnitTestExtrasFullProtoFile.EmployeeId, TestInteropEmployeeId.CreateBuilder().SetNumber("123").Build()) - .Build(); - Assert.IsTrue(person.IsInitialized); - - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestExtrasLiteProtoFile.RegisterAllExtensions(registry); - - TestInteropPersonLite copy = TestInteropPersonLite.ParseFrom(person.ToByteArray(), registry); - - Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestConvertFromLiteMinimal() { - TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder() - .SetId(123) - .SetName("abc") - .Build(); - Assert.IsTrue(person.IsInitialized); - - TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray()); - - Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); - } - - [Test] - public void TestConvertFromLiteComplete() { - TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder() - .SetId(123) - .SetName("abc") - .SetEmail("abc@123.com") - .AddRangeCodes(new[] { 1, 2, 3 }) - .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build()) - .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build()) - .AddAddresses(TestInteropPersonLite.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build()) - .SetExtension(UnitTestExtrasLiteProtoFile.EmployeeIdLite, TestInteropEmployeeIdLite.CreateBuilder().SetNumber("123").Build()) - .Build(); - Assert.IsTrue(person.IsInitialized); - - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry); - - TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray(), registry); - - Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); - } - - public ByteString AllBytes { - get { - byte[] bytes = new byte[256]; - for (int i = 0; i < bytes.Length; i++) - bytes[i] = (byte)i; - return ByteString.CopyFrom(bytes); - } - } - - [Test] - public void TestCompareStringValues() { - TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder() - .SetId(123) - .SetName("abc") - .SetEmail("abc@123.com") - .AddRangeCodes(new[] { 1, 2, 3 }) - .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build()) - .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber(System.Text.Encoding.ASCII.GetString(AllBytes.ToByteArray())).Build()) - .AddAddresses(TestInteropPersonLite.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build()) - .SetExtension(UnitTestExtrasLiteProtoFile.EmployeeIdLite, TestInteropEmployeeIdLite.CreateBuilder().SetNumber("123").Build()) - .Build(); - Assert.IsTrue(person.IsInitialized); - - ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); - UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry); - - TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray(), registry); - - Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); - - TestInteropPerson.Builder copyBuilder = TestInteropPerson.CreateBuilder(); - TextFormat.Merge(person.ToString().Replace("[protobuf_unittest_extra.employee_id_lite]", "[protobuf_unittest_extra.employee_id]"), registry, copyBuilder); - - copy = copyBuilder.Build(); - Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); - - string liteText = person.ToString().TrimEnd().Replace("\r", ""); - string fullText = copy.ToString().TrimEnd().Replace("\r", ""); - //map the extension type - liteText = liteText.Replace("[protobuf_unittest_extra.employee_id_lite]", "[protobuf_unittest_extra.employee_id]"); - //lite version does not indent - while (fullText.IndexOf("\n ") >= 0) - fullText = fullText.Replace("\n ", "\n"); - - Assert.AreEqual(fullText, liteText); +namespace Google.ProtocolBuffers +{ + [TestFixture] + public class InteropLiteTest + { + [Test] + public void TestConvertFromFullMinimal() + { + TestInteropPerson person = TestInteropPerson.CreateBuilder() + .SetId(123) + .SetName("abc") + .Build(); + Assert.IsTrue(person.IsInitialized); + + TestInteropPersonLite copy = TestInteropPersonLite.ParseFrom(person.ToByteArray()); + + Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestConvertFromFullComplete() + { + TestInteropPerson person = TestInteropPerson.CreateBuilder() + .SetId(123) + .SetName("abc") + .SetEmail("abc@123.com") + .AddRangeCodes(new[] {1, 2, 3}) + .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build()) + .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build()) + .AddAddresses( + TestInteropPerson.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland"). + SetState("NA").SetZip(12345).Build()) + .SetExtension(UnitTestExtrasFullProtoFile.EmployeeId, + TestInteropEmployeeId.CreateBuilder().SetNumber("123").Build()) + .Build(); + Assert.IsTrue(person.IsInitialized); + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestExtrasLiteProtoFile.RegisterAllExtensions(registry); + + TestInteropPersonLite copy = TestInteropPersonLite.ParseFrom(person.ToByteArray(), registry); + + Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestConvertFromLiteMinimal() + { + TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder() + .SetId(123) + .SetName("abc") + .Build(); + Assert.IsTrue(person.IsInitialized); + + TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray()); + + Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestConvertFromLiteComplete() + { + TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder() + .SetId(123) + .SetName("abc") + .SetEmail("abc@123.com") + .AddRangeCodes(new[] {1, 2, 3}) + .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build()) + .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build()) + .AddAddresses( + TestInteropPersonLite.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland") + .SetState("NA").SetZip(12345).Build()) + .SetExtension(UnitTestExtrasLiteProtoFile.EmployeeIdLite, + TestInteropEmployeeIdLite.CreateBuilder().SetNumber("123").Build()) + .Build(); + Assert.IsTrue(person.IsInitialized); + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry); + + TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray(), registry); + + Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); + } + + public ByteString AllBytes + { + get + { + byte[] bytes = new byte[256]; + for (int i = 0; i < bytes.Length; i++) + bytes[i] = (byte) i; + return ByteString.CopyFrom(bytes); + } + } + + [Test] + public void TestCompareStringValues() + { + TestInteropPersonLite person = TestInteropPersonLite.CreateBuilder() + .SetId(123) + .SetName("abc") + .SetEmail("abc@123.com") + .AddRangeCodes(new[] {1, 2, 3}) + .AddPhone(TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build()) + .AddPhone( + TestInteropPersonLite.Types.PhoneNumber.CreateBuilder().SetNumber( + System.Text.Encoding.ASCII.GetString(AllBytes.ToByteArray())).Build()) + .AddAddresses( + TestInteropPersonLite.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland") + .SetState("NA").SetZip(12345).Build()) + .SetExtension(UnitTestExtrasLiteProtoFile.EmployeeIdLite, + TestInteropEmployeeIdLite.CreateBuilder().SetNumber("123").Build()) + .Build(); + Assert.IsTrue(person.IsInitialized); + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestExtrasFullProtoFile.RegisterAllExtensions(registry); + + TestInteropPerson copy = TestInteropPerson.ParseFrom(person.ToByteArray(), registry); + + Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); + + TestInteropPerson.Builder copyBuilder = TestInteropPerson.CreateBuilder(); + TextFormat.Merge( + person.ToString().Replace("[protobuf_unittest_extra.employee_id_lite]", + "[protobuf_unittest_extra.employee_id]"), registry, copyBuilder); + + copy = copyBuilder.Build(); + Assert.AreEqual(person.ToByteArray(), copy.ToByteArray()); + + string liteText = person.ToString().TrimEnd().Replace("\r", ""); + string fullText = copy.ToString().TrimEnd().Replace("\r", ""); + //map the extension type + liteText = liteText.Replace("[protobuf_unittest_extra.employee_id_lite]", + "[protobuf_unittest_extra.employee_id]"); + //lite version does not indent + while (fullText.IndexOf("\n ") >= 0) + fullText = fullText.Replace("\n ", "\n"); + + Assert.AreEqual(fullText, liteText); + } } - } -} +} \ No newline at end of file diff --git a/src/ProtocolBuffersLite.Test/LiteTest.cs b/src/ProtocolBuffersLite.Test/LiteTest.cs index ca5c4bff..f1cb949a 100644 --- a/src/ProtocolBuffersLite.Test/LiteTest.cs +++ b/src/ProtocolBuffersLite.Test/LiteTest.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; @@ -39,74 +41,78 @@ using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; -namespace Google.ProtocolBuffers { - /// - /// Miscellaneous tests for message operations that apply to both - /// generated and dynamic messages. - /// - [TestFixture] - public class LiteTest { - [Test] - public void TestLite() { - // Since lite messages are a subset of regular messages, we can mostly - // assume that the functionality of lite messages is already thoroughly - // tested by the regular tests. All this test really verifies is that - // a proto with optimize_for = LITE_RUNTIME compiles correctly when - // linked only against the lite library. That is all tested at compile - // time, leaving not much to do in this method. Let's just do some random - // stuff to make sure the lite message is actually here and usable. +namespace Google.ProtocolBuffers +{ + /// + /// Miscellaneous tests for message operations that apply to both + /// generated and dynamic messages. + /// + [TestFixture] + public class LiteTest + { + [Test] + public void TestLite() + { + // Since lite messages are a subset of regular messages, we can mostly + // assume that the functionality of lite messages is already thoroughly + // tested by the regular tests. All this test really verifies is that + // a proto with optimize_for = LITE_RUNTIME compiles correctly when + // linked only against the lite library. That is all tested at compile + // time, leaving not much to do in this method. Let's just do some random + // stuff to make sure the lite message is actually here and usable. - TestAllTypesLite message = - TestAllTypesLite.CreateBuilder() - .SetOptionalInt32(123) - .AddRepeatedString("hello") - .SetOptionalNestedMessage( - TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7)) - .Build(); + TestAllTypesLite message = + TestAllTypesLite.CreateBuilder() + .SetOptionalInt32(123) + .AddRepeatedString("hello") + .SetOptionalNestedMessage( + TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7)) + .Build(); - ByteString data = message.ToByteString(); + ByteString data = message.ToByteString(); - TestAllTypesLite message2 = TestAllTypesLite.ParseFrom(data); + TestAllTypesLite message2 = TestAllTypesLite.ParseFrom(data); - Assert.AreEqual(123, message2.OptionalInt32); - Assert.AreEqual(1, message2.RepeatedStringCount); - Assert.AreEqual("hello", message2.RepeatedStringList[0]); - Assert.AreEqual(7, message2.OptionalNestedMessage.Bb); - } + Assert.AreEqual(123, message2.OptionalInt32); + Assert.AreEqual(1, message2.RepeatedStringCount); + Assert.AreEqual("hello", message2.RepeatedStringList[0]); + Assert.AreEqual(7, message2.OptionalNestedMessage.Bb); + } - [Test] - public void TestLiteExtensions() { - // TODO(kenton): Unlike other features of the lite library, extensions are - // implemented completely differently from the regular library. We - // should probably test them more thoroughly. + [Test] + public void TestLiteExtensions() + { + // TODO(kenton): Unlike other features of the lite library, extensions are + // implemented completely differently from the regular library. We + // should probably test them more thoroughly. - TestAllExtensionsLite message = - TestAllExtensionsLite.CreateBuilder() - .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123) - .AddExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, "hello") - .SetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite, - TestAllTypesLite.Types.NestedEnum.BAZ) - .SetExtension(UnitTestLiteProtoFile.OptionalNestedMessageExtensionLite, - TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7).Build()) - .Build(); + TestAllExtensionsLite message = + TestAllExtensionsLite.CreateBuilder() + .SetExtension(UnitTestLiteProtoFile.OptionalInt32ExtensionLite, 123) + .AddExtension(UnitTestLiteProtoFile.RepeatedStringExtensionLite, "hello") + .SetExtension(UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite, + TestAllTypesLite.Types.NestedEnum.BAZ) + .SetExtension(UnitTestLiteProtoFile.OptionalNestedMessageExtensionLite, + TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7).Build()) + .Build(); - // Test copying a message, since coping extensions actually does use a - // different code path between lite and regular libraries, and as of this - // writing, parsing hasn't been implemented yet. - TestAllExtensionsLite message2 = message.ToBuilder().Build(); + // Test copying a message, since coping extensions actually does use a + // different code path between lite and regular libraries, and as of this + // writing, parsing hasn't been implemented yet. + TestAllExtensionsLite message2 = message.ToBuilder().Build(); - Assert.AreEqual(123, (int)message2.GetExtension( - UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); - Assert.AreEqual(1, message2.GetExtensionCount( - UnitTestLiteProtoFile.RepeatedStringExtensionLite)); - Assert.AreEqual(1, message2.GetExtension( - UnitTestLiteProtoFile.RepeatedStringExtensionLite).Count); - Assert.AreEqual("hello", message2.GetExtension( - UnitTestLiteProtoFile.RepeatedStringExtensionLite, 0)); - Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.BAZ, message2.GetExtension( - UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite)); - Assert.AreEqual(7, message2.GetExtension( - UnitTestLiteProtoFile.OptionalNestedMessageExtensionLite).Bb); + Assert.AreEqual(123, (int) message2.GetExtension( + UnitTestLiteProtoFile.OptionalInt32ExtensionLite)); + Assert.AreEqual(1, message2.GetExtensionCount( + UnitTestLiteProtoFile.RepeatedStringExtensionLite)); + Assert.AreEqual(1, message2.GetExtension( + UnitTestLiteProtoFile.RepeatedStringExtensionLite).Count); + Assert.AreEqual("hello", message2.GetExtension( + UnitTestLiteProtoFile.RepeatedStringExtensionLite, 0)); + Assert.AreEqual(TestAllTypesLite.Types.NestedEnum.BAZ, message2.GetExtension( + UnitTestLiteProtoFile.OptionalNestedEnumExtensionLite)); + Assert.AreEqual(7, message2.GetExtension( + UnitTestLiteProtoFile.OptionalNestedMessageExtensionLite).Bb); + } } - } } \ No newline at end of file diff --git a/src/ProtocolBuffersLite.Test/MissingFieldAndExtensionTest.cs b/src/ProtocolBuffersLite.Test/MissingFieldAndExtensionTest.cs index f43f709d..47014f34 100644 --- a/src/ProtocolBuffersLite.Test/MissingFieldAndExtensionTest.cs +++ b/src/ProtocolBuffersLite.Test/MissingFieldAndExtensionTest.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. @@ -39,11 +39,14 @@ using NUnit.Framework; using System.Collections.Generic; using Google.ProtocolBuffers.TestProtos; -namespace Google.ProtocolBuffers { +namespace Google.ProtocolBuffers +{ [TestFixture] - public class MissingFieldAndExtensionTest { + public class MissingFieldAndExtensionTest + { [Test] - public void TestRecoverMissingExtensions() { + public void TestRecoverMissingExtensions() + { const int optionalInt32 = 12345678; TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder(); builder.SetExtension(UnitTestProtoFile.OptionalInt32Extension, optionalInt32); @@ -88,7 +91,8 @@ namespace Google.ProtocolBuffers { } [Test] - public void TestRecoverMissingFields() { + public void TestRecoverMissingFields() + { TestMissingFieldsA msga = TestMissingFieldsA.CreateBuilder() .SetId(1001) .SetName("Name") @@ -101,7 +105,8 @@ namespace Google.ProtocolBuffers { Assert.AreEqual("Name", msgb.Name); Assert.IsFalse(msgb.HasWebsite); Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count); - Assert.AreEqual("missing@field.value", msgb.UnknownFields[TestMissingFieldsA.EmailFieldNumber].LengthDelimitedList[0].ToStringUtf8()); + Assert.AreEqual("missing@field.value", + msgb.UnknownFields[TestMissingFieldsA.EmailFieldNumber].LengthDelimitedList[0].ToStringUtf8()); //serializes exactly the same (at least for this simple example) Assert.AreEqual(msga.ToByteArray(), msgb.ToByteArray()); @@ -126,7 +131,9 @@ namespace Google.ProtocolBuffers { Assert.AreEqual("Name", copya.Name); Assert.AreEqual("missing@field.value", copya.Email); Assert.AreEqual(1, copya.UnknownFields.FieldDictionary.Count); - Assert.AreEqual("http://new.missing.field", copya.UnknownFields[TestMissingFieldsB.WebsiteFieldNumber].LengthDelimitedList[0].ToStringUtf8()); + Assert.AreEqual("http://new.missing.field", + copya.UnknownFields[TestMissingFieldsB.WebsiteFieldNumber].LengthDelimitedList[0]. + ToStringUtf8()); //Lastly we can even still trip back to type B and see all fields: TestMissingFieldsB copyb = TestMissingFieldsB.ParseFrom(copya.ToByteArray()); @@ -135,12 +142,17 @@ namespace Google.ProtocolBuffers { Assert.AreEqual("Name", copyb.Name); Assert.AreEqual("http://new.missing.field", copyb.Website); Assert.AreEqual(1, copyb.UnknownFields.FieldDictionary.Count); - Assert.AreEqual("missing@field.value", copyb.UnknownFields[TestMissingFieldsA.EmailFieldNumber].LengthDelimitedList[0].ToStringUtf8()); + Assert.AreEqual("missing@field.value", + copyb.UnknownFields[TestMissingFieldsA.EmailFieldNumber].LengthDelimitedList[0].ToStringUtf8 + ()); } [Test] - public void TestRecoverMissingMessage() { - TestMissingFieldsA.Types.SubA suba = TestMissingFieldsA.Types.SubA.CreateBuilder().SetCount(3).AddValues("a").AddValues("b").AddValues("c").Build(); + public void TestRecoverMissingMessage() + { + TestMissingFieldsA.Types.SubA suba = + TestMissingFieldsA.Types.SubA.CreateBuilder().SetCount(3).AddValues("a").AddValues("b").AddValues("c"). + Build(); TestMissingFieldsA msga = TestMissingFieldsA.CreateBuilder() .SetId(1001) .SetName("Name") @@ -152,7 +164,10 @@ namespace Google.ProtocolBuffers { Assert.AreEqual(1001, msgb.Id); Assert.AreEqual("Name", msgb.Name); Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count); - Assert.AreEqual(suba.ToString(), TestMissingFieldsA.Types.SubA.ParseFrom(msgb.UnknownFields[TestMissingFieldsA.TestAFieldNumber].LengthDelimitedList[0]).ToString()); + Assert.AreEqual(suba.ToString(), + TestMissingFieldsA.Types.SubA.ParseFrom( + msgb.UnknownFields[TestMissingFieldsA.TestAFieldNumber].LengthDelimitedList[0]).ToString + ()); //serializes exactly the same (at least for this simple example) Assert.AreEqual(msga.ToByteArray(), msgb.ToByteArray()); @@ -166,7 +181,8 @@ namespace Google.ProtocolBuffers { Assert.AreEqual(suba, copya.TestA); //Now we modify B... and try again - TestMissingFieldsB.Types.SubB subb = TestMissingFieldsB.Types.SubB.CreateBuilder().AddValues("test-b").Build(); + TestMissingFieldsB.Types.SubB subb = + TestMissingFieldsB.Types.SubB.CreateBuilder().AddValues("test-b").Build(); msgb = msgb.ToBuilder().SetTestB(subb).Build(); //Does B still have the missing field? Assert.AreEqual(1, msgb.UnknownFields.FieldDictionary.Count); @@ -178,7 +194,8 @@ namespace Google.ProtocolBuffers { Assert.AreEqual("Name", copya.Name); Assert.AreEqual(suba, copya.TestA); Assert.AreEqual(1, copya.UnknownFields.FieldDictionary.Count); - Assert.AreEqual(subb.ToByteArray(), copya.UnknownFields[TestMissingFieldsB.TestBFieldNumber].LengthDelimitedList[0].ToByteArray()); + Assert.AreEqual(subb.ToByteArray(), + copya.UnknownFields[TestMissingFieldsB.TestBFieldNumber].LengthDelimitedList[0].ToByteArray()); //Lastly we can even still trip back to type B and see all fields: TestMissingFieldsB copyb = TestMissingFieldsB.ParseFrom(copya.ToByteArray()); @@ -190,7 +207,8 @@ namespace Google.ProtocolBuffers { } [Test] - public void TestRestoreFromOtherType() { + public void TestRestoreFromOtherType() + { TestInteropPerson person = TestInteropPerson.CreateBuilder() .SetId(123) .SetName("abc") @@ -198,8 +216,11 @@ namespace Google.ProtocolBuffers { .AddRangeCodes(new[] {1, 2, 3}) .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-1234").Build()) .AddPhone(TestInteropPerson.Types.PhoneNumber.CreateBuilder().SetNumber("555-5678").Build()) - .AddAddresses(TestInteropPerson.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland").SetState("NA").SetZip(12345).Build()) - .SetExtension(UnitTestExtrasFullProtoFile.EmployeeId, TestInteropEmployeeId.CreateBuilder().SetNumber("123").Build()) + .AddAddresses( + TestInteropPerson.Types.Addresses.CreateBuilder().SetAddress("123 Seseme").SetCity("Wonderland"). + SetState("NA").SetZip(12345).Build()) + .SetExtension(UnitTestExtrasFullProtoFile.EmployeeId, + TestInteropEmployeeId.CreateBuilder().SetNumber("123").Build()) .Build(); Assert.IsTrue(person.IsInitialized); diff --git a/src/ProtocolBuffersLite.Test/TestLiteByApi.cs b/src/ProtocolBuffersLite.Test/TestLiteByApi.cs index 5fc00a45..5fee2ecb 100644 --- a/src/ProtocolBuffersLite.Test/TestLiteByApi.cs +++ b/src/ProtocolBuffersLite.Test/TestLiteByApi.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,84 +31,91 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #endregion using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; -namespace Google.ProtocolBuffers { - [TestFixture] - public class TestLiteByApi { - - [Test] - public void TestAllTypesEquality() { - TestAllTypesLite msg = TestAllTypesLite.DefaultInstance; - TestAllTypesLite copy = msg.ToBuilder().Build(); - Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode()); - Assert.IsTrue(msg.Equals(copy)); - msg = msg.ToBuilder().SetOptionalString("Hi").Build(); - Assert.AreNotEqual(msg.GetHashCode(), copy.GetHashCode()); - Assert.IsFalse(msg.Equals(copy)); - copy = copy.ToBuilder().SetOptionalString("Hi").Build(); - Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode()); - Assert.IsTrue(msg.Equals(copy)); - } +namespace Google.ProtocolBuffers +{ + [TestFixture] + public class TestLiteByApi + { + [Test] + public void TestAllTypesEquality() + { + TestAllTypesLite msg = TestAllTypesLite.DefaultInstance; + TestAllTypesLite copy = msg.ToBuilder().Build(); + Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode()); + Assert.IsTrue(msg.Equals(copy)); + msg = msg.ToBuilder().SetOptionalString("Hi").Build(); + Assert.AreNotEqual(msg.GetHashCode(), copy.GetHashCode()); + Assert.IsFalse(msg.Equals(copy)); + copy = copy.ToBuilder().SetOptionalString("Hi").Build(); + Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode()); + Assert.IsTrue(msg.Equals(copy)); + } - [Test] - public void TestEqualityOnExtensions() { - TestAllExtensionsLite msg = TestAllExtensionsLite.DefaultInstance; - TestAllExtensionsLite copy = msg.ToBuilder().Build(); - Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode()); - Assert.IsTrue(msg.Equals(copy)); - msg = msg.ToBuilder().SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Hi").Build(); - Assert.AreNotEqual(msg.GetHashCode(), copy.GetHashCode()); - Assert.IsFalse(msg.Equals(copy)); - copy = copy.ToBuilder().SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Hi").Build(); - Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode()); - Assert.IsTrue(msg.Equals(copy)); - } + [Test] + public void TestEqualityOnExtensions() + { + TestAllExtensionsLite msg = TestAllExtensionsLite.DefaultInstance; + TestAllExtensionsLite copy = msg.ToBuilder().Build(); + Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode()); + Assert.IsTrue(msg.Equals(copy)); + msg = msg.ToBuilder().SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Hi").Build(); + Assert.AreNotEqual(msg.GetHashCode(), copy.GetHashCode()); + Assert.IsFalse(msg.Equals(copy)); + copy = copy.ToBuilder().SetExtension(UnitTestLiteProtoFile.OptionalStringExtensionLite, "Hi").Build(); + Assert.AreEqual(msg.GetHashCode(), copy.GetHashCode()); + Assert.IsTrue(msg.Equals(copy)); + } - [Test] - public void TestAllTypesToString() { - TestAllTypesLite msg = TestAllTypesLite.DefaultInstance; - TestAllTypesLite copy = msg.ToBuilder().Build(); - Assert.AreEqual(msg.ToString(), copy.ToString()); - Assert.IsEmpty(msg.ToString()); - msg = msg.ToBuilder().SetOptionalInt32(-1).Build(); - Assert.AreEqual("optional_int32: -1", msg.ToString().TrimEnd()); - msg = msg.ToBuilder().SetOptionalString("abc123").Build(); - Assert.AreEqual("optional_int32: -1\noptional_string: \"abc123\"", msg.ToString().Replace("\r", "").TrimEnd()); - } + [Test] + public void TestAllTypesToString() + { + TestAllTypesLite msg = TestAllTypesLite.DefaultInstance; + TestAllTypesLite copy = msg.ToBuilder().Build(); + Assert.AreEqual(msg.ToString(), copy.ToString()); + Assert.IsEmpty(msg.ToString()); + msg = msg.ToBuilder().SetOptionalInt32(-1).Build(); + Assert.AreEqual("optional_int32: -1", msg.ToString().TrimEnd()); + msg = msg.ToBuilder().SetOptionalString("abc123").Build(); + Assert.AreEqual("optional_int32: -1\noptional_string: \"abc123\"", + msg.ToString().Replace("\r", "").TrimEnd()); + } - [Test] - public void TestAllTypesDefaultedRoundTrip() { - TestAllTypesLite msg = TestAllTypesLite.DefaultInstance; - Assert.IsTrue(msg.IsInitialized); - TestAllTypesLite copy = TestAllTypesLite.CreateBuilder().MergeFrom(msg.ToByteArray()).Build(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); - } + [Test] + public void TestAllTypesDefaultedRoundTrip() + { + TestAllTypesLite msg = TestAllTypesLite.DefaultInstance; + Assert.IsTrue(msg.IsInitialized); + TestAllTypesLite copy = TestAllTypesLite.CreateBuilder().MergeFrom(msg.ToByteArray()).Build(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } - [Test] - public void TestAllTypesModifiedRoundTrip() { - TestAllTypesLite msg = TestAllTypesLite.DefaultInstance; - msg.ToBuilder() - .SetOptionalBool(true) - .SetOptionalCord("Hi") - .SetOptionalDouble(1.123) - .SetOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_FOO) - .SetOptionalForeignMessage(ForeignMessageLite.CreateBuilder().SetC('c').Build()) - .SetOptionalGroup(TestAllTypesLite.Types.OptionalGroup.CreateBuilder().SetA('a').Build()) - .SetOptionalImportEnum(ImportEnumLite.IMPORT_LITE_BAR) - .SetOptionalInt32(32) - .SetOptionalInt64(64) - .SetOptionalNestedEnum(TestAllTypesLite.Types.NestedEnum.FOO) - .SetOptionalString("SetOptionalString") - .AddRepeatedGroup(TestAllTypesLite.Types.RepeatedGroup.CreateBuilder().SetA('a').Build()) - .AddRepeatedGroup(TestAllTypesLite.Types.RepeatedGroup.CreateBuilder().SetA('A').Build()) - ; - TestAllTypesLite copy = TestAllTypesLite.CreateBuilder().MergeFrom(msg.ToByteArray()).Build(); - Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + [Test] + public void TestAllTypesModifiedRoundTrip() + { + TestAllTypesLite msg = TestAllTypesLite.DefaultInstance; + msg.ToBuilder() + .SetOptionalBool(true) + .SetOptionalCord("Hi") + .SetOptionalDouble(1.123) + .SetOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_FOO) + .SetOptionalForeignMessage(ForeignMessageLite.CreateBuilder().SetC('c').Build()) + .SetOptionalGroup(TestAllTypesLite.Types.OptionalGroup.CreateBuilder().SetA('a').Build()) + .SetOptionalImportEnum(ImportEnumLite.IMPORT_LITE_BAR) + .SetOptionalInt32(32) + .SetOptionalInt64(64) + .SetOptionalNestedEnum(TestAllTypesLite.Types.NestedEnum.FOO) + .SetOptionalString("SetOptionalString") + .AddRepeatedGroup(TestAllTypesLite.Types.RepeatedGroup.CreateBuilder().SetA('a').Build()) + .AddRepeatedGroup(TestAllTypesLite.Types.RepeatedGroup.CreateBuilder().SetA('A').Build()) + ; + TestAllTypesLite copy = TestAllTypesLite.CreateBuilder().MergeFrom(msg.ToByteArray()).Build(); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } } - - } -} +} \ No newline at end of file -- cgit v1.2.3