csharptest 14 gadi atpakaļ
vecāks
revīzija
945ea76eaa
31 mainītis faili ar 639 papildinājumiem un 143 dzēšanām
  1. 62 61
      protos/extest/unittest_extras_lite.proto
  2. 22 23
      protos/extest/unittest_extras_xmltest.proto
  3. 3 0
      protos/google/protobuf/csharp_options.proto
  4. 9 1
      src/ProtoGen/MessageGenerator.cs
  5. 1 0
      src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj
  6. 177 0
      src/ProtocolBuffers.Test/SerializableTest.cs
  7. 15 3
      src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
  8. 1 1
      src/ProtocolBuffers/AbstractBuilder.cs
  9. 1 1
      src/ProtocolBuffers/AbstractBuilderLite.cs
  10. 1 1
      src/ProtocolBuffers/AbstractMessage.cs
  11. 1 1
      src/ProtocolBuffers/AbstractMessageLite.cs
  12. 188 0
      src/ProtocolBuffers/CustomSerialization.cs
  13. 78 36
      src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
  14. 2 2
      src/ProtocolBuffers/DynamicMessage.cs
  15. 1 1
      src/ProtocolBuffers/ExtendableBuilder.cs
  16. 1 1
      src/ProtocolBuffers/ExtendableBuilderLite.cs
  17. 1 1
      src/ProtocolBuffers/ExtendableMessage.cs
  18. 1 1
      src/ProtocolBuffers/ExtendableMessageLite.cs
  19. 1 1
      src/ProtocolBuffers/GeneratedBuilder.cs
  20. 1 1
      src/ProtocolBuffers/GeneratedBuilderLite.cs
  21. 1 1
      src/ProtocolBuffers/GeneratedMessage.cs
  22. 1 1
      src/ProtocolBuffers/GeneratedMessageLite.cs
  23. 1 1
      src/ProtocolBuffers/IBuilderLite.cs
  24. 1 1
      src/ProtocolBuffers/IMessageLite.cs
  25. 1 0
      src/ProtocolBuffers/ProtocolBuffers.csproj
  26. 1 0
      src/ProtocolBuffers/ProtocolBuffersLite.csproj
  27. 2 2
      src/ProtocolBuffers/UnknownFieldSet.cs
  28. 0 1
      src/ProtocolBuffers2008.sln
  29. 1 0
      src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj
  30. 53 0
      src/ProtocolBuffersLite.Test/SerializableLiteTest.cs
  31. 10 0
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs

+ 62 - 61
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;
+}

+ 22 - 23
protos/extest/unittest_extras_xmltest.proto

@@ -1,52 +1,51 @@
 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;
 
 option optimize_for = SPEED;
 
 enum EnumOptions {
-    ONE = 0;
-    TWO = 1;
-    THREE = 2;
+  ONE = 0;
+  TWO = 1;
+  THREE = 2;
 }
 
-message TestXmlChild
-{
-    repeated EnumOptions options = 3;
-    optional bytes binary = 4;
+message TestXmlChild {
+  repeated EnumOptions options = 3;
+  optional bytes binary = 4;
 }
 
 message TestXmlNoFields {
 }
 
 message TestXmlRescursive {
-    optional TestXmlRescursive child = 1;
+  optional TestXmlRescursive child = 1;
 }
 
 message TestXmlMessage {
 
-    optional int64 number = 6;
-    repeated int32 numbers = 2;
-    optional string text = 3;
-    repeated string textlines = 700;
-    optional bool valid = 5;
-    
-    optional TestXmlChild child = 1;
-    repeated group Children = 401 
-    {
-        repeated EnumOptions options = 3;
-        optional bytes binary = 4;
-    }
-
-    extensions 100 to 199;
+  optional int64 number = 6;
+  repeated int32 numbers = 2;
+  optional string text = 3;
+  repeated string textlines = 700;
+  optional bool valid = 5;
+
+  optional TestXmlChild child = 1;
+  repeated group Children = 401 {
+    repeated EnumOptions options = 3;
+    optional bytes binary = 4;
+  }
+
+extensions 100 to 199;
 }
 
 message  TestXmlExtension {
   required int32 number = 1;
 }
-  
+
 extend TestXmlMessage {
   optional EnumOptions extension_enum = 101;
   optional string extension_text = 102;

+ 3 - 0
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"];

+ 9 - 1
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}\")]",

+ 1 - 0
src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj

@@ -103,6 +103,7 @@
     <Compile Include="NameHelpersTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ReflectionTester.cs" />
+    <Compile Include="SerializableTest.cs" />
     <Compile Include="ServiceTest.cs" />
     <Compile Include="TestCornerCases.cs" />
     <Compile Include="TestProtos\UnitTestCSharpOptionsProtoFile.cs" />

+ 177 - 0
src/ProtocolBuffers.Test/SerializableTest.cs

@@ -0,0 +1,177 @@
+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
+    {
+        /// <summary>
+        /// Just keep it from even compiling if we these objects don't implement the expected interface.
+        /// </summary>
+        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());
+        }
+    }
+}

