From 3c6e93283a90b2d5c944a02bba3f1606272d762d Mon Sep 17 00:00:00 2001 From: csharptest Date: Fri, 9 Sep 2011 18:14:40 -0500 Subject: Completed addition and testing of new add_serializable option. --- protos/extest/unittest_extras_lite.proto | 123 +++++++------- protos/extest/unittest_extras_xmltest.proto | 1 + protos/google/protobuf/csharp_options.proto | 3 + src/ProtoGen/MessageGenerator.cs | 10 +- .../ProtocolBuffers.Test.csproj | 1 + src/ProtocolBuffers.Test/SerializableTest.cs | 153 ++++++++++++++++++ .../UnitTestXmlSerializerTestProtoFile.cs | 18 ++- src/ProtocolBuffers/AbstractBuilder.cs | 2 +- src/ProtocolBuffers/AbstractBuilderLite.cs | 2 +- src/ProtocolBuffers/AbstractMessage.cs | 2 +- src/ProtocolBuffers/AbstractMessageLite.cs | 2 +- src/ProtocolBuffers/CustomSerialization.cs | 180 +++++++++++++++++++++ .../DescriptorProtos/CSharpOptions.cs | 114 ++++++++----- src/ProtocolBuffers/DynamicMessage.cs | 4 +- src/ProtocolBuffers/ExtendableBuilder.cs | 2 +- src/ProtocolBuffers/ExtendableBuilderLite.cs | 2 +- src/ProtocolBuffers/ExtendableMessage.cs | 2 +- src/ProtocolBuffers/ExtendableMessageLite.cs | 2 +- src/ProtocolBuffers/GeneratedBuilder.cs | 2 +- src/ProtocolBuffers/GeneratedBuilderLite.cs | 2 +- src/ProtocolBuffers/GeneratedMessage.cs | 2 +- src/ProtocolBuffers/GeneratedMessageLite.cs | 2 +- src/ProtocolBuffers/IBuilderLite.cs | 2 +- src/ProtocolBuffers/IMessageLite.cs | 2 +- src/ProtocolBuffers/ProtocolBuffers.csproj | 1 + src/ProtocolBuffers/ProtocolBuffersLite.csproj | 1 + src/ProtocolBuffers/UnknownFieldSet.cs | 4 +- src/ProtocolBuffers2008.sln | 1 - .../ProtocolBuffersLite.Test.csproj | 1 + .../SerializableLiteTest.cs | 53 ++++++ .../TestProtos/UnitTestExtrasLiteProtoFile.cs | 10 ++ 31 files changed, 586 insertions(+), 120 deletions(-) create mode 100644 src/ProtocolBuffers.Test/SerializableTest.cs create mode 100644 src/ProtocolBuffers/CustomSerialization.cs create mode 100644 src/ProtocolBuffersLite.Test/SerializableLiteTest.cs diff --git a/protos/extest/unittest_extras_lite.proto b/protos/extest/unittest_extras_lite.proto index 46d5ab91..72e7ee81 100644 --- a/protos/extest/unittest_extras_lite.proto +++ b/protos/extest/unittest_extras_lite.proto @@ -1,61 +1,62 @@ -// Additional options required for C# generation. File from copyright -// line onwards is as per original distribution. -import "google/protobuf/csharp_options.proto"; -option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos"; -option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestExtrasLiteProtoFile"; - -package protobuf_unittest_extra; - -option optimize_for = LITE_RUNTIME; - -option java_package = "com.google.protobuf"; - -message TestRequiredLite { - required int32 d = 1; - required ExtraEnum en = 2 [default = DEFAULT]; -} - -enum ExtraEnum { - DEFAULT = 10; - EXLITE_FOO = 7; - EXLITE_BAR = 8; - EXLITE_BAZ = 9; -} - -message TestInteropPersonLite { - required string name = 1; - required int32 id = 2; - optional string email = 3; - repeated int32 codes = 10 [packed=true]; - - enum PhoneType { - MOBILE = 0; - HOME = 1; - WORK = 2; - } - - message PhoneNumber { - required string number = 1; - optional PhoneType type = 2 [default = HOME]; - } - - repeated PhoneNumber phone = 4; - - repeated group Addresses = 5 { - required string address = 1; - optional string address2 = 2; - required string city = 3; - required string state = 4; - required fixed32 zip = 5; - } - - extensions 100 to 199; -} - -message TestInteropEmployeeIdLite { - required string number = 1; -} - -extend TestInteropPersonLite { - required TestInteropEmployeeIdLite employee_id_lite = 126; -} +// Additional options required for C# generation. File from copyright +// line onwards is as per original distribution. +import "google/protobuf/csharp_options.proto"; +option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos"; +option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestExtrasLiteProtoFile"; +option (google.protobuf.csharp_file_options).add_serializable = true; + +package protobuf_unittest_extra; + +option optimize_for = LITE_RUNTIME; + +option java_package = "com.google.protobuf"; + +message TestRequiredLite { + required int32 d = 1; + required ExtraEnum en = 2 [default = DEFAULT]; +} + +enum ExtraEnum { + DEFAULT = 10; + EXLITE_FOO = 7; + EXLITE_BAR = 8; + EXLITE_BAZ = 9; +} + +message TestInteropPersonLite { + required string name = 1; + required int32 id = 2; + optional string email = 3; + repeated int32 codes = 10 [packed=true]; + + enum PhoneType { + MOBILE = 0; + HOME = 1; + WORK = 2; + } + + message PhoneNumber { + required string number = 1; + optional PhoneType type = 2 [default = HOME]; + } + + repeated PhoneNumber phone = 4; + + repeated group Addresses = 5 { + required string address = 1; + optional string address2 = 2; + required string city = 3; + required string state = 4; + required fixed32 zip = 5; + } + + extensions 100 to 199; +} + +message TestInteropEmployeeIdLite { + required string number = 1; +} + +extend TestInteropPersonLite { + required TestInteropEmployeeIdLite employee_id_lite = 126; +} diff --git a/protos/extest/unittest_extras_xmltest.proto b/protos/extest/unittest_extras_xmltest.proto index f00fb027..7fc4e3a2 100644 --- a/protos/extest/unittest_extras_xmltest.proto +++ b/protos/extest/unittest_extras_xmltest.proto @@ -1,6 +1,7 @@ import "google/protobuf/csharp_options.proto"; option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos"; option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestXmlSerializerTestProtoFile"; +option (google.protobuf.csharp_file_options).add_serializable = true; package protobuf_unittest_extra; diff --git a/protos/google/protobuf/csharp_options.proto b/protos/google/protobuf/csharp_options.proto index 33a7b03d..9ebcfa6b 100644 --- a/protos/google/protobuf/csharp_options.proto +++ b/protos/google/protobuf/csharp_options.proto @@ -38,6 +38,9 @@ message CSharpFileOptions { // Generate attributes indicating non-CLS-compliance optional bool cls_compliance = 8 [default = true]; + + // Generate messages/builders with the [Serializable] attribute + optional bool add_serializable = 9 [default = false]; // The extension that should be appended to the umbrella_classname when creating files. optional string file_extension = 221 [default = ".cs"]; diff --git a/src/ProtoGen/MessageGenerator.cs b/src/ProtoGen/MessageGenerator.cs index 01d47ce2..83004da9 100644 --- a/src/ProtoGen/MessageGenerator.cs +++ b/src/ProtoGen/MessageGenerator.cs @@ -165,9 +165,13 @@ namespace Google.ProtocolBuffers.ProtoGen { return SourceGenerators.CreateFieldGenerator(fieldDescriptor, FieldOrdinal(fieldDescriptor)); } - + public void Generate(TextGenerator writer) { + if (Descriptor.File.CSharpOptions.AddSerializable) + { + writer.WriteLine("[global::System.SerializableAttribute()]"); + } writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); writer.WriteLine("[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]"); writer.WriteLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"{0}\", \"{1}\")]", @@ -554,6 +558,10 @@ namespace Google.ProtocolBuffers.ProtoGen writer.WriteLine(" return (Builder) new Builder().MergeFrom(prototype);"); writer.WriteLine("}"); writer.WriteLine(); + if (Descriptor.File.CSharpOptions.AddSerializable) + { + writer.WriteLine("[global::System.SerializableAttribute()]"); + } writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); writer.WriteLine("[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]"); writer.WriteLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"{0}\", \"{1}\")]", diff --git a/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj b/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj index 95ab0b9c..98fd3cb1 100644 --- a/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj +++ b/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj @@ -105,6 +105,7 @@ + diff --git a/src/ProtocolBuffers.Test/SerializableTest.cs b/src/ProtocolBuffers.Test/SerializableTest.cs new file mode 100644 index 00000000..701cfc6b --- /dev/null +++ b/src/ProtocolBuffers.Test/SerializableTest.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using Google.ProtocolBuffers.TestProtos; +using NUnit.Framework; + +namespace Google.ProtocolBuffers +{ + [TestFixture] + public class SerializableTest + { + /// + /// Just keep it from even compiling if we these objects don't implement the expected interface. + /// + public static readonly ISerializable CompileTimeCheckSerializableMessage = TestXmlMessage.DefaultInstance; + public static readonly ISerializable CompileTimeCheckSerializableBuilder = new TestXmlMessage.Builder(); + + [Test] + public void TestPlainMessage() + { + TestXmlMessage message = TestXmlMessage.CreateBuilder() + .SetValid(true) + .SetText("text") + .AddTextlines("a") + .AddTextlines("b") + .AddTextlines("c") + .SetNumber(0x1010101010) + .AddNumbers(1) + .AddNumbers(2) + .AddNumbers(3) + .SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.ONE).SetBinary(ByteString.CopyFrom(new byte[1]))) + .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.TWO).SetBinary(ByteString.CopyFrom(new byte[2]))) + .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.THREE).SetBinary(ByteString.CopyFrom(new byte[3]))) + .Build(); + + MemoryStream ms = new MemoryStream(); + new BinaryFormatter().Serialize(ms, message); + + ms.Position = 0; + TestXmlMessage copy = (TestXmlMessage)new BinaryFormatter().Deserialize(ms); + + Assert.AreEqual(message, copy); + } + + [Test] + public void TestMessageWithExtensions() + { + TestXmlMessage message = TestXmlMessage.CreateBuilder() + .SetValid(true) + .SetText("text") + .AddTextlines("a") + .AddTextlines("b") + .AddTextlines("c") + .SetNumber(0x1010101010) + .AddNumbers(1) + .AddNumbers(2) + .AddNumbers(3) + .SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.ONE).SetBinary(ByteString.CopyFrom(new byte[1]))) + .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.TWO).SetBinary(ByteString.CopyFrom(new byte[2]))) + .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.THREE).SetBinary(ByteString.CopyFrom(new byte[3]))) + .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionText, " extension text value ! ") + .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionMessage, new TestXmlExtension.Builder().SetNumber(42).Build()) + .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 100) + .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 101) + .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 102) + .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionEnum, EnumOptions.ONE) + .Build(); + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry); + + MemoryStream ms = new MemoryStream(); + new BinaryFormatter().Serialize(ms, message); + + ms.Position = 0; + //you need to provide the extension registry as context to the serializer + BinaryFormatter bff = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.All, registry)); + TestXmlMessage copy = (TestXmlMessage)bff.Deserialize(ms); + + // And all extensions will be defined. + Assert.AreEqual(message, copy); + } + + [Test] + public void TestPlainBuilder() + { + TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder() + .SetValid(true) + .SetText("text") + .AddTextlines("a") + .AddTextlines("b") + .AddTextlines("c") + .SetNumber(0x1010101010) + .AddNumbers(1) + .AddNumbers(2) + .AddNumbers(3) + .SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.ONE).SetBinary(ByteString.CopyFrom(new byte[1]))) + .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.TWO).SetBinary(ByteString.CopyFrom(new byte[2]))) + .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.THREE).SetBinary(ByteString.CopyFrom(new byte[3]))) + ; + + MemoryStream ms = new MemoryStream(); + new BinaryFormatter().Serialize(ms, builder); + + ms.Position = 0; + TestXmlMessage.Builder copy = (TestXmlMessage.Builder)new BinaryFormatter().Deserialize(ms); + + Assert.AreEqual(builder.Build(), copy.Build()); + } + + [Test] + public void TestBuilderWithExtensions() + { + TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder() + .SetValid(true) + .SetText("text") + .AddTextlines("a") + .AddTextlines("b") + .AddTextlines("c") + .SetNumber(0x1010101010) + .AddNumbers(1) + .AddNumbers(2) + .AddNumbers(3) + .SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.ONE).SetBinary(ByteString.CopyFrom(new byte[1]))) + .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.TWO).SetBinary(ByteString.CopyFrom(new byte[2]))) + .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.THREE).SetBinary(ByteString.CopyFrom(new byte[3]))) + .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionText, " extension text value ! ") + .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionMessage, new TestXmlExtension.Builder().SetNumber(42).Build()) + .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 100) + .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 101) + .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 102) + .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionEnum, EnumOptions.ONE) + ; + + ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry); + + MemoryStream ms = new MemoryStream(); + new BinaryFormatter().Serialize(ms, builder); + + ms.Position = 0; + //you need to provide the extension registry as context to the serializer + BinaryFormatter bff = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.All, registry)); + TestXmlMessage.Builder copy = (TestXmlMessage.Builder)bff.Deserialize(ms); + + // And all extensions will be defined. + Assert.AreEqual(builder.Build(), copy.Build()); + } + } +} diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs index 3d818a60..8e8aff01 100644 --- a/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs +++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs @@ -76,9 +76,9 @@ namespace Google.ProtocolBuffers.TestProtos { "dGVuc2lvbl9udW1iZXISJy5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0" + "WG1sTWVzc2FnZRhnIAMoBUICEAE6bgoRZXh0ZW5zaW9uX21lc3NhZ2USJy5w" + "cm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0WG1sTWVzc2FnZRjHASABKAsy" + - "KS5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0WG1sRXh0ZW5zaW9uQkxI" + - "AcI+RwohR29vZ2xlLlByb3RvY29sQnVmZmVycy5UZXN0UHJvdG9zEiJVbml0" + - "VGVzdFhtbFNlcmlhbGl6ZXJUZXN0UHJvdG9GaWxl"); + "KS5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0WG1sRXh0ZW5zaW9uQk5I" + + "AcI+SQohR29vZ2xlLlByb3RvY29sQnVmZmVycy5UZXN0UHJvdG9zEiJVbml0" + + "VGVzdFhtbFNlcmlhbGl6ZXJUZXN0UHJvdG9GaWxlSAE="); pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { descriptor = root; internal__static_protobuf_unittest_extra_TestXmlChild__Descriptor = Descriptor.MessageTypes[0]; @@ -134,6 +134,7 @@ namespace Google.ProtocolBuffers.TestProtos { #endregion #region Messages + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -264,6 +265,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -443,6 +445,7 @@ namespace Google.ProtocolBuffers.TestProtos { } } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -532,6 +535,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -641,6 +645,7 @@ namespace Google.ProtocolBuffers.TestProtos { } } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -746,6 +751,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -903,6 +909,7 @@ namespace Google.ProtocolBuffers.TestProtos { } } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -935,6 +942,7 @@ namespace Google.ProtocolBuffers.TestProtos { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] public static class Types { + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -1065,6 +1073,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -1441,6 +1450,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -1792,6 +1802,7 @@ namespace Google.ProtocolBuffers.TestProtos { } } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -1898,6 +1909,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] diff --git a/src/ProtocolBuffers/AbstractBuilder.cs b/src/ProtocolBuffers/AbstractBuilder.cs index e477194c..47d84a35 100644 --- a/src/ProtocolBuffers/AbstractBuilder.cs +++ b/src/ProtocolBuffers/AbstractBuilder.cs @@ -44,7 +44,7 @@ namespace Google.ProtocolBuffers /// /// Implementation of the non-generic IMessage interface as far as possible. /// - public abstract class AbstractBuilder : AbstractBuilderLite, + public abstract partial class AbstractBuilder : AbstractBuilderLite, IBuilder where TMessage : AbstractMessage where TBuilder : AbstractBuilder diff --git a/src/ProtocolBuffers/AbstractBuilderLite.cs b/src/ProtocolBuffers/AbstractBuilderLite.cs index 8899d9b2..a7fedeae 100644 --- a/src/ProtocolBuffers/AbstractBuilderLite.cs +++ b/src/ProtocolBuffers/AbstractBuilderLite.cs @@ -42,7 +42,7 @@ namespace Google.ProtocolBuffers /// /// Implementation of the non-generic IMessage interface as far as possible. /// - public abstract class AbstractBuilderLite : IBuilderLite + public abstract partial class AbstractBuilderLite : IBuilderLite where TMessage : AbstractMessageLite where TBuilder : AbstractBuilderLite { diff --git a/src/ProtocolBuffers/AbstractMessage.cs b/src/ProtocolBuffers/AbstractMessage.cs index 13443b1c..16c8c786 100644 --- a/src/ProtocolBuffers/AbstractMessage.cs +++ b/src/ProtocolBuffers/AbstractMessage.cs @@ -46,7 +46,7 @@ namespace Google.ProtocolBuffers /// /// Implementation of the non-generic IMessage interface as far as possible. /// - public abstract class AbstractMessage : AbstractMessageLite, + public abstract partial class AbstractMessage : AbstractMessageLite, IMessage where TMessage : AbstractMessage where TBuilder : AbstractBuilder diff --git a/src/ProtocolBuffers/AbstractMessageLite.cs b/src/ProtocolBuffers/AbstractMessageLite.cs index 021cb0ef..1cdead2e 100644 --- a/src/ProtocolBuffers/AbstractMessageLite.cs +++ b/src/ProtocolBuffers/AbstractMessageLite.cs @@ -41,7 +41,7 @@ namespace Google.ProtocolBuffers /// /// Implementation of the non-generic IMessage interface as far as possible. /// - public abstract class AbstractMessageLite : IMessageLite + public abstract partial class AbstractMessageLite : IMessageLite where TMessage : AbstractMessageLite where TBuilder : AbstractBuilderLite { diff --git a/src/ProtocolBuffers/CustomSerialization.cs b/src/ProtocolBuffers/CustomSerialization.cs new file mode 100644 index 00000000..a68f816e --- /dev/null +++ b/src/ProtocolBuffers/CustomSerialization.cs @@ -0,0 +1,180 @@ +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) 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.Runtime.Serialization; + +/* + * This entire source file is not supported on the Silverlight platform + */ +#if !SILVERLIGHT2 +namespace Google.ProtocolBuffers +{ + /* + * Specialized handing of *all* message types. Messages are serialized into a byte[] and stored + * into the SerializationInfo, they are then reconstituded by an IObjectReference class after + * deserialization. IDeserializationCallback is supported on both the Builder and Message. + */ + [Serializable] + partial class AbstractMessageLite : ISerializable + { + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof(SerializationSurrogate)); + info.AddValue("message", ToByteArray()); + info.AddValue("initialized", IsInitialized); + } + + [Serializable] + private sealed class SerializationSurrogate : IObjectReference, ISerializable + { + static readonly TBuilder TemplateInstance = (TBuilder)Activator.CreateInstance(typeof(TBuilder)); + private readonly byte[] _message; + private readonly bool _initialized; + + private SerializationSurrogate(SerializationInfo info, StreamingContext context) + { + _message = (byte[])info.GetValue("message", typeof(byte[])); + _initialized = info.GetBoolean("initialized"); + } + + Object IObjectReference.GetRealObject(StreamingContext context) + { + ExtensionRegistry registry = context.Context as ExtensionRegistry; + TBuilder builder = TemplateInstance.DefaultInstanceForType.CreateBuilderForType(); + builder.MergeFrom(_message, registry ?? ExtensionRegistry.Empty); + + if (builder is IDeserializationCallback) + ((IDeserializationCallback)builder).OnDeserialization(context); + + TMessage message = _initialized ? builder.Build() : builder.BuildPartial(); + + if (message is IDeserializationCallback) + ((IDeserializationCallback)message).OnDeserialization(context); + + return message; + } + + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("message", _message); + } + } + } + + [Serializable] + partial class AbstractBuilderLite : ISerializable + { + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof(SerializationSurrogate)); + info.AddValue("message", Clone().BuildPartial().ToByteArray()); + } + + [Serializable] + private sealed class SerializationSurrogate : IObjectReference, ISerializable + { + static readonly TBuilder TemplateInstance = (TBuilder)Activator.CreateInstance(typeof(TBuilder)); + private readonly byte[] _message; + + private SerializationSurrogate(SerializationInfo info, StreamingContext context) + { + _message = (byte[])info.GetValue("message", typeof(byte[])); + } + + Object IObjectReference.GetRealObject(StreamingContext context) + { + ExtensionRegistry registry = context.Context as ExtensionRegistry; + TBuilder builder = TemplateInstance.DefaultInstanceForType.CreateBuilderForType(); + builder.MergeFrom(_message, registry ?? ExtensionRegistry.Empty); + + if (builder is IDeserializationCallback) + ((IDeserializationCallback)builder).OnDeserialization(context); + + return builder; + } + + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("message", _message); + } + } + } + + /* + * Spread some attribute love around, keeping this all here so we don't use conditional compliation + * in every one of these classes. If we introduce a new platform that also does not support this + * we can control it all from this source file. + */ + + [Serializable] + partial class GeneratedMessageLite { } + + [Serializable] + partial class ExtendableMessageLite { } + + [Serializable] + partial class AbstractMessage { } + + [Serializable] + partial class GeneratedMessage { } + + [Serializable] + partial class ExtendableMessage { } + + [Serializable] + partial class GeneratedBuilderLite { } + + [Serializable] + partial class ExtendableBuilderLite { } + + [Serializable] + partial class AbstractBuilder { } + + [Serializable] + partial class GeneratedBuilder { } + + [Serializable] + partial class ExtendableBuilder { } + + [Serializable] + partial class DynamicMessage + { + [Serializable] + partial class Builder { } + } +} +#endif \ No newline at end of file diff --git a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs index 853b0e7d..056eb982 100644 --- a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs +++ b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs @@ -52,36 +52,37 @@ namespace Google.ProtocolBuffers.DescriptorProtos { byte[] descriptorData = global::System.Convert.FromBase64String( "CiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8SD2dvb2ds" + "ZS5wcm90b2J1ZhogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8i" + - "tgMKEUNTaGFycEZpbGVPcHRpb25zEhEKCW5hbWVzcGFjZRgBIAEoCRIaChJ1" + + "1wMKEUNTaGFycEZpbGVPcHRpb25zEhEKCW5hbWVzcGFjZRgBIAEoCRIaChJ1" + "bWJyZWxsYV9jbGFzc25hbWUYAiABKAkSHAoOcHVibGljX2NsYXNzZXMYAyAB" + "KAg6BHRydWUSFgoObXVsdGlwbGVfZmlsZXMYBCABKAgSFAoMbmVzdF9jbGFz" + "c2VzGAUgASgIEhYKDmNvZGVfY29udHJhY3RzGAYgASgIEiQKHGV4cGFuZF9u" + "YW1lc3BhY2VfZGlyZWN0b3JpZXMYByABKAgSHAoOY2xzX2NvbXBsaWFuY2UY" + - "CCABKAg6BHRydWUSHAoOZmlsZV9leHRlbnNpb24Y3QEgASgJOgMuY3MSGwoS" + - "dW1icmVsbGFfbmFtZXNwYWNlGN4BIAEoCRIcChBvdXRwdXRfZGlyZWN0b3J5" + - "GN8BIAEoCToBLhImChZpZ25vcmVfZ29vZ2xlX3Byb3RvYnVmGOABIAEoCDoF" + - "ZmFsc2USSQoWc2VydmljZV9nZW5lcmF0b3JfdHlwZRjhASABKA4yIi5nb29n" + - "bGUucHJvdG9idWYuQ1NoYXJwU2VydmljZVR5cGU6BE5PTkUiKwoSQ1NoYXJw" + - "RmllbGRPcHRpb25zEhUKDXByb3BlcnR5X25hbWUYASABKAkiLAoUQ1NoYXJw" + - "U2VydmljZU9wdGlvbnMSFAoMaW50ZXJmYWNlX2lkGAEgASgJIioKE0NTaGFy" + - "cE1ldGhvZE9wdGlvbnMSEwoLZGlzcGF0Y2hfaWQYASABKAUqSwoRQ1NoYXJw" + - "U2VydmljZVR5cGUSCAoETk9ORRAAEgsKB0dFTkVSSUMQARINCglJTlRFUkZB" + - "Q0UQAhIQCgxJUlBDRElTUEFUQ0gQAzpeChNjc2hhcnBfZmlsZV9vcHRpb25z" + - "EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGOgHIAEoCzIiLmdvb2ds" + - "ZS5wcm90b2J1Zi5DU2hhcnBGaWxlT3B0aW9uczphChRjc2hhcnBfZmllbGRf" + - "b3B0aW9ucxIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY6AcgASgL" + - "MiMuZ29vZ2xlLnByb3RvYnVmLkNTaGFycEZpZWxkT3B0aW9uczpnChZjc2hh" + - "cnBfc2VydmljZV9vcHRpb25zEh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VP" + - "cHRpb25zGOgHIAEoCzIlLmdvb2dsZS5wcm90b2J1Zi5DU2hhcnBTZXJ2aWNl" + - "T3B0aW9uczpkChVjc2hhcnBfbWV0aG9kX29wdGlvbnMSHi5nb29nbGUucHJv" + - "dG9idWYuTWV0aG9kT3B0aW9ucxjoByABKAsyJC5nb29nbGUucHJvdG9idWYu" + - "Q1NoYXJwTWV0aG9kT3B0aW9ucw=="); + "CCABKAg6BHRydWUSHwoQYWRkX3NlcmlhbGl6YWJsZRgJIAEoCDoFZmFsc2US" + + "HAoOZmlsZV9leHRlbnNpb24Y3QEgASgJOgMuY3MSGwoSdW1icmVsbGFfbmFt" + + "ZXNwYWNlGN4BIAEoCRIcChBvdXRwdXRfZGlyZWN0b3J5GN8BIAEoCToBLhIm" + + "ChZpZ25vcmVfZ29vZ2xlX3Byb3RvYnVmGOABIAEoCDoFZmFsc2USSQoWc2Vy" + + "dmljZV9nZW5lcmF0b3JfdHlwZRjhASABKA4yIi5nb29nbGUucHJvdG9idWYu" + + "Q1NoYXJwU2VydmljZVR5cGU6BE5PTkUiKwoSQ1NoYXJwRmllbGRPcHRpb25z" + + "EhUKDXByb3BlcnR5X25hbWUYASABKAkiLAoUQ1NoYXJwU2VydmljZU9wdGlv" + + "bnMSFAoMaW50ZXJmYWNlX2lkGAEgASgJIioKE0NTaGFycE1ldGhvZE9wdGlv" + + "bnMSEwoLZGlzcGF0Y2hfaWQYASABKAUqSwoRQ1NoYXJwU2VydmljZVR5cGUS" + + "CAoETk9ORRAAEgsKB0dFTkVSSUMQARINCglJTlRFUkZBQ0UQAhIQCgxJUlBD" + + "RElTUEFUQ0gQAzpeChNjc2hhcnBfZmlsZV9vcHRpb25zEhwuZ29vZ2xlLnBy" + + "b3RvYnVmLkZpbGVPcHRpb25zGOgHIAEoCzIiLmdvb2dsZS5wcm90b2J1Zi5D" + + "U2hhcnBGaWxlT3B0aW9uczphChRjc2hhcnBfZmllbGRfb3B0aW9ucxIdLmdv" + + "b2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY6AcgASgLMiMuZ29vZ2xlLnBy" + + "b3RvYnVmLkNTaGFycEZpZWxkT3B0aW9uczpnChZjc2hhcnBfc2VydmljZV9v" + + "cHRpb25zEh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zGOgHIAEo" + + "CzIlLmdvb2dsZS5wcm90b2J1Zi5DU2hhcnBTZXJ2aWNlT3B0aW9uczpkChVj" + + "c2hhcnBfbWV0aG9kX29wdGlvbnMSHi5nb29nbGUucHJvdG9idWYuTWV0aG9k" + + "T3B0aW9ucxjoByABKAsyJC5nb29nbGUucHJvdG9idWYuQ1NoYXJwTWV0aG9k" + + "T3B0aW9ucw=="); 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", }); + new string[] { "Namespace", "UmbrellaClassname", "PublicClasses", "MultipleFiles", "NestClasses", "CodeContracts", "ExpandNamespaceDirectories", "ClsCompliance", "AddSerializable", "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, @@ -126,8 +127,8 @@ namespace Google.ProtocolBuffers.DescriptorProtos { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] public sealed partial class CSharpFileOptions : pb::GeneratedMessage { private static readonly CSharpFileOptions defaultInstance = new Builder().BuildPartial(); - private static readonly string[] _cSharpFileOptionsFieldNames = new string[] { "cls_compliance", "code_contracts", "expand_namespace_directories", "file_extension", "ignore_google_protobuf", "multiple_files", "namespace", "nest_classes", "output_directory", "public_classes", "service_generator_type", "umbrella_classname", "umbrella_namespace" }; - private static readonly uint[] _cSharpFileOptionsFieldTags = new uint[] { 64, 48, 56, 1770, 1792, 32, 10, 40, 1786, 24, 1800, 18, 1778 }; + private static readonly string[] _cSharpFileOptionsFieldNames = new string[] { "add_serializable", "cls_compliance", "code_contracts", "expand_namespace_directories", "file_extension", "ignore_google_protobuf", "multiple_files", "namespace", "nest_classes", "output_directory", "public_classes", "service_generator_type", "umbrella_classname", "umbrella_namespace" }; + private static readonly uint[] _cSharpFileOptionsFieldTags = new uint[] { 72, 64, 48, 56, 1770, 1792, 32, 10, 40, 1786, 24, 1800, 18, 1778 }; public static CSharpFileOptions DefaultInstance { get { return defaultInstance; } } @@ -228,6 +229,16 @@ namespace Google.ProtocolBuffers.DescriptorProtos { get { return clsCompliance_; } } + public const int AddSerializableFieldNumber = 9; + private bool hasAddSerializable; + private bool addSerializable_; + public bool HasAddSerializable { + get { return hasAddSerializable; } + } + public bool AddSerializable { + get { return addSerializable_; } + } + public const int FileExtensionFieldNumber = 221; private bool hasFileExtension; private string fileExtension_ = ".cs"; @@ -288,43 +299,46 @@ namespace Google.ProtocolBuffers.DescriptorProtos { int size = SerializedSize; string[] field_names = _cSharpFileOptionsFieldNames; if (hasNamespace) { - output.WriteString(1, field_names[6], Namespace); + output.WriteString(1, field_names[7], Namespace); } if (hasUmbrellaClassname) { - output.WriteString(2, field_names[11], UmbrellaClassname); + output.WriteString(2, field_names[12], UmbrellaClassname); } if (hasPublicClasses) { - output.WriteBool(3, field_names[9], PublicClasses); + output.WriteBool(3, field_names[10], PublicClasses); } if (hasMultipleFiles) { - output.WriteBool(4, field_names[5], MultipleFiles); + output.WriteBool(4, field_names[6], MultipleFiles); } if (hasNestClasses) { - output.WriteBool(5, field_names[7], NestClasses); + output.WriteBool(5, field_names[8], NestClasses); } if (hasCodeContracts) { - output.WriteBool(6, field_names[1], CodeContracts); + output.WriteBool(6, field_names[2], CodeContracts); } if (hasExpandNamespaceDirectories) { - output.WriteBool(7, field_names[2], ExpandNamespaceDirectories); + output.WriteBool(7, field_names[3], ExpandNamespaceDirectories); } if (hasClsCompliance) { - output.WriteBool(8, field_names[0], ClsCompliance); + output.WriteBool(8, field_names[1], ClsCompliance); + } + if (hasAddSerializable) { + output.WriteBool(9, field_names[0], AddSerializable); } if (hasFileExtension) { - output.WriteString(221, field_names[3], FileExtension); + output.WriteString(221, field_names[4], FileExtension); } if (hasUmbrellaNamespace) { - output.WriteString(222, field_names[12], UmbrellaNamespace); + output.WriteString(222, field_names[13], UmbrellaNamespace); } if (hasOutputDirectory) { - output.WriteString(223, field_names[8], OutputDirectory); + output.WriteString(223, field_names[9], OutputDirectory); } if (hasIgnoreGoogleProtobuf) { - output.WriteBool(224, field_names[4], IgnoreGoogleProtobuf); + output.WriteBool(224, field_names[5], IgnoreGoogleProtobuf); } if (hasServiceGeneratorType) { - output.WriteEnum(225, field_names[10], (int) ServiceGeneratorType, ServiceGeneratorType); + output.WriteEnum(225, field_names[11], (int) ServiceGeneratorType, ServiceGeneratorType); } UnknownFields.WriteTo(output); } @@ -360,6 +374,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos { if (hasClsCompliance) { size += pb::CodedOutputStream.ComputeBoolSize(8, ClsCompliance); } + if (hasAddSerializable) { + size += pb::CodedOutputStream.ComputeBoolSize(9, AddSerializable); + } if (hasFileExtension) { size += pb::CodedOutputStream.ComputeStringSize(221, FileExtension); } @@ -494,6 +511,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos { if (other.HasClsCompliance) { ClsCompliance = other.ClsCompliance; } + if (other.HasAddSerializable) { + AddSerializable = other.AddSerializable; + } if (other.HasFileExtension) { FileExtension = other.FileExtension; } @@ -583,6 +603,10 @@ namespace Google.ProtocolBuffers.DescriptorProtos { result.hasClsCompliance = input.ReadBool(ref result.clsCompliance_); break; } + case 72: { + result.hasAddSerializable = input.ReadBool(ref result.addSerializable_); + break; + } case 1770: { result.hasFileExtension = input.ReadString(ref result.fileExtension_); break; @@ -767,6 +791,24 @@ namespace Google.ProtocolBuffers.DescriptorProtos { return this; } + public bool HasAddSerializable { + get { return result.hasAddSerializable; } + } + public bool AddSerializable { + get { return result.AddSerializable; } + set { SetAddSerializable(value); } + } + public Builder SetAddSerializable(bool value) { + result.hasAddSerializable = true; + result.addSerializable_ = value; + return this; + } + public Builder ClearAddSerializable() { + result.hasAddSerializable = false; + result.addSerializable_ = false; + return this; + } + public bool HasFileExtension { get { return result.hasFileExtension; } } diff --git a/src/ProtocolBuffers/DynamicMessage.cs b/src/ProtocolBuffers/DynamicMessage.cs index 6235eb5b..e39efb12 100644 --- a/src/ProtocolBuffers/DynamicMessage.cs +++ b/src/ProtocolBuffers/DynamicMessage.cs @@ -44,7 +44,7 @@ namespace Google.ProtocolBuffers /// /// An implementation of IMessage that can represent arbitrary types, given a MessageaDescriptor. /// - public sealed class DynamicMessage : AbstractMessage + public sealed partial class DynamicMessage : AbstractMessage { private readonly MessageDescriptor type; private readonly FieldSet fields; @@ -308,7 +308,7 @@ namespace Google.ProtocolBuffers /// /// Builder for dynamic messages. Instances are created with DynamicMessage.CreateBuilder. /// - public sealed class Builder : AbstractBuilder + public sealed partial class Builder : AbstractBuilder { private readonly MessageDescriptor type; private FieldSet fields; diff --git a/src/ProtocolBuffers/ExtendableBuilder.cs b/src/ProtocolBuffers/ExtendableBuilder.cs index 137762ab..111ff57e 100644 --- a/src/ProtocolBuffers/ExtendableBuilder.cs +++ b/src/ProtocolBuffers/ExtendableBuilder.cs @@ -40,7 +40,7 @@ using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers { - public abstract class ExtendableBuilder : GeneratedBuilder + public abstract partial class ExtendableBuilder : GeneratedBuilder where TMessage : ExtendableMessage where TBuilder : GeneratedBuilder, new() { diff --git a/src/ProtocolBuffers/ExtendableBuilderLite.cs b/src/ProtocolBuffers/ExtendableBuilderLite.cs index cdec4fa3..2a71aa4a 100644 --- a/src/ProtocolBuffers/ExtendableBuilderLite.cs +++ b/src/ProtocolBuffers/ExtendableBuilderLite.cs @@ -40,7 +40,7 @@ using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers { - public abstract class ExtendableBuilderLite : GeneratedBuilderLite + public abstract partial class ExtendableBuilderLite : GeneratedBuilderLite where TMessage : ExtendableMessageLite where TBuilder : GeneratedBuilderLite { diff --git a/src/ProtocolBuffers/ExtendableMessage.cs b/src/ProtocolBuffers/ExtendableMessage.cs index e8f9ce41..71cd1b38 100644 --- a/src/ProtocolBuffers/ExtendableMessage.cs +++ b/src/ProtocolBuffers/ExtendableMessage.cs @@ -41,7 +41,7 @@ using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers { - public abstract class ExtendableMessage : GeneratedMessage + public abstract partial class ExtendableMessage : GeneratedMessage where TMessage : GeneratedMessage where TBuilder : GeneratedBuilder, new() { diff --git a/src/ProtocolBuffers/ExtendableMessageLite.cs b/src/ProtocolBuffers/ExtendableMessageLite.cs index 6ff56566..e682475d 100644 --- a/src/ProtocolBuffers/ExtendableMessageLite.cs +++ b/src/ProtocolBuffers/ExtendableMessageLite.cs @@ -42,7 +42,7 @@ using Google.ProtocolBuffers.Collections; namespace Google.ProtocolBuffers { - public abstract class ExtendableMessageLite : GeneratedMessageLite + public abstract partial class ExtendableMessageLite : GeneratedMessageLite where TMessage : GeneratedMessageLite where TBuilder : GeneratedBuilderLite { diff --git a/src/ProtocolBuffers/GeneratedBuilder.cs b/src/ProtocolBuffers/GeneratedBuilder.cs index 94948e49..69c3ccf1 100644 --- a/src/ProtocolBuffers/GeneratedBuilder.cs +++ b/src/ProtocolBuffers/GeneratedBuilder.cs @@ -47,7 +47,7 @@ namespace Google.ProtocolBuffers /// most of the IBuilder interface using reflection. Users can ignore this class /// as an implementation detail. /// - public abstract class GeneratedBuilder : AbstractBuilder + public abstract partial class GeneratedBuilder : AbstractBuilder where TMessage : GeneratedMessage where TBuilder : GeneratedBuilder, new() { diff --git a/src/ProtocolBuffers/GeneratedBuilderLite.cs b/src/ProtocolBuffers/GeneratedBuilderLite.cs index cd2b8395..00e6be26 100644 --- a/src/ProtocolBuffers/GeneratedBuilderLite.cs +++ b/src/ProtocolBuffers/GeneratedBuilderLite.cs @@ -44,7 +44,7 @@ namespace Google.ProtocolBuffers /// most of the IBuilder interface using reflection. Users can ignore this class /// as an implementation detail. /// - public abstract class GeneratedBuilderLite : AbstractBuilderLite + public abstract partial class GeneratedBuilderLite : AbstractBuilderLite where TMessage : GeneratedMessageLite where TBuilder : GeneratedBuilderLite { diff --git a/src/ProtocolBuffers/GeneratedMessage.cs b/src/ProtocolBuffers/GeneratedMessage.cs index ce755bed..6f4b6657 100644 --- a/src/ProtocolBuffers/GeneratedMessage.cs +++ b/src/ProtocolBuffers/GeneratedMessage.cs @@ -50,7 +50,7 @@ namespace Google.ProtocolBuffers /// most of the IMessage interface using reflection. Users /// can ignore this class as an implementation detail. /// - public abstract class GeneratedMessage : AbstractMessage + public abstract partial class GeneratedMessage : AbstractMessage where TMessage : GeneratedMessage where TBuilder : GeneratedBuilder, new() { diff --git a/src/ProtocolBuffers/GeneratedMessageLite.cs b/src/ProtocolBuffers/GeneratedMessageLite.cs index 1406d304..aecba7d6 100644 --- a/src/ProtocolBuffers/GeneratedMessageLite.cs +++ b/src/ProtocolBuffers/GeneratedMessageLite.cs @@ -47,7 +47,7 @@ namespace Google.ProtocolBuffers /// most of the IMessage interface using reflection. Users /// can ignore this class as an implementation detail. /// - public abstract class GeneratedMessageLite : AbstractMessageLite + public abstract partial class GeneratedMessageLite : AbstractMessageLite where TMessage : GeneratedMessageLite where TBuilder : GeneratedBuilderLite { diff --git a/src/ProtocolBuffers/IBuilderLite.cs b/src/ProtocolBuffers/IBuilderLite.cs index 801f8e24..330fe495 100644 --- a/src/ProtocolBuffers/IBuilderLite.cs +++ b/src/ProtocolBuffers/IBuilderLite.cs @@ -46,7 +46,7 @@ namespace Google.ProtocolBuffers /// use explicit interface implemenation for the non-generic form. This mirrors /// how IEnumerable and IEnumerable<T> work. /// - public interface IBuilderLite + public partial interface IBuilderLite { /// /// Returns true iff all required fields in the message and all diff --git a/src/ProtocolBuffers/IMessageLite.cs b/src/ProtocolBuffers/IMessageLite.cs index 90fb9509..ea5d9940 100644 --- a/src/ProtocolBuffers/IMessageLite.cs +++ b/src/ProtocolBuffers/IMessageLite.cs @@ -42,7 +42,7 @@ namespace Google.ProtocolBuffers /// Non-generic interface used for all parts of the API which don't require /// any type knowledge. /// - public interface IMessageLite + public partial interface IMessageLite { /// /// Returns true iff all required fields in the message and all embedded diff --git a/src/ProtocolBuffers/ProtocolBuffers.csproj b/src/ProtocolBuffers/ProtocolBuffers.csproj index 336b387f..be80bd36 100644 --- a/src/ProtocolBuffers/ProtocolBuffers.csproj +++ b/src/ProtocolBuffers/ProtocolBuffers.csproj @@ -105,6 +105,7 @@ + diff --git a/src/ProtocolBuffers/ProtocolBuffersLite.csproj b/src/ProtocolBuffers/ProtocolBuffersLite.csproj index 44c92550..e2d44785 100644 --- a/src/ProtocolBuffers/ProtocolBuffersLite.csproj +++ b/src/ProtocolBuffers/ProtocolBuffersLite.csproj @@ -86,6 +86,7 @@ + diff --git a/src/ProtocolBuffers/UnknownFieldSet.cs b/src/ProtocolBuffers/UnknownFieldSet.cs index 9261dbae..09ed680f 100644 --- a/src/ProtocolBuffers/UnknownFieldSet.cs +++ b/src/ProtocolBuffers/UnknownFieldSet.cs @@ -53,7 +53,7 @@ namespace Google.ProtocolBuffers /// /// Most users will never need to use this class directly. /// - public sealed class UnknownFieldSet : IMessageLite + public sealed partial class UnknownFieldSet : IMessageLite { private static readonly UnknownFieldSet defaultInstance = new UnknownFieldSet(new Dictionary()); @@ -314,7 +314,7 @@ namespace Google.ProtocolBuffers /// /// Builder for UnknownFieldSets. /// - public sealed class Builder : IBuilderLite + public sealed partial class Builder : IBuilderLite { /// /// Mapping from number to field. Note that by using a SortedList we ensure diff --git a/src/ProtocolBuffers2008.sln b/src/ProtocolBuffers2008.sln index 0baadbae..26924c60 100644 --- a/src/ProtocolBuffers2008.sln +++ b/src/ProtocolBuffers2008.sln @@ -23,7 +23,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unittest", "unittest", "{C8 ..\protos\extest\unittest_generic_services.proto = ..\protos\extest\unittest_generic_services.proto ..\protos\google\protobuf\unittest_import.proto = ..\protos\google\protobuf\unittest_import.proto ..\protos\google\protobuf\unittest_import_lite.proto = ..\protos\google\protobuf\unittest_import_lite.proto - ..\protos\extest\unittest_issues.proto = ..\protos\extest\unittest_issues.proto ..\protos\google\protobuf\unittest_lite.proto = ..\protos\google\protobuf\unittest_lite.proto ..\protos\google\protobuf\unittest_lite_imports_nonlite.proto = ..\protos\google\protobuf\unittest_lite_imports_nonlite.proto ..\protos\google\protobuf\unittest_mset.proto = ..\protos\google\protobuf\unittest_mset.proto diff --git a/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj b/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj index 2b8fe7ce..8da5b263 100644 --- a/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj +++ b/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj @@ -61,6 +61,7 @@ + diff --git a/src/ProtocolBuffersLite.Test/SerializableLiteTest.cs b/src/ProtocolBuffersLite.Test/SerializableLiteTest.cs new file mode 100644 index 00000000..7c12ef40 --- /dev/null +++ b/src/ProtocolBuffersLite.Test/SerializableLiteTest.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using Google.ProtocolBuffers.TestProtos; +using NUnit.Framework; + +namespace Google.ProtocolBuffers +{ + [TestFixture] + public class SerializableLiteTest + { + /// + /// Just keep it from even compiling if we these objects don't implement the expected interface. + /// + public static readonly ISerializable CompileTimeCheckSerializableMessage = TestRequiredLite.DefaultInstance; + public static readonly ISerializable CompileTimeCheckSerializableBuilder = new TestRequiredLite.Builder(); + + [Test] + public void TestPlainMessage() + { + TestRequiredLite message = TestRequiredLite.CreateBuilder() + .SetD(42) + .BuildPartial(); + + MemoryStream ms = new MemoryStream(); + new BinaryFormatter().Serialize(ms, message); + + ms.Position = 0; + TestRequiredLite copy = (TestRequiredLite)new BinaryFormatter().Deserialize(ms); + + Assert.AreEqual(message, copy); + } + + [Test] + public void TestPlainBuilder() + { + TestRequiredLite.Builder builder = TestRequiredLite.CreateBuilder() + .SetD(42) + ; + + MemoryStream ms = new MemoryStream(); + new BinaryFormatter().Serialize(ms, builder); + + ms.Position = 0; + TestRequiredLite.Builder copy = (TestRequiredLite.Builder)new BinaryFormatter().Deserialize(ms); + + Assert.AreEqual(builder.BuildPartial(), copy.BuildPartial()); + } + } +} diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs index bc214e25..646aac21 100644 --- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs +++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs @@ -55,6 +55,7 @@ namespace Google.ProtocolBuffers.TestProtos { #endregion #region Messages + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -190,6 +191,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -335,6 +337,7 @@ namespace Google.ProtocolBuffers.TestProtos { } } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -367,6 +370,7 @@ namespace Google.ProtocolBuffers.TestProtos { WORK = 2, } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -501,6 +505,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -647,6 +652,7 @@ namespace Google.ProtocolBuffers.TestProtos { } } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -842,6 +848,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -1293,6 +1300,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -1589,6 +1597,7 @@ namespace Google.ProtocolBuffers.TestProtos { } } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] @@ -1704,6 +1713,7 @@ namespace Google.ProtocolBuffers.TestProtos { return (Builder) new Builder().MergeFrom(prototype); } + [global::System.SerializableAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")] -- cgit v1.2.3