+ 15 - 3
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")]

+ 1 - 1
src/ProtocolBuffers/AbstractBuilder.cs

@@ -44,7 +44,7 @@ namespace Google.ProtocolBuffers
     /// <summary>
     /// Implementation of the non-generic IMessage interface as far as possible.
     /// </summary>
-    public abstract class AbstractBuilder<TMessage, TBuilder> : AbstractBuilderLite<TMessage, TBuilder>,
+    public abstract partial class AbstractBuilder<TMessage, TBuilder> : AbstractBuilderLite<TMessage, TBuilder>,
                                                                 IBuilder<TMessage, TBuilder>
         where TMessage : AbstractMessage<TMessage, TBuilder>
         where TBuilder : AbstractBuilder<TMessage, TBuilder>

+ 1 - 1
src/ProtocolBuffers/AbstractBuilderLite.cs

@@ -42,7 +42,7 @@ namespace Google.ProtocolBuffers
     /// <summary>
     /// Implementation of the non-generic IMessage interface as far as possible.
     /// </summary>
-    public abstract class AbstractBuilderLite<TMessage, TBuilder> : IBuilderLite<TMessage, TBuilder>
+    public abstract partial class AbstractBuilderLite<TMessage, TBuilder> : IBuilderLite<TMessage, TBuilder>
         where TMessage : AbstractMessageLite<TMessage, TBuilder>
         where TBuilder : AbstractBuilderLite<TMessage, TBuilder>
     {

+ 1 - 1
src/ProtocolBuffers/AbstractMessage.cs

@@ -46,7 +46,7 @@ namespace Google.ProtocolBuffers
     /// <summary>
     /// Implementation of the non-generic IMessage interface as far as possible.
     /// </summary>
-    public abstract class AbstractMessage<TMessage, TBuilder> : AbstractMessageLite<TMessage, TBuilder>,
+    public abstract partial class AbstractMessage<TMessage, TBuilder> : AbstractMessageLite<TMessage, TBuilder>,
                                                                 IMessage<TMessage, TBuilder>
         where TMessage : AbstractMessage<TMessage, TBuilder>
         where TBuilder : AbstractBuilder<TMessage, TBuilder>

+ 1 - 1
src/ProtocolBuffers/AbstractMessageLite.cs

@@ -41,7 +41,7 @@ namespace Google.ProtocolBuffers
     /// <summary>
     /// Implementation of the non-generic IMessage interface as far as possible.
     /// </summary>
-    public abstract class AbstractMessageLite<TMessage, TBuilder> : IMessageLite<TMessage, TBuilder>
+    public abstract partial class AbstractMessageLite<TMessage, TBuilder> : IMessageLite<TMessage, TBuilder>
         where TMessage : AbstractMessageLite<TMessage, TBuilder>
         where TBuilder : AbstractBuilderLite<TMessage, TBuilder>
     {

+ 188 - 0
src/ProtocolBuffers/CustomSerialization.cs

@@ -0,0 +1,188 @@
+#region Copyright notice and license
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) 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, and are then reconstituted by an IObjectReference class after
+     * deserialization.  IDeserializationCallback is supported on both the Builder and Message.
+     */
+    [Serializable]
+    partial class AbstractMessageLite<TMessage, TBuilder> : 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);
+
+                IDeserializationCallback callback = builder as IDeserializationCallback;
+                if(callback != null)
+                {
+                    callback.OnDeserialization(context);
+                }
+
+                TMessage message = _initialized ? builder.Build() : builder.BuildPartial();
+                callback = message as IDeserializationCallback;
+                if (callback != null)
+                {
+                    callback.OnDeserialization(context);
+                }
+
+                return message;
+            }
+
+            void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("message", _message);
+            }
+        }
+    }
+
+    [Serializable]
+    partial class AbstractBuilderLite<TMessage, TBuilder> : 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);
+
+                IDeserializationCallback callback = builder as IDeserializationCallback;
+                if(callback != null)
+                {
+                    callback.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<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class ExtendableMessageLite<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class AbstractMessage<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class GeneratedMessage<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class ExtendableMessage<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class GeneratedBuilderLite<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class ExtendableBuilderLite<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class AbstractBuilder<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class GeneratedBuilder<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class ExtendableBuilder<TMessage, TBuilder> { }
+
+    [Serializable]
+    partial class DynamicMessage 
+    {
+        [Serializable]
+        partial class Builder { }
+    }
+}
+#endif

+ 78 - 36
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<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", });
+                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<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Builder>(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<CSharpFileOptions, CSharpFileOptions.Builder> {
     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; }
       }

+ 2 - 2
src/ProtocolBuffers/DynamicMessage.cs

@@ -44,7 +44,7 @@ namespace Google.ProtocolBuffers
     /// <summary>
     /// An implementation of IMessage that can represent arbitrary types, given a MessageaDescriptor.
     /// </summary>
-    public sealed class DynamicMessage : AbstractMessage<DynamicMessage, DynamicMessage.Builder>
+    public sealed partial class DynamicMessage : AbstractMessage<DynamicMessage, DynamicMessage.Builder>
     {
         private readonly MessageDescriptor type;
         private readonly FieldSet fields;
@@ -308,7 +308,7 @@ namespace Google.ProtocolBuffers
         /// <summary>
         /// Builder for dynamic messages. Instances are created with DynamicMessage.CreateBuilder.
         /// </summary>
-        public sealed class Builder : AbstractBuilder<DynamicMessage, Builder>
+        public sealed partial class Builder : AbstractBuilder<DynamicMessage, Builder>
         {
             private readonly MessageDescriptor type;
             private FieldSet fields;

+ 1 - 1
src/ProtocolBuffers/ExtendableBuilder.cs

@@ -40,7 +40,7 @@ using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers
 {
-    public abstract class ExtendableBuilder<TMessage, TBuilder> : GeneratedBuilder<TMessage, TBuilder>
+    public abstract partial class ExtendableBuilder<TMessage, TBuilder> : GeneratedBuilder<TMessage, TBuilder>
         where TMessage : ExtendableMessage<TMessage, TBuilder>
         where TBuilder : GeneratedBuilder<TMessage, TBuilder>, new()
     {

+ 1 - 1
src/ProtocolBuffers/ExtendableBuilderLite.cs

@@ -40,7 +40,7 @@ using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers
 {
-    public abstract class ExtendableBuilderLite<TMessage, TBuilder> : GeneratedBuilderLite<TMessage, TBuilder>
+    public abstract partial class ExtendableBuilderLite<TMessage, TBuilder> : GeneratedBuilderLite<TMessage, TBuilder>
         where TMessage : ExtendableMessageLite<TMessage, TBuilder>
         where TBuilder : GeneratedBuilderLite<TMessage, TBuilder>
     {

+ 1 - 1
src/ProtocolBuffers/ExtendableMessage.cs

@@ -41,7 +41,7 @@ using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers
 {
-    public abstract class ExtendableMessage<TMessage, TBuilder> : GeneratedMessage<TMessage, TBuilder>
+    public abstract partial class ExtendableMessage<TMessage, TBuilder> : GeneratedMessage<TMessage, TBuilder>
         where TMessage : GeneratedMessage<TMessage, TBuilder>
         where TBuilder : GeneratedBuilder<TMessage, TBuilder>, new()
     {

+ 1 - 1
src/ProtocolBuffers/ExtendableMessageLite.cs

@@ -42,7 +42,7 @@ using Google.ProtocolBuffers.Collections;
 
 namespace Google.ProtocolBuffers
 {
-    public abstract class ExtendableMessageLite<TMessage, TBuilder> : GeneratedMessageLite<TMessage, TBuilder>
+    public abstract partial class ExtendableMessageLite<TMessage, TBuilder> : GeneratedMessageLite<TMessage, TBuilder>
         where TMessage : GeneratedMessageLite<TMessage, TBuilder>
         where TBuilder : GeneratedBuilderLite<TMessage, TBuilder>
     {

+ 1 - 1
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.
     /// </summary>
-    public abstract class GeneratedBuilder<TMessage, TBuilder> : AbstractBuilder<TMessage, TBuilder>
+    public abstract partial class GeneratedBuilder<TMessage, TBuilder> : AbstractBuilder<TMessage, TBuilder>
         where TMessage : GeneratedMessage<TMessage, TBuilder>
         where TBuilder : GeneratedBuilder<TMessage, TBuilder>, new()
     {

+ 1 - 1
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.
     /// </summary>
-    public abstract class GeneratedBuilderLite<TMessage, TBuilder> : AbstractBuilderLite<TMessage, TBuilder>
+    public abstract partial class GeneratedBuilderLite<TMessage, TBuilder> : AbstractBuilderLite<TMessage, TBuilder>
         where TMessage : GeneratedMessageLite<TMessage, TBuilder>
         where TBuilder : GeneratedBuilderLite<TMessage, TBuilder>
     {

+ 1 - 1
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.
     /// </summary>
-    public abstract class GeneratedMessage<TMessage, TBuilder> : AbstractMessage<TMessage, TBuilder>
+    public abstract partial class GeneratedMessage<TMessage, TBuilder> : AbstractMessage<TMessage, TBuilder>
         where TMessage : GeneratedMessage<TMessage, TBuilder>
         where TBuilder : GeneratedBuilder<TMessage, TBuilder>, new()
     {

+ 1 - 1
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.
     /// </summary>
-    public abstract class GeneratedMessageLite<TMessage, TBuilder> : AbstractMessageLite<TMessage, TBuilder>
+    public abstract partial class GeneratedMessageLite<TMessage, TBuilder> : AbstractMessageLite<TMessage, TBuilder>
         where TMessage : GeneratedMessageLite<TMessage, TBuilder>
         where TBuilder : GeneratedBuilderLite<TMessage, TBuilder>
     {

+ 1 - 1
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&lt;T&gt; work.
     /// </summary>
-    public interface IBuilderLite
+    public partial interface IBuilderLite
     {
         /// <summary>
         /// Returns true iff all required fields in the message and all

+ 1 - 1
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.
     /// </summary>
-    public interface IMessageLite
+    public partial interface IMessageLite
     {
         /// <summary>
         /// Returns true iff all required fields in the message and all embedded

+ 1 - 0
src/ProtocolBuffers/ProtocolBuffers.csproj

@@ -105,6 +105,7 @@
     <Compile Include="Collections\IPopsicleList.cs" />
     <Compile Include="Collections\PopsicleList.cs" />
     <Compile Include="CodedOutputStream.ComputeSize.cs" />
+    <Compile Include="CustomSerialization.cs" />
     <Compile Include="Delegates.cs" />
     <Compile Include="CodedInputStream.cs" />
     <Compile Include="CodedOutputStream.cs" />

+ 1 - 0
src/ProtocolBuffers/ProtocolBuffersLite.csproj

@@ -86,6 +86,7 @@
     <Compile Include="Collections\Lists.cs" />
     <Compile Include="Collections\PopsicleList.cs" />
     <Compile Include="Collections\ReadOnlyDictionary.cs" />
+    <Compile Include="CustomSerialization.cs" />
     <Compile Include="Descriptors\FieldMappingAttribute.cs" />
     <Compile Include="Descriptors\FieldType.cs" />
     <Compile Include="Descriptors\MappedType.cs" />

+ 2 - 2
src/ProtocolBuffers/UnknownFieldSet.cs

@@ -53,7 +53,7 @@ namespace Google.ProtocolBuffers
     /// 
     /// Most users will never need to use this class directly.
     /// </summary>
-    public sealed class UnknownFieldSet : IMessageLite
+    public sealed partial class UnknownFieldSet : IMessageLite
     {
         private static readonly UnknownFieldSet defaultInstance =
             new UnknownFieldSet(new Dictionary<int, UnknownField>());
@@ -314,7 +314,7 @@ namespace Google.ProtocolBuffers
         /// <summary>
         /// Builder for UnknownFieldSets.
         /// </summary>
-        public sealed class Builder : IBuilderLite
+        public sealed partial class Builder : IBuilderLite
         {
             /// <summary>
             /// Mapping from number to field. Note that by using a SortedList we ensure

+ 0 - 1
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

+ 1 - 0
src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj

@@ -61,6 +61,7 @@
     <Compile Include="ExtendableBuilderLiteTest.cs" />
     <Compile Include="ExtendableMessageLiteTest.cs" />
     <Compile Include="LiteTest.cs" />
+    <Compile Include="SerializableLiteTest.cs" />
     <Compile Include="TestLiteByApi.cs" />
     <Compile Include="TestProtos\UnitTestExtrasLiteProtoFile.cs" />
     <Compile Include="TestProtos\UnitTestImportLiteProtoFile.cs" />

+ 53 - 0
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
+    {
+        /// <summary>
+        /// Just keep it from even compiling if we these objects don't implement the expected interface.
+        /// </summary>
+        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());
+        }
+    }
+}

+ 10 - 0
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")]